ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

hash.c
Go to the documentation of this file.
00001 /*
00002  * hash.c: chained hash tables
00003  *
00004  * Reference: Your favorite introductory book on algorithms
00005  *
00006  * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
00007  *
00008  * Permission to use, copy, modify, and distribute this software for any
00009  * purpose with or without fee is hereby granted, provided that the above
00010  * copyright notice and this permission notice appear in all copies.
00011  *
00012  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
00013  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
00014  * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
00015  * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
00016  *
00017  * Author: breese@users.sourceforge.net
00018  */
00019 
00020 #define IN_LIBXML
00021 #include "libxml.h"
00022 
00023 #include <string.h>
00024 #include <libxml/parser.h>
00025 #include <libxml/hash.h>
00026 #include <libxml/xmlmemory.h>
00027 #include <libxml/xmlerror.h>
00028 #include <libxml/globals.h>
00029 
00030 #define MAX_HASH_LEN 8
00031 
00032 /* #define DEBUG_GROW */
00033 
00034 /*
00035  * A single entry in the hash table
00036  */
00037 typedef struct _xmlHashEntry xmlHashEntry;
00038 typedef xmlHashEntry *xmlHashEntryPtr;
00039 struct _xmlHashEntry {
00040     struct _xmlHashEntry *next;
00041     xmlChar *name;
00042     xmlChar *name2;
00043     xmlChar *name3;
00044     void *payload;
00045     int valid;
00046 };
00047 
00048 /*
00049  * The entire hash table
00050  */
00051 struct _xmlHashTable {
00052     struct _xmlHashEntry *table;
00053     int size;
00054     int nbElems;
00055     xmlDictPtr dict;
00056 };
00057 
00058 /*
00059  * xmlHashComputeKey:
00060  * Calculate the hash key
00061  */
00062 static unsigned long
00063 xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
00064               const xmlChar *name2, const xmlChar *name3) {
00065     unsigned long value = 0L;
00066     char ch;
00067     
00068     if (name != NULL) {
00069     value += 30 * (*name);
00070     while ((ch = *name++) != 0) {
00071         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00072     }
00073     }
00074     if (name2 != NULL) {
00075     while ((ch = *name2++) != 0) {
00076         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00077     }
00078     }
00079     if (name3 != NULL) {
00080     while ((ch = *name3++) != 0) {
00081         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00082     }
00083     }
00084     return (value % table->size);
00085 }
00086 
00087 static unsigned long
00088 xmlHashComputeQKey(xmlHashTablePtr table,
00089            const xmlChar *prefix, const xmlChar *name,
00090            const xmlChar *prefix2, const xmlChar *name2,
00091            const xmlChar *prefix3, const xmlChar *name3) {
00092     unsigned long value = 0L;
00093     char ch;
00094     
00095     if (prefix != NULL)
00096     value += 30 * (*prefix);
00097     else
00098     value += 30 * (*name);
00099 
00100     if (prefix != NULL) {
00101     while ((ch = *prefix++) != 0) {
00102         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00103     }
00104     value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
00105     }
00106     if (name != NULL) {
00107     while ((ch = *name++) != 0) {
00108         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00109     }
00110     }
00111     if (prefix2 != NULL) {
00112     while ((ch = *prefix2++) != 0) {
00113         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00114     }
00115     value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
00116     }
00117     if (name2 != NULL) {
00118     while ((ch = *name2++) != 0) {
00119         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00120     }
00121     }
00122     if (prefix3 != NULL) {
00123     while ((ch = *prefix3++) != 0) {
00124         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00125     }
00126     value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
00127     }
00128     if (name3 != NULL) {
00129     while ((ch = *name3++) != 0) {
00130         value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
00131     }
00132     }
00133     return (value % table->size);
00134 }
00135 
00144 xmlHashTablePtr
00145 xmlHashCreate(int size) {
00146     xmlHashTablePtr table;
00147   
00148     if (size <= 0)
00149         size = 256;
00150   
00151     table = xmlMalloc(sizeof(xmlHashTable));
00152     if (table) {
00153         table->dict = NULL;
00154         table->size = size;
00155     table->nbElems = 0;
00156         table->table = xmlMalloc(size * sizeof(xmlHashEntry));
00157         if (table->table) {
00158         memset(table->table, 0, size * sizeof(xmlHashEntry));
00159         return(table);
00160         }
00161         xmlFree(table);
00162     }
00163     return(NULL);
00164 }
00165 
00175 xmlHashTablePtr
00176 xmlHashCreateDict(int size, xmlDictPtr dict) {
00177     xmlHashTablePtr table;
00178 
00179     table = xmlHashCreate(size);
00180     if (table != NULL) {
00181         table->dict = dict;
00182     xmlDictReference(dict);
00183     }
00184     return(table);
00185 }
00186 
00196 static int
00197 xmlHashGrow(xmlHashTablePtr table, int size) {
00198     unsigned long key;
00199     int oldsize, i;
00200     xmlHashEntryPtr iter, next;
00201     struct _xmlHashEntry *oldtable;
00202 #ifdef DEBUG_GROW
00203     unsigned long nbElem = 0;
00204 #endif
00205   
00206     if (table == NULL)
00207     return(-1);
00208     if (size < 8)
00209         return(-1);
00210     if (size > 8 * 2048)
00211     return(-1);
00212 
00213     oldsize = table->size;
00214     oldtable = table->table;
00215     if (oldtable == NULL)
00216         return(-1);
00217   
00218     table->table = xmlMalloc(size * sizeof(xmlHashEntry));
00219     if (table->table == NULL) {
00220     table->table = oldtable;
00221     return(-1);
00222     }
00223     memset(table->table, 0, size * sizeof(xmlHashEntry));
00224     table->size = size;
00225 
00226     /*  If the two loops are merged, there would be situations where
00227     a new entry needs to allocated and data copied into it from 
00228     the main table. So instead, we run through the array twice, first
00229     copying all the elements in the main array (where we can't get
00230     conflicts) and then the rest, so we only free (and don't allocate)
00231     */
00232     for (i = 0; i < oldsize; i++) {
00233     if (oldtable[i].valid == 0) 
00234         continue;
00235     key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
00236                 oldtable[i].name3);
00237     memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
00238     table->table[key].next = NULL;
00239     }
00240 
00241     for (i = 0; i < oldsize; i++) {
00242     iter = oldtable[i].next;
00243     while (iter) {
00244         next = iter->next;
00245 
00246         /*
00247          * put back the entry in the new table
00248          */
00249 
00250         key = xmlHashComputeKey(table, iter->name, iter->name2,
00251                             iter->name3);
00252         if (table->table[key].valid == 0) {
00253         memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
00254         table->table[key].next = NULL;
00255         xmlFree(iter);
00256         } else {
00257             iter->next = table->table[key].next;
00258             table->table[key].next = iter;
00259         }
00260 
00261 #ifdef DEBUG_GROW
00262         nbElem++;
00263 #endif
00264 
00265         iter = next;
00266     }
00267     }
00268 
00269     xmlFree(oldtable);
00270 
00271 #ifdef DEBUG_GROW
00272     xmlGenericError(xmlGenericErrorContext,
00273         "xmlHashGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
00274 #endif
00275 
00276     return(0);
00277 }
00278 
00287 void
00288 xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
00289     int i;
00290     xmlHashEntryPtr iter;
00291     xmlHashEntryPtr next;
00292     int inside_table = 0;
00293     int nbElems;
00294 
00295     if (table == NULL)
00296     return;
00297     if (table->table) {
00298     nbElems = table->nbElems;
00299     for(i = 0; (i < table->size) && (nbElems > 0); i++) {
00300         iter = &(table->table[i]);
00301         if (iter->valid == 0)
00302         continue;
00303         inside_table = 1;
00304         while (iter) {
00305         next = iter->next;
00306         if ((f != NULL) && (iter->payload != NULL))
00307             f(iter->payload, iter->name);
00308         if (table->dict == NULL) {
00309             if (iter->name)
00310             xmlFree(iter->name);
00311             if (iter->name2)
00312             xmlFree(iter->name2);
00313             if (iter->name3)
00314             xmlFree(iter->name3);
00315         }
00316         iter->payload = NULL;
00317         if (!inside_table)
00318             xmlFree(iter);
00319         nbElems--;
00320         inside_table = 0;
00321         iter = next;
00322         }
00323     }
00324     xmlFree(table->table);
00325     }
00326     if (table->dict)
00327         xmlDictFree(table->dict);
00328     xmlFree(table);
00329 }
00330 
00342 int
00343 xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
00344     return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
00345 }
00346 
00359 int
00360 xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
00361             const xmlChar *name2, void *userdata) {
00362     return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
00363 }
00364 
00378 int
00379 xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
00380                void *userdata, xmlHashDeallocator f) {
00381     return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
00382 }
00383 
00398 int
00399 xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
00400                const xmlChar *name2, void *userdata,
00401            xmlHashDeallocator f) {
00402     return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
00403 }
00404 
00414 void *
00415 xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
00416     return(xmlHashLookup3(table, name, NULL, NULL));
00417 }
00418 
00429 void *
00430 xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
00431           const xmlChar *name2) {
00432     return(xmlHashLookup3(table, name, name2, NULL));
00433 }
00434 
00445 void *
00446 xmlHashQLookup(xmlHashTablePtr table, const xmlChar *prefix,
00447                const xmlChar *name) {
00448     return(xmlHashQLookup3(table, prefix, name, NULL, NULL, NULL, NULL));
00449 }
00450 
00463 void *
00464 xmlHashQLookup2(xmlHashTablePtr table, const xmlChar *prefix,
00465                 const xmlChar *name, const xmlChar *prefix2,
00466             const xmlChar *name2) {
00467     return(xmlHashQLookup3(table, prefix, name, prefix2, name2, NULL, NULL));
00468 }
00469 
00484 int
00485 xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
00486              const xmlChar *name2, const xmlChar *name3,
00487          void *userdata) {
00488     unsigned long key, len = 0;
00489     xmlHashEntryPtr entry;
00490     xmlHashEntryPtr insert;
00491 
00492     if ((table == NULL) || (name == NULL))
00493     return(-1);
00494 
00495     /*
00496      * If using a dict internalize if needed
00497      */
00498     if (table->dict) {
00499         if (!xmlDictOwns(table->dict, name)) {
00500         name = xmlDictLookup(table->dict, name, -1);
00501         if (name == NULL)
00502             return(-1);
00503     }
00504         if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
00505         name2 = xmlDictLookup(table->dict, name2, -1);
00506         if (name2 == NULL)
00507             return(-1);
00508     }
00509         if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
00510         name3 = xmlDictLookup(table->dict, name3, -1);
00511         if (name3 == NULL)
00512             return(-1);
00513     }
00514     }
00515 
00516     /*
00517      * Check for duplicate and insertion location.
00518      */
00519     key = xmlHashComputeKey(table, name, name2, name3);
00520     if (table->table[key].valid == 0) {
00521     insert = NULL;
00522     } else {
00523         if (table->dict) {
00524         for (insert = &(table->table[key]); insert->next != NULL;
00525          insert = insert->next) {
00526         if ((insert->name == name) &&
00527             (insert->name2 == name2) &&
00528             (insert->name3 == name3))
00529             return(-1);
00530         len++;
00531         }
00532         if ((insert->name == name) &&
00533         (insert->name2 == name2) &&
00534         (insert->name3 == name3))
00535         return(-1);
00536     } else {
00537         for (insert = &(table->table[key]); insert->next != NULL;
00538          insert = insert->next) {
00539         if ((xmlStrEqual(insert->name, name)) &&
00540             (xmlStrEqual(insert->name2, name2)) &&
00541             (xmlStrEqual(insert->name3, name3)))
00542             return(-1);
00543         len++;
00544         }
00545         if ((xmlStrEqual(insert->name, name)) &&
00546         (xmlStrEqual(insert->name2, name2)) &&
00547         (xmlStrEqual(insert->name3, name3)))
00548         return(-1);
00549     }
00550     }
00551 
00552     if (insert == NULL) {
00553     entry = &(table->table[key]);
00554     } else {
00555     entry = xmlMalloc(sizeof(xmlHashEntry));
00556     if (entry == NULL)
00557          return(-1);
00558     }
00559 
00560     if (table->dict != NULL) {
00561         entry->name = (xmlChar *) name;
00562         entry->name2 = (xmlChar *) name2;
00563         entry->name3 = (xmlChar *) name3;
00564     } else {
00565     entry->name = xmlStrdup(name);
00566     entry->name2 = xmlStrdup(name2);
00567     entry->name3 = xmlStrdup(name3);
00568     }
00569     entry->payload = userdata;
00570     entry->next = NULL;
00571     entry->valid = 1;
00572 
00573 
00574     if (insert != NULL) 
00575     insert->next = entry;
00576 
00577     table->nbElems++;
00578 
00579     if (len > MAX_HASH_LEN)
00580     xmlHashGrow(table, MAX_HASH_LEN * table->size);
00581 
00582     return(0);
00583 }
00584 
00600 int
00601 xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
00602                const xmlChar *name2, const xmlChar *name3,
00603            void *userdata, xmlHashDeallocator f) {
00604     unsigned long key;
00605     xmlHashEntryPtr entry;
00606     xmlHashEntryPtr insert;
00607 
00608     if ((table == NULL) || name == NULL)
00609     return(-1);
00610 
00611     /*
00612      * If using a dict internalize if needed
00613      */
00614     if (table->dict) {
00615         if (!xmlDictOwns(table->dict, name)) {
00616         name = xmlDictLookup(table->dict, name, -1);
00617         if (name == NULL)
00618             return(-1);
00619     }
00620         if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
00621         name2 = xmlDictLookup(table->dict, name2, -1);
00622         if (name2 == NULL)
00623             return(-1);
00624     }
00625         if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
00626         name3 = xmlDictLookup(table->dict, name3, -1);
00627         if (name3 == NULL)
00628             return(-1);
00629     }
00630     }
00631 
00632     /*
00633      * Check for duplicate and insertion location.
00634      */
00635     key = xmlHashComputeKey(table, name, name2, name3);
00636     if (table->table[key].valid == 0) {
00637     insert = NULL;
00638     } else {
00639         if (table ->dict) {
00640         for (insert = &(table->table[key]); insert->next != NULL;
00641          insert = insert->next) {
00642         if ((insert->name == name) &&
00643             (insert->name2 == name2) &&
00644             (insert->name3 == name3)) {
00645             if (f)
00646             f(insert->payload, insert->name);
00647             insert->payload = userdata;
00648             return(0);
00649         }
00650         }
00651         if ((insert->name == name) &&
00652         (insert->name2 == name2) &&
00653         (insert->name3 == name3)) {
00654         if (f)
00655             f(insert->payload, insert->name);
00656         insert->payload = userdata;
00657         return(0);
00658         }
00659     } else {
00660         for (insert = &(table->table[key]); insert->next != NULL;
00661          insert = insert->next) {
00662         if ((xmlStrEqual(insert->name, name)) &&
00663             (xmlStrEqual(insert->name2, name2)) &&
00664             (xmlStrEqual(insert->name3, name3))) {
00665             if (f)
00666             f(insert->payload, insert->name);
00667             insert->payload = userdata;
00668             return(0);
00669         }
00670         }
00671         if ((xmlStrEqual(insert->name, name)) &&
00672         (xmlStrEqual(insert->name2, name2)) &&
00673         (xmlStrEqual(insert->name3, name3))) {
00674         if (f)
00675             f(insert->payload, insert->name);
00676         insert->payload = userdata;
00677         return(0);
00678         }
00679     }
00680     }
00681 
00682     if (insert == NULL) {
00683     entry =  &(table->table[key]);
00684     } else {
00685     entry = xmlMalloc(sizeof(xmlHashEntry));
00686     if (entry == NULL)
00687          return(-1);
00688     }
00689 
00690     if (table->dict != NULL) {
00691         entry->name = (xmlChar *) name;
00692         entry->name2 = (xmlChar *) name2;
00693         entry->name3 = (xmlChar *) name3;
00694     } else {
00695     entry->name = xmlStrdup(name);
00696     entry->name2 = xmlStrdup(name2);
00697     entry->name3 = xmlStrdup(name3);
00698     }
00699     entry->payload = userdata;
00700     entry->next = NULL;
00701     entry->valid = 1;
00702     table->nbElems++;
00703 
00704 
00705     if (insert != NULL) {
00706     insert->next = entry;
00707     }
00708     return(0);
00709 }
00710 
00722 void *
00723 xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, 
00724            const xmlChar *name2, const xmlChar *name3) {
00725     unsigned long key;
00726     xmlHashEntryPtr entry;
00727 
00728     if (table == NULL)
00729     return(NULL);
00730     if (name == NULL)
00731     return(NULL);
00732     key = xmlHashComputeKey(table, name, name2, name3);
00733     if (table->table[key].valid == 0)
00734     return(NULL);
00735     if (table->dict) {
00736     for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
00737         if ((entry->name == name) &&
00738         (entry->name2 == name2) &&
00739         (entry->name3 == name3))
00740         return(entry->payload);
00741     }
00742     }
00743     for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
00744     if ((xmlStrEqual(entry->name, name)) &&
00745         (xmlStrEqual(entry->name2, name2)) &&
00746         (xmlStrEqual(entry->name3, name3)))
00747         return(entry->payload);
00748     }
00749     return(NULL);
00750 }
00751 
00766 void *
00767 xmlHashQLookup3(xmlHashTablePtr table,
00768                 const xmlChar *prefix, const xmlChar *name,
00769         const xmlChar *prefix2, const xmlChar *name2,
00770         const xmlChar *prefix3, const xmlChar *name3) {
00771     unsigned long key;
00772     xmlHashEntryPtr entry;
00773 
00774     if (table == NULL)
00775     return(NULL);
00776     if (name == NULL)
00777     return(NULL);
00778     key = xmlHashComputeQKey(table, prefix, name, prefix2,
00779                              name2, prefix3, name3);
00780     if (table->table[key].valid == 0)
00781     return(NULL);
00782     for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
00783     if ((xmlStrQEqual(prefix, name, entry->name)) &&
00784         (xmlStrQEqual(prefix2, name2, entry->name2)) &&
00785         (xmlStrQEqual(prefix3, name3, entry->name3)))
00786         return(entry->payload);
00787     }
00788     return(NULL);
00789 }
00790 
00791 typedef struct {
00792     xmlHashScanner hashscanner;
00793     void *data;
00794 } stubData;
00795 
00796 static void 
00797 stubHashScannerFull (void *payload, void *data, const xmlChar *name, 
00798                      const xmlChar *name2 ATTRIBUTE_UNUSED,
00799              const xmlChar *name3 ATTRIBUTE_UNUSED) {
00800     stubData *stubdata = (stubData *) data;
00801     stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);
00802 }                                  
00803  
00812 void
00813 xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
00814     stubData stubdata;
00815     stubdata.data = data;
00816     stubdata.hashscanner = f; 
00817     xmlHashScanFull (table, stubHashScannerFull, &stubdata);
00818 }
00819 
00828 void
00829 xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
00830     int i, nb;
00831     xmlHashEntryPtr iter;
00832     xmlHashEntryPtr next;
00833 
00834     if (table == NULL)
00835     return;
00836     if (f == NULL)
00837     return;
00838 
00839     if (table->table) {
00840     for(i = 0; i < table->size; i++) {
00841         if (table->table[i].valid == 0) 
00842         continue;
00843         iter = &(table->table[i]);
00844         while (iter) {
00845         next = iter->next;
00846                 nb = table->nbElems;
00847         if ((f != NULL) && (iter->payload != NULL))
00848             f(iter->payload, data, iter->name,
00849               iter->name2, iter->name3);
00850                 if (nb != table->nbElems) {
00851                     /* table was modified by the callback, be careful */
00852                     if (iter == &(table->table[i])) {
00853                         if (table->table[i].valid == 0)
00854                             iter = NULL;
00855                         if (table->table[i].next != next)
00856                 iter = &(table->table[i]);
00857                     } else
00858                 iter = next;
00859                 } else
00860             iter = next;
00861         }
00862     }
00863     }
00864 }
00865 
00879 void
00880 xmlHashScan3(xmlHashTablePtr table, const xmlChar *name, 
00881          const xmlChar *name2, const xmlChar *name3,
00882          xmlHashScanner f, void *data) {
00883     xmlHashScanFull3 (table, name, name2, name3,
00884               (xmlHashScannerFull) f, data);
00885 }
00886 
00900 void
00901 xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name, 
00902          const xmlChar *name2, const xmlChar *name3,
00903          xmlHashScannerFull f, void *data) {
00904     int i;
00905     xmlHashEntryPtr iter;
00906     xmlHashEntryPtr next;
00907 
00908     if (table == NULL)
00909     return;
00910     if (f == NULL)
00911     return;
00912 
00913     if (table->table) {
00914     for(i = 0; i < table->size; i++) {
00915         if (table->table[i].valid == 0)
00916         continue;
00917         iter = &(table->table[i]);
00918         while (iter) {
00919         next = iter->next;
00920         if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
00921             ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
00922             ((name3 == NULL) || (xmlStrEqual(name3, iter->name3))) &&
00923             (iter->payload != NULL)) {
00924             f(iter->payload, data, iter->name,
00925               iter->name2, iter->name3);
00926         }
00927         iter = next;
00928         }
00929     }
00930     }
00931 }
00932 
00942 xmlHashTablePtr
00943 xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
00944     int i;
00945     xmlHashEntryPtr iter;
00946     xmlHashEntryPtr next;
00947     xmlHashTablePtr ret;
00948 
00949     if (table == NULL)
00950     return(NULL);
00951     if (f == NULL)
00952     return(NULL);
00953 
00954     ret = xmlHashCreate(table->size);
00955     if (table->table) {
00956     for(i = 0; i < table->size; i++) {
00957         if (table->table[i].valid == 0)
00958         continue;
00959         iter = &(table->table[i]);
00960         while (iter) {
00961         next = iter->next;
00962         xmlHashAddEntry3(ret, iter->name, iter->name2,
00963                      iter->name3, f(iter->payload, iter->name));
00964         iter = next;
00965         }
00966     }
00967     }
00968     ret->nbElems = table->nbElems;
00969     return(ret);
00970 }
00971 
00981 int
00982 xmlHashSize(xmlHashTablePtr table) {
00983     if (table == NULL)
00984     return(-1);
00985     return(table->nbElems);
00986 }
00987 
01000 int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
01001                xmlHashDeallocator f) {
01002     return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
01003 }
01004 
01018 int
01019 xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
01020             const xmlChar *name2, xmlHashDeallocator f) {
01021     return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
01022 }
01023 
01038 int
01039 xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
01040     const xmlChar *name2, const xmlChar *name3, xmlHashDeallocator f) {
01041     unsigned long key;
01042     xmlHashEntryPtr entry;
01043     xmlHashEntryPtr prev = NULL;
01044 
01045     if (table == NULL || name == NULL)
01046         return(-1);
01047 
01048     key = xmlHashComputeKey(table, name, name2, name3);
01049     if (table->table[key].valid == 0) {
01050         return(-1);
01051     } else {
01052         for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
01053             if (xmlStrEqual(entry->name, name) &&
01054                     xmlStrEqual(entry->name2, name2) &&
01055                     xmlStrEqual(entry->name3, name3)) {
01056                 if ((f != NULL) && (entry->payload != NULL))
01057                     f(entry->payload, entry->name);
01058                 entry->payload = NULL;
01059         if (table->dict == NULL) {
01060             if(entry->name)
01061             xmlFree(entry->name);
01062             if(entry->name2)
01063             xmlFree(entry->name2);
01064             if(entry->name3)
01065             xmlFree(entry->name3);
01066         }
01067                 if(prev) {
01068                     prev->next = entry->next;
01069             xmlFree(entry);
01070         } else {
01071             if (entry->next == NULL) {
01072             entry->valid = 0;
01073             } else {
01074             entry = entry->next;
01075             memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
01076             xmlFree(entry);
01077             }
01078         }
01079                 table->nbElems--;
01080                 return(0);
01081             }
01082             prev = entry;
01083         }
01084         return(-1);
01085     }
01086 }
01087 
01088 #define bottom_hash
01089 #include "elfgcchack.h"

Generated on Sun May 27 2012 04:20:18 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.