📄 hash.c.svn-base
字号:
for (insert = &(table->table[key]); insert->next != NULL; insert = insert->next) { if ((xmlStrEqual(insert->name, name)) && (xmlStrEqual(insert->name2, name2)) && (xmlStrEqual(insert->name3, name3))) return(-1); len++; } if ((xmlStrEqual(insert->name, name)) && (xmlStrEqual(insert->name2, name2)) && (xmlStrEqual(insert->name3, name3))) return(-1); } if (insert == NULL) { entry = &(table->table[key]); } else { entry = xmlMalloc(sizeof(xmlHashEntry)); if (entry == NULL) return(-1); } entry->name = xmlStrdup(name); entry->name2 = xmlStrdup(name2); entry->name3 = xmlStrdup(name3); entry->payload = userdata; entry->next = NULL; entry->valid = 1; if (insert != NULL) insert->next = entry; table->nbElems++; if (len > MAX_HASH_LEN) xmlHashGrow(table, MAX_HASH_LEN * table->size); return(0);}/** * xmlHashUpdateEntry3: * @table: the hash table * @name: the name of the userdata * @name2: a second name of the userdata * @name3: a third name of the userdata * @userdata: a pointer to the userdata * @f: the deallocator function for replaced item (if any) * * Add the @userdata to the hash @table. This can later be retrieved * by using the tuple (@name, @name2, @name3). Existing entry for this tuple * will be removed and freed with @f if found. * * Returns 0 the addition succeeded and -1 in case of error. */intxmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, void *userdata, xmlHashDeallocator f) { unsigned long key; xmlHashEntryPtr entry; xmlHashEntryPtr insert; if ((table == NULL) || name == NULL) return(-1); /* * Check for duplicate and insertion location. */ key = xmlHashComputeKey(table, name, name2, name3); if (table->table[key].valid == 0) { insert = NULL; } else { for (insert = &(table->table[key]); insert->next != NULL; insert = insert->next) { if ((xmlStrEqual(insert->name, name)) && (xmlStrEqual(insert->name2, name2)) && (xmlStrEqual(insert->name3, name3))) { if (f) f(insert->payload, insert->name); insert->payload = userdata; return(0); } } if ((xmlStrEqual(insert->name, name)) && (xmlStrEqual(insert->name2, name2)) && (xmlStrEqual(insert->name3, name3))) { if (f) f(insert->payload, insert->name); insert->payload = userdata; return(0); } } if (insert == NULL) { entry = &(table->table[key]); } else { entry = xmlMalloc(sizeof(xmlHashEntry)); if (entry == NULL) return(-1); } entry->name = xmlStrdup(name); entry->name2 = xmlStrdup(name2); entry->name3 = xmlStrdup(name3); entry->payload = userdata; entry->next = NULL; entry->valid = 1; table->nbElems++; if (insert != NULL) { insert->next = entry; } return(0);}/** * xmlHashLookup3: * @table: the hash table * @name: the name of the userdata * @name2: a second name of the userdata * @name3: a third name of the userdata * * Find the userdata specified by the (@name, @name2, @name3) tuple. * * Returns the a pointer to the userdata */void *xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3) { unsigned long key; xmlHashEntryPtr entry; if (table == NULL) return(NULL); if (name == NULL) return(NULL); key = xmlHashComputeKey(table, name, name2, name3); if (table->table[key].valid == 0) return(NULL); for (entry = &(table->table[key]); entry != NULL; entry = entry->next) { if ((xmlStrEqual(entry->name, name)) && (xmlStrEqual(entry->name2, name2)) && (xmlStrEqual(entry->name3, name3))) return(entry->payload); } return(NULL);}/** * xmlHashQLookup3: * @table: the hash table * @prefix: the prefix of the userdata * @name: the name of the userdata * @prefix2: the second prefix of the userdata * @name2: a second name of the userdata * @prefix3: the third prefix of the userdata * @name3: a third name of the userdata * * Find the userdata specified by the (@name, @name2, @name3) tuple. * * Returns the a pointer to the userdata */void *xmlHashQLookup3(xmlHashTablePtr table, const xmlChar *prefix, const xmlChar *name, const xmlChar *prefix2, const xmlChar *name2, const xmlChar *prefix3, const xmlChar *name3) { unsigned long key; xmlHashEntryPtr entry; if (table == NULL) return(NULL); if (name == NULL) return(NULL); key = xmlHashComputeQKey(table, prefix, name, prefix2, name2, prefix3, name3); if (table->table[key].valid == 0) return(NULL); for (entry = &(table->table[key]); entry != NULL; entry = entry->next) { if ((xmlStrQEqual(prefix, name, entry->name)) && (xmlStrQEqual(prefix2, name2, entry->name2)) && (xmlStrQEqual(prefix3, name3, entry->name3))) return(entry->payload); } return(NULL);}typedef struct { xmlHashScanner hashscanner; void *data;} stubData;static void stubHashScannerFull (void *payload, void *data, const xmlChar *name, const xmlChar *name2 ATTRIBUTE_UNUSED, const xmlChar *name3 ATTRIBUTE_UNUSED) { stubData *stubdata = (stubData *) data; stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);} /** * xmlHashScan: * @table: the hash table * @f: the scanner function for items in the hash * @data: extra data passed to f * * Scan the hash @table and applied @f to each value. */voidxmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) { stubData stubdata; stubdata.data = data; stubdata.hashscanner = f; xmlHashScanFull (table, stubHashScannerFull, &stubdata);}/** * xmlHashScanFull: * @table: the hash table * @f: the scanner function for items in the hash * @data: extra data passed to f * * Scan the hash @table and applied @f to each value. */voidxmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) { int i; xmlHashEntryPtr iter; xmlHashEntryPtr next; if (table == NULL) return; if (f == NULL) return; if (table->table) { for(i = 0; i < table->size; i++) { if (table->table[i].valid == 0) continue; iter = &(table->table[i]); while (iter) { next = iter->next; if ((f != NULL) && (iter->payload != NULL)) f(iter->payload, data, iter->name, iter->name2, iter->name3); iter = next; } } }}/** * xmlHashScan3: * @table: the hash table * @name: the name of the userdata or NULL * @name2: a second name of the userdata or NULL * @name3: a third name of the userdata or NULL * @f: the scanner function for items in the hash * @data: extra data passed to f * * Scan the hash @table and applied @f to each value matching * (@name, @name2, @name3) tuple. If one of the names is null, * the comparison is considered to match. */voidxmlHashScan3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, xmlHashScanner f, void *data) { xmlHashScanFull3 (table, name, name2, name3, (xmlHashScannerFull) f, data);}/** * xmlHashScanFull3: * @table: the hash table * @name: the name of the userdata or NULL * @name2: a second name of the userdata or NULL * @name3: a third name of the userdata or NULL * @f: the scanner function for items in the hash * @data: extra data passed to f * * Scan the hash @table and applied @f to each value matching * (@name, @name2, @name3) tuple. If one of the names is null, * the comparison is considered to match. */voidxmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, xmlHashScannerFull f, void *data) { int i; xmlHashEntryPtr iter; xmlHashEntryPtr next; if (table == NULL) return; if (f == NULL) return; if (table->table) { for(i = 0; i < table->size; i++) { if (table->table[i].valid == 0) continue; iter = &(table->table[i]); while (iter) { next = iter->next; if (((name == NULL) || (xmlStrEqual(name, iter->name))) && ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) && ((name3 == NULL) || (xmlStrEqual(name3, iter->name3))) && (iter->payload != NULL)) { f(iter->payload, data, iter->name, iter->name2, iter->name3); } iter = next; } } }}/** * xmlHashCopy: * @table: the hash table * @f: the copier function for items in the hash * * Scan the hash @table and applied @f to each value. * * Returns the new table or NULL in case of error. */xmlHashTablePtrxmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) { int i; xmlHashEntryPtr iter; xmlHashEntryPtr next; xmlHashTablePtr ret; if (table == NULL) return(NULL); if (f == NULL) return(NULL); ret = xmlHashCreate(table->size); if (table->table) { for(i = 0; i < table->size; i++) { if (table->table[i].valid == 0) continue; iter = &(table->table[i]); while (iter) { next = iter->next; xmlHashAddEntry3(ret, iter->name, iter->name2, iter->name3, f(iter->payload, iter->name)); iter = next; } } } ret->nbElems = table->nbElems; return(ret);}/** * xmlHashSize: * @table: the hash table * * Query the number of elements installed in the hash @table. * * Returns the number of elements in the hash table or * -1 in case of error */intxmlHashSize(xmlHashTablePtr table) { if (table == NULL) return(-1); return(table->nbElems);}/** * xmlHashRemoveEntry: * @table: the hash table * @name: the name of the userdata * @f: the deallocator function for removed item (if any) * * Find the userdata specified by the @name and remove * it from the hash @table. Existing userdata for this tuple will be removed * and freed with @f. * * Returns 0 if the removal succeeded and -1 in case of error or not found. */int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name, xmlHashDeallocator f) { return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));}/** * xmlHashRemoveEntry2: * @table: the hash table * @name: the name of the userdata * @name2: a second name of the userdata * @f: the deallocator function for removed item (if any) * * Find the userdata specified by the (@name, @name2) tuple and remove * it from the hash @table. Existing userdata for this tuple will be removed * and freed with @f. * * Returns 0 if the removal succeeded and -1 in case of error or not found. */intxmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, xmlHashDeallocator f) { return(xmlHashRemoveEntry3(table, name, name2, NULL, f));}/** * xmlHashRemoveEntry3: * @table: the hash table * @name: the name of the userdata * @name2: a second name of the userdata * @name3: a third name of the userdata * @f: the deallocator function for removed item (if any) * * Find the userdata specified by the (@name, @name2, @name3) tuple and remove * it from the hash @table. Existing userdata for this tuple will be removed * and freed with @f. * * Returns 0 if the removal succeeded and -1 in case of error or not found. */intxmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, xmlHashDeallocator f) { unsigned long key; xmlHashEntryPtr entry; xmlHashEntryPtr prev = NULL; if (table == NULL || name == NULL) return(-1); key = xmlHashComputeKey(table, name, name2, name3); if (table->table[key].valid == 0) { return(-1); } else { for (entry = &(table->table[key]); entry != NULL; entry = entry->next) { if (xmlStrEqual(entry->name, name) && xmlStrEqual(entry->name2, name2) && xmlStrEqual(entry->name3, name3)) { if ((f != NULL) && (entry->payload != NULL)) f(entry->payload, entry->name); entry->payload = NULL; if(entry->name) xmlFree(entry->name); if(entry->name2) xmlFree(entry->name2); if(entry->name3) xmlFree(entry->name3); if(prev) { prev->next = entry->next; xmlFree(entry); } else { if (entry->next == NULL) { entry->valid = 0; } else { entry = entry->next; memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry)); xmlFree(entry); } } table->nbElems--; return(0); } prev = entry; } return(-1); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -