📄 db_file.xs
字号:
dSP ; void * data1, * data2 ; int retval ; int count ; data1 = key1->data ; data2 = key2->data ;#ifndef newSVpvn /* As newSVpv will assume that the data pointer is a null terminated C string if the size parameter is 0, make sure that data points to an empty string if the length is 0 */ if (key1->size == 0) data1 = "" ; if (key2->size == 0) data2 = "" ;#endif ENTER ; SAVETMPS; PUSHMARK(SP) ; EXTEND(SP,2) ; PUSHs(sv_2mortal(newSVpvn(data1,key1->size))); PUSHs(sv_2mortal(newSVpvn(data2,key2->size))); PUTBACK ; count = perl_call_sv(CurrentDB->compare, G_SCALAR); SPAGAIN ; if (count != 1) croak ("DB_File btree_compare: expected 1 return value from compare sub, got %d\n", count) ; retval = POPi ; PUTBACK ; FREETMPS ; LEAVE ; return (retval) ;}static DB_Prefix_t#ifdef AT_LEAST_DB_3_2#ifdef CAN_PROTOTYPEbtree_prefix(DB * db, const DBT *key1, const DBT *key2)#elsebtree_prefix(db, key1, key2)Db * db ;const DBT * key1 ;const DBT * key2 ;#endif#else /* Berkeley DB < 3.2 */#ifdef CAN_PROTOTYPEbtree_prefix(const DBT *key1, const DBT *key2)#elsebtree_prefix(key1, key2)const DBT * key1 ;const DBT * key2 ;#endif#endif{#ifdef dTHX dTHX;#endif dSP ; void * data1, * data2 ; int retval ; int count ; data1 = key1->data ; data2 = key2->data ;#ifndef newSVpvn /* As newSVpv will assume that the data pointer is a null terminated C string if the size parameter is 0, make sure that data points to an empty string if the length is 0 */ if (key1->size == 0) data1 = "" ; if (key2->size == 0) data2 = "" ;#endif ENTER ; SAVETMPS; PUSHMARK(SP) ; EXTEND(SP,2) ; PUSHs(sv_2mortal(newSVpvn(data1,key1->size))); PUSHs(sv_2mortal(newSVpvn(data2,key2->size))); PUTBACK ; count = perl_call_sv(CurrentDB->prefix, G_SCALAR); SPAGAIN ; if (count != 1) croak ("DB_File btree_prefix: expected 1 return value from prefix sub, got %d\n", count) ; retval = POPi ; PUTBACK ; FREETMPS ; LEAVE ; return (retval) ;}#ifdef BERKELEY_DB_1# define HASH_CB_SIZE_TYPE size_t#else# define HASH_CB_SIZE_TYPE u_int32_t#endifstatic DB_Hash_t#ifdef AT_LEAST_DB_3_2#ifdef CAN_PROTOTYPEhash_cb(DB * db, const void *data, u_int32_t size)#elsehash_cb(db, data, size)DB * db ;const void * data ;HASH_CB_SIZE_TYPE size ;#endif#else /* Berkeley DB < 3.2 */#ifdef CAN_PROTOTYPEhash_cb(const void *data, HASH_CB_SIZE_TYPE size)#elsehash_cb(data, size)const void * data ;HASH_CB_SIZE_TYPE size ;#endif#endif{#ifdef dTHX dTHX;#endif dSP ; int retval ; int count ;#ifndef newSVpvn if (size == 0) data = "" ;#endif /* DGH - Next two lines added to fix corrupted stack problem */ ENTER ; SAVETMPS; PUSHMARK(SP) ; XPUSHs(sv_2mortal(newSVpvn((char*)data,size))); PUTBACK ; count = perl_call_sv(CurrentDB->hash, G_SCALAR); SPAGAIN ; if (count != 1) croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ; retval = POPi ; PUTBACK ; FREETMPS ; LEAVE ; return (retval) ;}#if defined(TRACE) && defined(BERKELEY_DB_1_OR_2)static void#ifdef CAN_PROTOTYPEPrintHash(INFO *hash)#elsePrintHash(hash)INFO * hash ;#endif{ printf ("HASH Info\n") ; printf (" hash = %s\n", (hash->db_HA_hash != NULL ? "redefined" : "default")) ; printf (" bsize = %d\n", hash->db_HA_bsize) ; printf (" ffactor = %d\n", hash->db_HA_ffactor) ; printf (" nelem = %d\n", hash->db_HA_nelem) ; printf (" cachesize = %d\n", hash->db_HA_cachesize) ; printf (" lorder = %d\n", hash->db_HA_lorder) ;}static void#ifdef CAN_PROTOTYPEPrintRecno(INFO *recno)#elsePrintRecno(recno)INFO * recno ;#endif{ printf ("RECNO Info\n") ; printf (" flags = %d\n", recno->db_RE_flags) ; printf (" cachesize = %d\n", recno->db_RE_cachesize) ; printf (" psize = %d\n", recno->db_RE_psize) ; printf (" lorder = %d\n", recno->db_RE_lorder) ; printf (" reclen = %ul\n", (unsigned long)recno->db_RE_reclen) ; printf (" bval = %d 0x%x\n", recno->db_RE_bval, recno->db_RE_bval) ; printf (" bfname = %d [%s]\n", recno->db_RE_bfname, recno->db_RE_bfname) ;}static void#ifdef CAN_PROTOTYPEPrintBtree(INFO *btree)#elsePrintBtree(btree)INFO * btree ;#endif{ printf ("BTREE Info\n") ; printf (" compare = %s\n", (btree->db_BT_compare ? "redefined" : "default")) ; printf (" prefix = %s\n", (btree->db_BT_prefix ? "redefined" : "default")) ; printf (" flags = %d\n", btree->db_BT_flags) ; printf (" cachesize = %d\n", btree->db_BT_cachesize) ; printf (" psize = %d\n", btree->db_BT_psize) ;#ifndef DB_VERSION_MAJOR printf (" maxkeypage = %d\n", btree->db_BT_maxkeypage) ; printf (" minkeypage = %d\n", btree->db_BT_minkeypage) ;#endif printf (" lorder = %d\n", btree->db_BT_lorder) ;}#else#define PrintRecno(recno)#define PrintHash(hash)#define PrintBtree(btree)#endif /* TRACE */static I32#ifdef CAN_PROTOTYPEGetArrayLength(pTHX_ DB_File db)#elseGetArrayLength(db)DB_File db ;#endif{ DBT key ; DBT value ; int RETVAL ; DBT_clear(key) ; DBT_clear(value) ; RETVAL = do_SEQ(db, key, value, R_LAST) ; if (RETVAL == 0) RETVAL = *(I32 *)key.data ; else /* No key means empty file */ RETVAL = 0 ; return ((I32)RETVAL) ;}static recno_t#ifdef CAN_PROTOTYPEGetRecnoKey(pTHX_ DB_File db, I32 value)#elseGetRecnoKey(db, value)DB_File db ;I32 value ;#endif{ if (value < 0) { /* Get the length of the array */ I32 length = GetArrayLength(aTHX_ db) ; /* check for attempt to write before start of array */ if (length + value + 1 <= 0) croak("Modification of non-creatable array value attempted, subscript %ld", (long)value) ; value = length + value + 1 ; } else ++ value ; return value ;}static DB_File#ifdef CAN_PROTOTYPEParseOpenInfo(pTHX_ int isHASH, char *name, int flags, int mode, SV *sv)#elseParseOpenInfo(isHASH, name, flags, mode, sv)int isHASH ;char * name ;int flags ;int mode ;SV * sv ;#endif{#ifdef BERKELEY_DB_1_OR_2 /* Berkeley DB Version 1 or 2 */ SV ** svp; HV * action ; DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ; void * openinfo = NULL ; INFO * info = &RETVAL->info ; STRLEN n_a;/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */ Zero(RETVAL, 1, DB_File_type) ; /* Default to HASH */#ifdef DBM_FILTERING RETVAL->filtering = 0 ; RETVAL->filter_fetch_key = RETVAL->filter_store_key = RETVAL->filter_fetch_value = RETVAL->filter_store_value =#endif /* DBM_FILTERING */ RETVAL->hash = RETVAL->compare = RETVAL->prefix = NULL ; RETVAL->type = DB_HASH ; /* DGH - Next line added to avoid SEGV on existing hash DB */ CurrentDB = RETVAL; /* fd for 1.86 hash in memory files doesn't return -1 like 1.85 */ RETVAL->in_memory = (name == NULL) ; if (sv) { if (! SvROK(sv) ) croak ("type parameter is not a reference") ; svp = hv_fetch( (HV*)SvRV(sv), "GOT", 3, FALSE) ; if (svp && SvOK(*svp)) action = (HV*) SvRV(*svp) ; else croak("internal error") ; if (sv_isa(sv, "DB_File::HASHINFO")) { if (!isHASH) croak("DB_File can only tie an associative array to a DB_HASH database") ; RETVAL->type = DB_HASH ; openinfo = (void*)info ; svp = hv_fetch(action, "hash", 4, FALSE); if (svp && SvOK(*svp)) { info->db_HA_hash = hash_cb ; RETVAL->hash = newSVsv(*svp) ; } else info->db_HA_hash = NULL ; svp = hv_fetch(action, "ffactor", 7, FALSE); info->db_HA_ffactor = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "nelem", 5, FALSE); info->db_HA_nelem = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "bsize", 5, FALSE); info->db_HA_bsize = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "cachesize", 9, FALSE); info->db_HA_cachesize = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "lorder", 6, FALSE); info->db_HA_lorder = svp ? SvIV(*svp) : 0; PrintHash(info) ; } else if (sv_isa(sv, "DB_File::BTREEINFO")) { if (!isHASH) croak("DB_File can only tie an associative array to a DB_BTREE database"); RETVAL->type = DB_BTREE ; openinfo = (void*)info ; svp = hv_fetch(action, "compare", 7, FALSE); if (svp && SvOK(*svp)) { info->db_BT_compare = btree_compare ; RETVAL->compare = newSVsv(*svp) ; } else info->db_BT_compare = NULL ; svp = hv_fetch(action, "prefix", 6, FALSE); if (svp && SvOK(*svp)) { info->db_BT_prefix = btree_prefix ; RETVAL->prefix = newSVsv(*svp) ; } else info->db_BT_prefix = NULL ; svp = hv_fetch(action, "flags", 5, FALSE); info->db_BT_flags = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "cachesize", 9, FALSE); info->db_BT_cachesize = svp ? SvIV(*svp) : 0; #ifndef DB_VERSION_MAJOR svp = hv_fetch(action, "minkeypage", 10, FALSE); info->btree.minkeypage = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "maxkeypage", 10, FALSE); info->btree.maxkeypage = svp ? SvIV(*svp) : 0;#endif svp = hv_fetch(action, "psize", 5, FALSE); info->db_BT_psize = svp ? SvIV(*svp) : 0; svp = hv_fetch(action, "lorder", 6, FALSE); info->db_BT_lorder = svp ? SvIV(*svp) : 0; PrintBtree(info) ; } else if (sv_isa(sv, "DB_File::RECNOINFO")) { if (isHASH) croak("DB_File can only tie an array to a DB_RECNO database"); RETVAL->type = DB_RECNO ; openinfo = (void *)info ; info->db_RE_flags = 0 ; svp = hv_fetch(action, "flags", 5, FALSE); info->db_RE_flags = (u_long) (svp ? SvIV(*svp) : 0); svp = hv_fetch(action, "reclen", 6, FALSE); info->db_RE_reclen = (size_t) (svp ? SvIV(*svp) : 0); svp = hv_fetch(action, "cachesize", 9, FALSE); info->db_RE_cachesize = (u_int) (svp ? SvIV(*svp) : 0); svp = hv_fetch(action, "psize", 5, FALSE); info->db_RE_psize = (u_int) (svp ? SvIV(*svp) : 0); svp = hv_fetch(action, "lorder", 6, FALSE); info->db_RE_lorder = (int) (svp ? SvIV(*svp) : 0);#ifdef DB_VERSION_MAJOR info->re_source = name ; name = NULL ;#endif svp = hv_fetch(action, "bfname", 6, FALSE); if (svp && SvOK(*svp)) { char * ptr = SvPV(*svp,n_a) ;#ifdef DB_VERSION_MAJOR name = (char*) n_a ? ptr : NULL ;#else info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;#endif } else#ifdef DB_VERSION_MAJOR name = NULL ;#else info->db_RE_bfname = NULL ;#endif svp = hv_fetch(action, "bval", 4, FALSE);#ifdef DB_VERSION_MAJOR if (svp && SvOK(*svp)) { int value ; if (SvPOK(*svp)) value = (int)*SvPV(*svp, n_a) ; else value = SvIV(*svp) ; if (info->flags & DB_FIXEDLEN) { info->re_pad = value ; info->flags |= DB_PAD ; } else { info->re_delim = value ; info->flags |= DB_DELIMITER ; } }#else if (svp && SvOK(*svp)) { if (SvPOK(*svp)) info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ; else info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ; DB_flags(info->flags, DB_DELIMITER) ; } else { if (info->db_RE_flags & R_FIXEDLEN)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -