MMapDB
view release on metacpan or search on metacpan
SV *sv; \
\
rec+=2; /* skip valid flag and ID */ \
rec+=xI(type, cnv, *rec)+2; /* skip NKEYS, KEYS and SORT */ \
\
stroff=xI(type, cnv, *rec); \
sv=newSV(0); \
SvUPGRADE(sv, SVt_PV); \
SvPOK_only(sv); \
/* set the string itself */ \
SvPV_set(sv, xSp(type, cnv, strtbl, stroff)); \
SvLEN_set(sv, 0); \
SvCUR_set(sv, xSl(type, cnv, strtbl, stroff)); \
SvREADONLY_on(sv); \
if( dbfmt>0 ) { \
if( xSutf8(type, cnv, strtbl, stroff) ) SvUTF8_on(sv); \
} \
return sv; \
} \
\
static SV* \
dsort_##fmt(pTHX_ const void* _rec, int dbfmt, const void* _strtbl) { \
const type* rec=_rec; \
type stroff; \
const char* strtbl=_strtbl; \
SV *sv; \
\
rec+=2; /* skip valid flag and ID */ \
rec+=xI(type, cnv, *rec)+1; /* skip NKEYS and KEYS */ \
\
stroff=xI(type, cnv, *rec); \
sv=newSV(0); \
SvUPGRADE(sv, SVt_PV); \
SvPOK_only(sv); \
/* set the string itself */ \
SvPV_set(sv, xSp(type, cnv, strtbl, stroff)); \
SvLEN_set(sv, 0); \
SvCUR_set(sv, xSl(type, cnv, strtbl, stroff)); \
SvREADONLY_on(sv); \
if( dbfmt>0 ) { \
if( xSutf8(type, cnv, strtbl, stroff) ) SvUTF8_on(sv); \
} \
return sv; \
}
GENFN(U32, L, identity)
GENFN(UV, J, identity)
GENFN(U32, N, ntohl)
# ifdef HAS_QUAD
GENFN(U64TYPE, Q, identity)
# endif
MODULE = MMapDB PACKAGE = MMapDB
PROTOTYPES: DISABLED
void
index_lookup(I, ...)
MMapDB I;
PPCODE:
if( expect_true(items>1) ) {
UV pos=SvUV(ST(1));
STRLEN keylen;
char *datap, *intfmt, *keyp;
SV **svp=av_fetch(I, MMDB_DATA, 0);
void *strtbl, *found=0;
UV dataend, dbfmt;
int i, isidx=1;
if( expect_false(!(svp && SvROK(*svp))) ) goto END;
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
W("MainIdx=%d, pos=%d\n", (int)dataend, (int)pos);
if( !pos ) pos=dataend;
for(i=2; i<items && isidx; i++) {
keyp=SvPV(ST(i), keylen);
W("\nlooking for %*s\n", (int)keylen, (char*)keyp);
found=L(intfmt[0],idx)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend,
&isidx, &pos);
W(" --> found %lx\n", (long)found);
if(!found) goto END;
}
if( expect_true(found && i==items) ) {
L(intfmt[0],pres)(aTHX_ found, sp);
/* pres() EXTENDs the stack and hence can reallocate it.
* So it calls PUTPACK afterwards and we must return here
* to avoid the implicit PUTBACK that XS inserts. */
return;
}
}
END:
void
index_lookup_position(I, ...)
MMapDB I;
PPCODE:
if( expect_true(items>1) ) {
UV pos=SvUV(ST(1));
STRLEN keylen;
char *datap, *intfmt, *keyp;
SV **svp=av_fetch(I, MMDB_DATA, 0);
void *strtbl;
UV dataend, dbfmt;
int i, isidx=1;
if( expect_false(!(svp && SvROK(*svp))) ) goto END;
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
if( !pos ) pos=dataend;
for(i=2; i<items-1 && isidx; i++) {
keyp=SvPV(ST(i), keylen);
if( !L(intfmt[0],idx)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend,
&isidx, &pos) ) goto END;
}
if( expect_true(i==items-1 && isidx) ) {
keyp=SvPV(ST(i), keylen);
/* we return 2 items. Since we got at least 2 items on the
* stack we don't need to extend it. */
mPUSHu(pos);
mPUSHu(L(intfmt[0],srch)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend));
}
}
END:
void
id_index_lookup(I, id)
MMapDB I;
UV id;
PPCODE:
{
char *datap, *intfmt;
UV pos;
SV **svp=av_fetch(I, MMDB_DATA, 0);
if( expect_true((svp && SvROK(*svp))) ) {
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
pos=SvUV(*av_fetch(I, MMDB_IDIDX, 0));
pos=L(intfmt[0],ididx)(id, datap+pos);
if( pos!=(UV)-1 ) {
/* EXTEND(SP,1); # not necessary there is already room for 2 items */
PUSHs(sv_2mortal(newSVuv(pos)));
}
}
}
void
data_record(I, ...)
MMapDB I;
PPCODE:
if( items>1 ) {
int i;
UV pos;
char *datap, *intfmt;
UV dataend, dbfmt;
SV **svp=av_fetch(I, MMDB_DATA, 0);
AV* av;
void* strtbl;
if( expect_true((svp && SvROK(*svp))) ) {
datap=SvPV_nolen(SvRV(*svp));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
for( i=1; i<items; i++ ) {
pos=SvUV(ST(i));
if( expect_true(pos<dataend) ) {
av=L(intfmt[0],drec)(aTHX_ datap+pos, dbfmt, strtbl);
PUSHs(sv_2mortal(newRV_noinc((SV*)av)));
} else {
PUSHs(&PL_sv_undef);
}
}
}
}
void
index_lookup_records(I, ...)
MMapDB I;
PPCODE:
if( expect_true(items>1) ) {
UV pos=SvUV(ST(1));
STRLEN keylen;
char *datap, *intfmt, *keyp;
SV **svp=av_fetch(I, MMDB_DATA, 0);
void *strtbl, *found=0;
UV dataend, dbfmt;
int i, isidx=1;
if( expect_false(!(svp && SvROK(*svp))) ) goto END;
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
W("MainIdx=%d, pos=%d\n", (int)dataend, (int)pos);
if( !pos ) pos=dataend;
for(i=2; i<items && isidx; i++) {
keyp=SvPV(ST(i), keylen);
W("\nlooking for %*s\n", (int)keylen, (char*)keyp);
found=L(intfmt[0],idx)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend,
&isidx, &pos);
W(" --> found %lx\n", (long)found);
if(!found) goto END;
}
if( expect_true(found && i==items) ) {
L(intfmt[0],precords)(aTHX_ found, dbfmt, datap, dataend, strtbl, sp);
/* pres() EXTENDs the stack and hence can reallocate it.
* So it calls PUTPACK afterwards and we must return here
* to avoid the implicit PUTBACK that XS inserts. */
return;
}
}
END:
void
data_value(I, ...)
MMapDB I;
PPCODE:
if( items>1 ) {
int i;
UV pos;
char *datap, *intfmt;
UV dataend, dbfmt;
SV **svp=av_fetch(I, MMDB_DATA, 0);
SV* rsv;
void* strtbl;
if( expect_true((svp && SvROK(*svp))) ) {
datap=SvPV_nolen(SvRV(*svp));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
for( i=1; i<items; i++ ) {
pos=SvUV(ST(i));
if( expect_true(pos<dataend) ) {
rsv=L(intfmt[0],dval)(aTHX_ datap+pos, dbfmt, strtbl);
PUSHs(sv_2mortal(rsv));
} else {
PUSHs(&PL_sv_undef);
}
}
}
}
void
index_lookup_values(I, ...)
MMapDB I;
PPCODE:
if( expect_true(items>1) ) {
UV pos=SvUV(ST(1));
STRLEN keylen;
char *datap, *intfmt, *keyp;
SV **svp=av_fetch(I, MMDB_DATA, 0);
void *strtbl, *found=0;
UV dataend, dbfmt;
int i, isidx=1;
if( expect_false(!(svp && SvROK(*svp))) ) goto END;
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
W("MainIdx=%d, pos=%d\n", (int)dataend, (int)pos);
if( !pos ) pos=dataend;
for(i=2; i<items && isidx; i++) {
keyp=SvPV(ST(i), keylen);
W("\nlooking for %*s\n", (int)keylen, (char*)keyp);
found=L(intfmt[0],idx)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend,
&isidx, &pos);
W(" --> found %lx\n", (long)found);
if(!found) goto END;
}
if( expect_true(found && i==items) ) {
L(intfmt[0],pvalues)(aTHX_ found, dbfmt, datap, dataend, strtbl, sp);
/* pres() EXTENDs the stack and hence can reallocate it.
* So it calls PUTPACK afterwards and we must return here
* to avoid the implicit PUTBACK that XS inserts. */
return;
}
}
END:
void
data_sort(I, ...)
MMapDB I;
PPCODE:
if( items>1 ) {
int i;
UV pos;
char *datap, *intfmt;
UV dataend, dbfmt;
SV **svp=av_fetch(I, MMDB_DATA, 0);
SV* rsv;
void* strtbl;
if( expect_true((svp && SvROK(*svp))) ) {
datap=SvPV_nolen(SvRV(*svp));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
for( i=1; i<items; i++ ) {
pos=SvUV(ST(i));
if( expect_true(pos<dataend) ) {
rsv=L(intfmt[0],dsort)(aTHX_ datap+pos, dbfmt, strtbl);
PUSHs(sv_2mortal(rsv));
} else {
PUSHs(&PL_sv_undef);
}
}
}
}
void
index_lookup_sorts(I, ...)
MMapDB I;
PPCODE:
if( expect_true(items>1) ) {
UV pos=SvUV(ST(1));
STRLEN keylen;
char *datap, *intfmt, *keyp;
SV **svp=av_fetch(I, MMDB_DATA, 0);
void *strtbl, *found=0;
UV dataend, dbfmt;
int i, isidx=1;
if( expect_false(!(svp && SvROK(*svp))) ) goto END;
datap=SvPV_nolen(SvRV(*svp));
intfmt=SvPV_nolen(*av_fetch(I, MMDB_INTFMT, 0));
strtbl=datap+SvUV(*av_fetch(I, MMDB_STRINGTBL, 0));
dataend=SvUV(*av_fetch(I, MMDB_MAINIDX, 0));
dbfmt=SvUV(*av_fetch(I, MMDB_DBFORMAT_IN, 0));
W("MainIdx=%d, pos=%d\n", (int)dataend, (int)pos);
if( !pos ) pos=dataend;
for(i=2; i<items && isidx; i++) {
keyp=SvPV(ST(i), keylen);
W("\nlooking for %*s\n", (int)keylen, (char*)keyp);
found=L(intfmt[0],idx)(keyp, keylen, dbfmt, SvUTF8(ST(i)), datap+pos,
strtbl, dataend,
&isidx, &pos);
W(" --> found %lx\n", (long)found);
if(!found) goto END;
}
if( expect_true(found && i==items) ) {
L(intfmt[0],psorts)(aTHX_ found, dbfmt, datap, dataend, strtbl, sp);
/* pres() EXTENDs the stack and hence can reallocate it.
* So it calls PUTPACK afterwards and we must return here
* to avoid the implicit PUTBACK that XS inserts. */
return;
}
}
END:
int
_localizing()
CODE:
RETVAL=PL_localizing;
OUTPUT:
RETVAL
## Local Variables:
## mode: C
## End:
( run in 1.519 second using v1.01-cache-2.11-cpan-5511b514fd6 )