MMapDB

 view release on metacpan or  search on metacpan

MMapDB.xs  view on Meta::CPAN

    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 )