Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(178)

Side by Side Diff: third_party/libxml/src/hash.c

Issue 1193533007: Upgrade to libxml 2.9.2 and libxslt 1.1.28 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: no iconv Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/libxml/src/globals.c ('k') | third_party/libxml/src/include/Makefile.am » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * hash.c: chained hash tables 2 * hash.c: chained hash tables
3 * 3 *
4 * Reference: Your favorite introductory book on algorithms 4 * Reference: Your favorite introductory book on algorithms
5 * 5 *
6 * Copyright (C) 2000 Bjorn Reese and Daniel Veillard. 6 * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
7 * 7 *
8 * Permission to use, copy, modify, and distribute this software for any 8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above 9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies. 10 * copyright notice and this permission notice appear in all copies.
11 * 11 *
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 13 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
14 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND 14 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
15 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. 15 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
16 * 16 *
17 * Author: breese@users.sourceforge.net 17 * Author: breese@users.sourceforge.net
18 */ 18 */
19 19
20 #define IN_LIBXML 20 #define IN_LIBXML
21 #include "libxml.h" 21 #include "libxml.h"
22 22
23 #include <string.h> 23 #include <string.h>
24 #ifdef HAVE_STDLIB_H
25 #include <stdlib.h>
26 #endif
27 #ifdef HAVE_TIME_H
28 #include <time.h>
29 #endif
30
31 /*
32 * Following http://www.ocert.org/advisories/ocert-2011-003.html
33 * it seems that having hash randomization might be a good idea
34 * when using XML with untrusted data
35 */
36 #if defined(HAVE_RAND) && defined(HAVE_SRAND) && defined(HAVE_TIME)
37 #define HASH_RANDOMIZATION
38 #endif
39
24 #include <libxml/parser.h> 40 #include <libxml/parser.h>
25 #include <libxml/hash.h> 41 #include <libxml/hash.h>
26 #include <libxml/xmlmemory.h> 42 #include <libxml/xmlmemory.h>
27 #include <libxml/xmlerror.h> 43 #include <libxml/xmlerror.h>
28 #include <libxml/globals.h> 44 #include <libxml/globals.h>
29 45
30 #define MAX_HASH_LEN 8 46 #define MAX_HASH_LEN 8
31 47
32 /* #define DEBUG_GROW */ 48 /* #define DEBUG_GROW */
33 49
(...skipping 12 matching lines...) Expand all
46 }; 62 };
47 63
48 /* 64 /*
49 * The entire hash table 65 * The entire hash table
50 */ 66 */
51 struct _xmlHashTable { 67 struct _xmlHashTable {
52 struct _xmlHashEntry *table; 68 struct _xmlHashEntry *table;
53 int size; 69 int size;
54 int nbElems; 70 int nbElems;
55 xmlDictPtr dict; 71 xmlDictPtr dict;
72 #ifdef HASH_RANDOMIZATION
73 int random_seed;
74 #endif
56 }; 75 };
57 76
58 /* 77 /*
59 * xmlHashComputeKey: 78 * xmlHashComputeKey:
60 * Calculate the hash key 79 * Calculate the hash key
61 */ 80 */
62 static unsigned long 81 static unsigned long
63 xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name, 82 xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
64 const xmlChar *name2, const xmlChar *name3) { 83 const xmlChar *name2, const xmlChar *name3) {
65 unsigned long value = 0L; 84 unsigned long value = 0L;
66 char ch; 85 char ch;
67 86
87 #ifdef HASH_RANDOMIZATION
88 value = table->random_seed;
89 #endif
68 if (name != NULL) { 90 if (name != NULL) {
69 value += 30 * (*name); 91 value += 30 * (*name);
70 while ((ch = *name++) != 0) { 92 while ((ch = *name++) != 0) {
71 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 93 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
72 } 94 }
73 } 95 }
96 value = value ^ ((value << 5) + (value >> 3));
74 if (name2 != NULL) { 97 if (name2 != NULL) {
75 while ((ch = *name2++) != 0) { 98 while ((ch = *name2++) != 0) {
76 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 99 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
77 } 100 }
78 } 101 }
102 value = value ^ ((value << 5) + (value >> 3));
79 if (name3 != NULL) { 103 if (name3 != NULL) {
80 while ((ch = *name3++) != 0) { 104 while ((ch = *name3++) != 0) {
81 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 105 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
82 } 106 }
83 } 107 }
84 return (value % table->size); 108 return (value % table->size);
85 } 109 }
86 110
87 static unsigned long 111 static unsigned long
88 xmlHashComputeQKey(xmlHashTablePtr table, 112 xmlHashComputeQKey(xmlHashTablePtr table,
89 const xmlChar *prefix, const xmlChar *name, 113 const xmlChar *prefix, const xmlChar *name,
90 const xmlChar *prefix2, const xmlChar *name2, 114 const xmlChar *prefix2, const xmlChar *name2,
91 const xmlChar *prefix3, const xmlChar *name3) { 115 const xmlChar *prefix3, const xmlChar *name3) {
92 unsigned long value = 0L; 116 unsigned long value = 0L;
93 char ch; 117 char ch;
94 118
119 #ifdef HASH_RANDOMIZATION
120 value = table->random_seed;
121 #endif
95 if (prefix != NULL) 122 if (prefix != NULL)
96 value += 30 * (*prefix); 123 value += 30 * (*prefix);
97 else 124 else
98 value += 30 * (*name); 125 value += 30 * (*name);
99 126
100 if (prefix != NULL) { 127 if (prefix != NULL) {
101 while ((ch = *prefix++) != 0) { 128 while ((ch = *prefix++) != 0) {
102 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 129 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
103 } 130 }
104 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); 131 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
105 } 132 }
106 if (name != NULL) { 133 if (name != NULL) {
107 while ((ch = *name++) != 0) { 134 while ((ch = *name++) != 0) {
108 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 135 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
109 } 136 }
110 } 137 }
138 value = value ^ ((value << 5) + (value >> 3));
111 if (prefix2 != NULL) { 139 if (prefix2 != NULL) {
112 while ((ch = *prefix2++) != 0) { 140 while ((ch = *prefix2++) != 0) {
113 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 141 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
114 } 142 }
115 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); 143 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
116 } 144 }
117 if (name2 != NULL) { 145 if (name2 != NULL) {
118 while ((ch = *name2++) != 0) { 146 while ((ch = *name2++) != 0) {
119 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 147 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
120 } 148 }
121 } 149 }
150 value = value ^ ((value << 5) + (value >> 3));
122 if (prefix3 != NULL) { 151 if (prefix3 != NULL) {
123 while ((ch = *prefix3++) != 0) { 152 while ((ch = *prefix3++) != 0) {
124 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 153 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
125 } 154 }
126 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':'); 155 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
127 } 156 }
128 if (name3 != NULL) { 157 if (name3 != NULL) {
129 while ((ch = *name3++) != 0) { 158 while ((ch = *name3++) != 0) {
130 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch); 159 value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
131 } 160 }
132 } 161 }
133 return (value % table->size); 162 return (value % table->size);
134 } 163 }
135 164
136 /** 165 /**
137 * xmlHashCreate: 166 * xmlHashCreate:
138 * @size: the size of the hash table 167 * @size: the size of the hash table
139 * 168 *
140 * Create a new xmlHashTablePtr. 169 * Create a new xmlHashTablePtr.
141 * 170 *
142 * Returns the newly created object, or NULL if an error occured. 171 * Returns the newly created object, or NULL if an error occured.
143 */ 172 */
144 xmlHashTablePtr 173 xmlHashTablePtr
145 xmlHashCreate(int size) { 174 xmlHashCreate(int size) {
146 xmlHashTablePtr table; 175 xmlHashTablePtr table;
147 176
148 if (size <= 0) 177 if (size <= 0)
149 size = 256; 178 size = 256;
150 179
151 table = xmlMalloc(sizeof(xmlHashTable)); 180 table = xmlMalloc(sizeof(xmlHashTable));
152 if (table) { 181 if (table) {
153 table->dict = NULL; 182 table->dict = NULL;
154 table->size = size; 183 table->size = size;
155 table->nbElems = 0; 184 table->nbElems = 0;
156 table->table = xmlMalloc(size * sizeof(xmlHashEntry)); 185 table->table = xmlMalloc(size * sizeof(xmlHashEntry));
157 if (table->table) { 186 if (table->table) {
158 » memset(table->table, 0, size * sizeof(xmlHashEntry)); 187 » memset(table->table, 0, size * sizeof(xmlHashEntry));
159 » return(table); 188 #ifdef HASH_RANDOMIZATION
189 table->random_seed = __xmlRandom();
190 #endif
191 » return(table);
160 } 192 }
161 xmlFree(table); 193 xmlFree(table);
162 } 194 }
163 return(NULL); 195 return(NULL);
164 } 196 }
165 197
166 /** 198 /**
167 * xmlHashCreateDict: 199 * xmlHashCreateDict:
168 * @size: the size of the hash table 200 * @size: the size of the hash table
169 * @dict: a dictionary to use for the hash 201 * @dict: a dictionary to use for the hash
(...skipping 25 matching lines...) Expand all
195 */ 227 */
196 static int 228 static int
197 xmlHashGrow(xmlHashTablePtr table, int size) { 229 xmlHashGrow(xmlHashTablePtr table, int size) {
198 unsigned long key; 230 unsigned long key;
199 int oldsize, i; 231 int oldsize, i;
200 xmlHashEntryPtr iter, next; 232 xmlHashEntryPtr iter, next;
201 struct _xmlHashEntry *oldtable; 233 struct _xmlHashEntry *oldtable;
202 #ifdef DEBUG_GROW 234 #ifdef DEBUG_GROW
203 unsigned long nbElem = 0; 235 unsigned long nbElem = 0;
204 #endif 236 #endif
205 237
206 if (table == NULL) 238 if (table == NULL)
207 return(-1); 239 return(-1);
208 if (size < 8) 240 if (size < 8)
209 return(-1); 241 return(-1);
210 if (size > 8 * 2048) 242 if (size > 8 * 2048)
211 return(-1); 243 return(-1);
212 244
213 oldsize = table->size; 245 oldsize = table->size;
214 oldtable = table->table; 246 oldtable = table->table;
215 if (oldtable == NULL) 247 if (oldtable == NULL)
216 return(-1); 248 return(-1);
217 249
218 table->table = xmlMalloc(size * sizeof(xmlHashEntry)); 250 table->table = xmlMalloc(size * sizeof(xmlHashEntry));
219 if (table->table == NULL) { 251 if (table->table == NULL) {
220 table->table = oldtable; 252 table->table = oldtable;
221 return(-1); 253 return(-1);
222 } 254 }
223 memset(table->table, 0, size * sizeof(xmlHashEntry)); 255 memset(table->table, 0, size * sizeof(xmlHashEntry));
224 table->size = size; 256 table->size = size;
225 257
226 /* If the two loops are merged, there would be situations where 258 /* If the two loops are merged, there would be situations where
227 » a new entry needs to allocated and data copied into it from 259 » a new entry needs to allocated and data copied into it from
228 the main table. So instead, we run through the array twice, first 260 the main table. So instead, we run through the array twice, first
229 copying all the elements in the main array (where we can't get 261 copying all the elements in the main array (where we can't get
230 conflicts) and then the rest, so we only free (and don't allocate) 262 conflicts) and then the rest, so we only free (and don't allocate)
231 */ 263 */
232 for (i = 0; i < oldsize; i++) { 264 for (i = 0; i < oldsize; i++) {
233 » if (oldtable[i].valid == 0) 265 » if (oldtable[i].valid == 0)
234 continue; 266 continue;
235 key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2, 267 key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
236 oldtable[i].name3); 268 oldtable[i].name3);
237 memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry)); 269 memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
238 table->table[key].next = NULL; 270 table->table[key].next = NULL;
239 } 271 }
240 272
241 for (i = 0; i < oldsize; i++) { 273 for (i = 0; i < oldsize; i++) {
242 iter = oldtable[i].next; 274 iter = oldtable[i].next;
243 while (iter) { 275 while (iter) {
244 next = iter->next; 276 next = iter->next;
245 277
246 /* 278 /*
247 * put back the entry in the new table 279 * put back the entry in the new table
248 */ 280 */
249 281
250 key = xmlHashComputeKey(table, iter->name, iter->name2, 282 key = xmlHashComputeKey(table, iter->name, iter->name2,
251 iter->name3); 283 iter->name3);
252 if (table->table[key].valid == 0) { 284 if (table->table[key].valid == 0) {
253 memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry)); 285 memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
254 table->table[key].next = NULL; 286 table->table[key].next = NULL;
255 xmlFree(iter); 287 xmlFree(iter);
256 } else { 288 } else {
257 » » iter->next = table->table[key].next; 289 » » iter->next = table->table[key].next;
258 » » table->table[key].next = iter; 290 » » table->table[key].next = iter;
259 } 291 }
260 292
261 #ifdef DEBUG_GROW 293 #ifdef DEBUG_GROW
262 nbElem++; 294 nbElem++;
263 #endif 295 #endif
264 296
265 iter = next; 297 iter = next;
266 } 298 }
267 } 299 }
268 300
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
564 } else { 596 } else {
565 entry->name = xmlStrdup(name); 597 entry->name = xmlStrdup(name);
566 entry->name2 = xmlStrdup(name2); 598 entry->name2 = xmlStrdup(name2);
567 entry->name3 = xmlStrdup(name3); 599 entry->name3 = xmlStrdup(name3);
568 } 600 }
569 entry->payload = userdata; 601 entry->payload = userdata;
570 entry->next = NULL; 602 entry->next = NULL;
571 entry->valid = 1; 603 entry->valid = 1;
572 604
573 605
574 if (insert != NULL) 606 if (insert != NULL)
575 insert->next = entry; 607 insert->next = entry;
576 608
577 table->nbElems++; 609 table->nbElems++;
578 610
579 if (len > MAX_HASH_LEN) 611 if (len > MAX_HASH_LEN)
580 xmlHashGrow(table, MAX_HASH_LEN * table->size); 612 xmlHashGrow(table, MAX_HASH_LEN * table->size);
581 613
582 return(0); 614 return(0);
583 } 615 }
584 616
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 * @table: the hash table 745 * @table: the hash table
714 * @name: the name of the userdata 746 * @name: the name of the userdata
715 * @name2: a second name of the userdata 747 * @name2: a second name of the userdata
716 * @name3: a third name of the userdata 748 * @name3: a third name of the userdata
717 * 749 *
718 * Find the userdata specified by the (@name, @name2, @name3) tuple. 750 * Find the userdata specified by the (@name, @name2, @name3) tuple.
719 * 751 *
720 * Returns the a pointer to the userdata 752 * Returns the a pointer to the userdata
721 */ 753 */
722 void * 754 void *
723 xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, 755 xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
724 const xmlChar *name2, const xmlChar *name3) { 756 const xmlChar *name2, const xmlChar *name3) {
725 unsigned long key; 757 unsigned long key;
726 xmlHashEntryPtr entry; 758 xmlHashEntryPtr entry;
727 759
728 if (table == NULL) 760 if (table == NULL)
729 return(NULL); 761 return(NULL);
730 if (name == NULL) 762 if (name == NULL)
731 return(NULL); 763 return(NULL);
732 key = xmlHashComputeKey(table, name, name2, name3); 764 key = xmlHashComputeKey(table, name, name2, name3);
733 if (table->table[key].valid == 0) 765 if (table->table[key].valid == 0)
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 return(entry->payload); 818 return(entry->payload);
787 } 819 }
788 return(NULL); 820 return(NULL);
789 } 821 }
790 822
791 typedef struct { 823 typedef struct {
792 xmlHashScanner hashscanner; 824 xmlHashScanner hashscanner;
793 void *data; 825 void *data;
794 } stubData; 826 } stubData;
795 827
796 static void 828 static void
797 stubHashScannerFull (void *payload, void *data, const xmlChar *name, 829 stubHashScannerFull (void *payload, void *data, const xmlChar *name,
798 const xmlChar *name2 ATTRIBUTE_UNUSED, 830 const xmlChar *name2 ATTRIBUTE_UNUSED,
799 const xmlChar *name3 ATTRIBUTE_UNUSED) { 831 const xmlChar *name3 ATTRIBUTE_UNUSED) {
800 stubData *stubdata = (stubData *) data; 832 stubData *stubdata = (stubData *) data;
801 stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name); 833 stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);
802 } 834 }
803 835
804 /** 836 /**
805 * xmlHashScan: 837 * xmlHashScan:
806 * @table: the hash table 838 * @table: the hash table
807 * @f: the scanner function for items in the hash 839 * @f: the scanner function for items in the hash
808 * @data: extra data passed to f 840 * @data: extra data passed to f
809 * 841 *
810 * Scan the hash @table and applied @f to each value. 842 * Scan the hash @table and applied @f to each value.
811 */ 843 */
812 void 844 void
813 xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) { 845 xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
814 stubData stubdata; 846 stubData stubdata;
815 stubdata.data = data; 847 stubdata.data = data;
816 stubdata.hashscanner = f; 848 stubdata.hashscanner = f;
817 xmlHashScanFull (table, stubHashScannerFull, &stubdata); 849 xmlHashScanFull (table, stubHashScannerFull, &stubdata);
818 } 850 }
819 851
820 /** 852 /**
821 * xmlHashScanFull: 853 * xmlHashScanFull:
822 * @table: the hash table 854 * @table: the hash table
823 * @f: the scanner function for items in the hash 855 * @f: the scanner function for items in the hash
824 * @data: extra data passed to f 856 * @data: extra data passed to f
825 * 857 *
826 * Scan the hash @table and applied @f to each value. 858 * Scan the hash @table and applied @f to each value.
827 */ 859 */
828 void 860 void
829 xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) { 861 xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
830 int i, nb; 862 int i, nb;
831 xmlHashEntryPtr iter; 863 xmlHashEntryPtr iter;
832 xmlHashEntryPtr next; 864 xmlHashEntryPtr next;
833 865
834 if (table == NULL) 866 if (table == NULL)
835 return; 867 return;
836 if (f == NULL) 868 if (f == NULL)
837 return; 869 return;
838 870
839 if (table->table) { 871 if (table->table) {
840 for(i = 0; i < table->size; i++) { 872 for(i = 0; i < table->size; i++) {
841 » if (table->table[i].valid == 0) 873 » if (table->table[i].valid == 0)
842 continue; 874 continue;
843 iter = &(table->table[i]); 875 iter = &(table->table[i]);
844 while (iter) { 876 while (iter) {
845 next = iter->next; 877 next = iter->next;
846 nb = table->nbElems; 878 nb = table->nbElems;
847 if ((f != NULL) && (iter->payload != NULL)) 879 if ((f != NULL) && (iter->payload != NULL))
848 f(iter->payload, data, iter->name, 880 f(iter->payload, data, iter->name,
849 iter->name2, iter->name3); 881 iter->name2, iter->name3);
850 if (nb != table->nbElems) { 882 if (nb != table->nbElems) {
851 /* table was modified by the callback, be careful */ 883 /* table was modified by the callback, be careful */
(...skipping 18 matching lines...) Expand all
870 * @name2: a second name of the userdata or NULL 902 * @name2: a second name of the userdata or NULL
871 * @name3: a third name of the userdata or NULL 903 * @name3: a third name of the userdata or NULL
872 * @f: the scanner function for items in the hash 904 * @f: the scanner function for items in the hash
873 * @data: extra data passed to f 905 * @data: extra data passed to f
874 * 906 *
875 * Scan the hash @table and applied @f to each value matching 907 * Scan the hash @table and applied @f to each value matching
876 * (@name, @name2, @name3) tuple. If one of the names is null, 908 * (@name, @name2, @name3) tuple. If one of the names is null,
877 * the comparison is considered to match. 909 * the comparison is considered to match.
878 */ 910 */
879 void 911 void
880 xmlHashScan3(xmlHashTablePtr table, const xmlChar *name, 912 xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
881 const xmlChar *name2, const xmlChar *name3, 913 const xmlChar *name2, const xmlChar *name3,
882 xmlHashScanner f, void *data) { 914 xmlHashScanner f, void *data) {
883 xmlHashScanFull3 (table, name, name2, name3, 915 xmlHashScanFull3 (table, name, name2, name3,
884 (xmlHashScannerFull) f, data); 916 (xmlHashScannerFull) f, data);
885 } 917 }
886 918
887 /** 919 /**
888 * xmlHashScanFull3: 920 * xmlHashScanFull3:
889 * @table: the hash table 921 * @table: the hash table
890 * @name: the name of the userdata or NULL 922 * @name: the name of the userdata or NULL
891 * @name2: a second name of the userdata or NULL 923 * @name2: a second name of the userdata or NULL
892 * @name3: a third name of the userdata or NULL 924 * @name3: a third name of the userdata or NULL
893 * @f: the scanner function for items in the hash 925 * @f: the scanner function for items in the hash
894 * @data: extra data passed to f 926 * @data: extra data passed to f
895 * 927 *
896 * Scan the hash @table and applied @f to each value matching 928 * Scan the hash @table and applied @f to each value matching
897 * (@name, @name2, @name3) tuple. If one of the names is null, 929 * (@name, @name2, @name3) tuple. If one of the names is null,
898 * the comparison is considered to match. 930 * the comparison is considered to match.
899 */ 931 */
900 void 932 void
901 xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name, 933 xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name,
902 const xmlChar *name2, const xmlChar *name3, 934 const xmlChar *name2, const xmlChar *name3,
903 xmlHashScannerFull f, void *data) { 935 xmlHashScannerFull f, void *data) {
904 int i; 936 int i;
905 xmlHashEntryPtr iter; 937 xmlHashEntryPtr iter;
906 xmlHashEntryPtr next; 938 xmlHashEntryPtr next;
907 939
908 if (table == NULL) 940 if (table == NULL)
909 return; 941 return;
910 if (f == NULL) 942 if (f == NULL)
911 return; 943 return;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 xmlHashEntryPtr iter; 977 xmlHashEntryPtr iter;
946 xmlHashEntryPtr next; 978 xmlHashEntryPtr next;
947 xmlHashTablePtr ret; 979 xmlHashTablePtr ret;
948 980
949 if (table == NULL) 981 if (table == NULL)
950 return(NULL); 982 return(NULL);
951 if (f == NULL) 983 if (f == NULL)
952 return(NULL); 984 return(NULL);
953 985
954 ret = xmlHashCreate(table->size); 986 ret = xmlHashCreate(table->size);
987 if (ret == NULL)
988 return(NULL);
989
955 if (table->table) { 990 if (table->table) {
956 for(i = 0; i < table->size; i++) { 991 for(i = 0; i < table->size; i++) {
957 if (table->table[i].valid == 0) 992 if (table->table[i].valid == 0)
958 continue; 993 continue;
959 iter = &(table->table[i]); 994 iter = &(table->table[i]);
960 while (iter) { 995 while (iter) {
961 next = iter->next; 996 next = iter->next;
962 xmlHashAddEntry3(ret, iter->name, iter->name2, 997 xmlHashAddEntry3(ret, iter->name, iter->name2,
963 iter->name3, f(iter->payload, iter->name)); 998 iter->name3, f(iter->payload, iter->name));
964 iter = next; 999 iter = next;
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
1080 return(0); 1115 return(0);
1081 } 1116 }
1082 prev = entry; 1117 prev = entry;
1083 } 1118 }
1084 return(-1); 1119 return(-1);
1085 } 1120 }
1086 } 1121 }
1087 1122
1088 #define bottom_hash 1123 #define bottom_hash
1089 #include "elfgcchack.h" 1124 #include "elfgcchack.h"
OLDNEW
« no previous file with comments | « third_party/libxml/src/globals.c ('k') | third_party/libxml/src/include/Makefile.am » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698