#include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include // a compiler supporting C99 is required /* try to be compatible with older perls */ /* SvPV_nolen() macro first defined in 5.005_55 */ /* this is slow, not threadsafe, but works */ #include "patchlevel.h" #if (PATCHLEVEL == 4) || ((PATCHLEVEL == 5) && (SUBVERSION < 55)) static STRLEN nolen_na; # define SvPV_nolen(sv) SvPV ((sv), nolen_na) #endif #if PATCHLEVEL < 6 # define call_sv perl_call_sv #endif #define KEYLEN 8 // number of bytes in the l, m, r fields static SV * new_key (void) { SV *new = NEWSV(0, KEYLEN); SvPOK_only (new); SvCUR_set (new, KEYLEN); return new; } MODULE = XML::DB PACKAGE = XML::DB::Key PROTOTYPES: ENABLE int KEYLEN() CODE: RETVAL = KEYLEN; OUTPUT: RETVAL SV * 0() ALIAS: 1 = 255 CODE: RETVAL = new_key (); memset (SvPVX (RETVAL), ix, KEYLEN); OUTPUT: RETVAL # calculcate l + r SV * m(ls,rs) SV * ls SV * rs CODE: unsigned char *l, *m, *r, *me; unsigned int mx, carry; RETVAL = new_key (); l = SvPVX (ls ) + KEYLEN; r = SvPVX (rs ) + KEYLEN; m = (me = SvPVX (RETVAL)) + KEYLEN; me [0] = 'U'; me [1] = 'U'; mx = (unsigned int)*--l + (unsigned int)*--r + 1; *--m = (mx & 0x0ff) >> 1; carry = mx & 0x100; do { mx = (unsigned int)*--l + (unsigned int)*--r + (carry >> 8); *--m = (mx & 0x0ff) >> 1; m[1] |= (mx & 0x001) << 7; carry = (mx & 0x100); } while (me < m); m[0] |= carry >> 1; OUTPUT: RETVAL