📄 db_file.xs
字号:
if ( temp_cursor->c_get(temp_cursor, &l_key, &l_value, DB_SET) != 0) { (void)temp_cursor->c_close(temp_cursor); return (-1); } status = temp_cursor->c_put(temp_cursor, &key, &value, flags); (void)temp_cursor->c_close(temp_cursor); return (status) ; } if (flagSet(flags, R_CURSOR)) { return ((db->cursor)->c_put)(db->cursor, &key, &value, DB_CURRENT); } if (flagSet(flags, R_SETCURSOR)) { if ((db->dbp)->put(db->dbp, NULL, &key, &value, 0) != 0) return -1 ; return ((db->cursor)->c_get)(db->cursor, &key, &value, DB_SET_RANGE); } return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;}#endif /* DB_VERSION_MAJOR */static voidtidyUp(DB_File db){ db->aborted = TRUE ;}static int#ifdef AT_LEAST_DB_3_2#ifdef CAN_PROTOTYPEbtree_compare(DB * db, const DBT *key1, const DBT *key2)#elsebtree_compare(db, key1, key2)DB * db ;const DBT * key1 ;const DBT * key2 ;#endif /* CAN_PROTOTYPE */#else /* Berkeley DB < 3.2 */#ifdef CAN_PROTOTYPEbtree_compare(const DBT *key1, const DBT *key2)#elsebtree_compare(key1, key2)const DBT * key1 ;const DBT * key2 ;#endif#endif{#ifdef dTHX dTHX;#endif dSP ; dMY_CXT ; void * data1, * data2 ; int retval ; int count ; if (CurrentDB->in_compare) { tidyUp(CurrentDB); croak ("DB_File btree_compare: recursion detected\n") ; } data1 = (char *) key1->data ; data2 = (char *) 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; SAVESPTR(CurrentDB); CurrentDB->in_compare = FALSE; SAVEINT(CurrentDB->in_compare); CurrentDB->in_compare = TRUE; 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){ tidyUp(CurrentDB); 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 ; dMY_CXT ; char * data1, * data2 ; int retval ; int count ; if (CurrentDB->in_prefix){ tidyUp(CurrentDB); croak ("DB_File btree_prefix: recursion detected\n") ; } data1 = (char *) key1->data ; data2 = (char *) 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; SAVESPTR(CurrentDB); CurrentDB->in_prefix = FALSE; SAVEINT(CurrentDB->in_prefix); CurrentDB->in_prefix = TRUE; 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){ tidyUp(CurrentDB); 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 ; dMY_CXT; int retval = 0; int count ; if (CurrentDB->in_hash){ tidyUp(CurrentDB); croak ("DB_File hash callback: recursion detected\n") ; }#ifndef newSVpvn if (size == 0) data = "" ;#endif /* DGH - Next two lines added to fix corrupted stack problem */ ENTER ; SAVETMPS; SAVESPTR(CurrentDB); CurrentDB->in_hash = FALSE; SAVEINT(CurrentDB->in_hash); CurrentDB->in_hash = TRUE; PUSHMARK(SP) ; XPUSHs(sv_2mortal(newSVpvn((char*)data,size))); PUTBACK ; count = perl_call_sv(CurrentDB->hash, G_SCALAR); SPAGAIN ; if (count != 1){ tidyUp(CurrentDB); croak ("DB_File hash_cb: expected 1 return value from hash sub, got %d\n", count) ; } retval = POPi ; PUTBACK ; FREETMPS ; LEAVE ; return (retval) ;}#ifdef WANT_ERRORstatic void#ifdef AT_LEAST_DB_4_3db_errcall_cb(const DB_ENV* dbenv, const char * db_errpfx, const char * buffer)#elsedb_errcall_cb(const char * db_errpfx, char * buffer)#endif{#ifdef dTHX dTHX;#endif SV * sv = perl_get_sv(ERR_BUFF, FALSE) ; if (sv) { if (db_errpfx) sv_setpvf(sv, "%s: %s", db_errpfx, buffer) ; else sv_setpv(sv, buffer) ; }} #endif#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 = %lu\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) { tidyUp(db); 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; dMY_CXT;#ifdef TRACE printf("In ParseOpenInfo name=[%s] flags=[%d] mode=[%d] SV NULL=[%d]\n", name, flags, mode, sv == NULL) ; #endif Zero(RETVAL, 1, DB_File_type) ; /* Default to HASH */ RETVAL->filtering = 0 ; RETVAL->filter_fetch_key = RETVAL->filter_store_key = RETVAL->filter_fetch_value = RETVAL->filter_store_value = 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) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -