pocxxeci 0.30.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pocxxeci might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +122 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,1146 @@
1
+ /*
2
+ * hash.c: chained hash tables
3
+ *
4
+ * Reference: Your favorite introductory book on algorithms
5
+ *
6
+ * Copyright (C) 2000,2012 Bjorn Reese and Daniel Veillard.
7
+ *
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
10
+ * copyright notice and this permission notice appear in all copies.
11
+ *
12
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
13
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
14
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
15
+ * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
16
+ *
17
+ * Author: breese@users.sourceforge.net
18
+ */
19
+
20
+ #define IN_LIBXML
21
+ #include "libxml.h"
22
+
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
+ !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
38
+ #define HASH_RANDOMIZATION
39
+ #endif
40
+
41
+ #include <libxml/parser.h>
42
+ #include <libxml/hash.h>
43
+ #include <libxml/xmlmemory.h>
44
+ #include <libxml/xmlerror.h>
45
+ #include <libxml/globals.h>
46
+
47
+ #define MAX_HASH_LEN 8
48
+
49
+ /* #define DEBUG_GROW */
50
+
51
+ /*
52
+ * A single entry in the hash table
53
+ */
54
+ typedef struct _xmlHashEntry xmlHashEntry;
55
+ typedef xmlHashEntry *xmlHashEntryPtr;
56
+ struct _xmlHashEntry {
57
+ struct _xmlHashEntry *next;
58
+ xmlChar *name;
59
+ xmlChar *name2;
60
+ xmlChar *name3;
61
+ void *payload;
62
+ int valid;
63
+ };
64
+
65
+ /*
66
+ * The entire hash table
67
+ */
68
+ struct _xmlHashTable {
69
+ struct _xmlHashEntry *table;
70
+ int size;
71
+ int nbElems;
72
+ xmlDictPtr dict;
73
+ #ifdef HASH_RANDOMIZATION
74
+ int random_seed;
75
+ #endif
76
+ };
77
+
78
+ /*
79
+ * xmlHashComputeKey:
80
+ * Calculate the hash key
81
+ */
82
+ #ifdef __clang__
83
+ ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
84
+ #endif
85
+ static unsigned long
86
+ xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *name,
87
+ const xmlChar *name2, const xmlChar *name3) {
88
+ unsigned long value = 0L;
89
+ char ch;
90
+
91
+ #ifdef HASH_RANDOMIZATION
92
+ value = table->random_seed;
93
+ #endif
94
+ if (name != NULL) {
95
+ value += 30 * (*name);
96
+ while ((ch = *name++) != 0) {
97
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
98
+ }
99
+ }
100
+ value = value ^ ((value << 5) + (value >> 3));
101
+ if (name2 != NULL) {
102
+ while ((ch = *name2++) != 0) {
103
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
104
+ }
105
+ }
106
+ value = value ^ ((value << 5) + (value >> 3));
107
+ if (name3 != NULL) {
108
+ while ((ch = *name3++) != 0) {
109
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
110
+ }
111
+ }
112
+ return (value % table->size);
113
+ }
114
+
115
+ #ifdef __clang__
116
+ ATTRIBUTE_NO_SANITIZE("unsigned-integer-overflow")
117
+ #endif
118
+ static unsigned long
119
+ xmlHashComputeQKey(xmlHashTablePtr table,
120
+ const xmlChar *prefix, const xmlChar *name,
121
+ const xmlChar *prefix2, const xmlChar *name2,
122
+ const xmlChar *prefix3, const xmlChar *name3) {
123
+ unsigned long value = 0L;
124
+ char ch;
125
+
126
+ #ifdef HASH_RANDOMIZATION
127
+ value = table->random_seed;
128
+ #endif
129
+ if (prefix != NULL)
130
+ value += 30 * (*prefix);
131
+ else
132
+ value += 30 * (*name);
133
+
134
+ if (prefix != NULL) {
135
+ while ((ch = *prefix++) != 0) {
136
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
137
+ }
138
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
139
+ }
140
+ if (name != NULL) {
141
+ while ((ch = *name++) != 0) {
142
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
143
+ }
144
+ }
145
+ value = value ^ ((value << 5) + (value >> 3));
146
+ if (prefix2 != NULL) {
147
+ while ((ch = *prefix2++) != 0) {
148
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
149
+ }
150
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
151
+ }
152
+ if (name2 != NULL) {
153
+ while ((ch = *name2++) != 0) {
154
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
155
+ }
156
+ }
157
+ value = value ^ ((value << 5) + (value >> 3));
158
+ if (prefix3 != NULL) {
159
+ while ((ch = *prefix3++) != 0) {
160
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
161
+ }
162
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)':');
163
+ }
164
+ if (name3 != NULL) {
165
+ while ((ch = *name3++) != 0) {
166
+ value = value ^ ((value << 5) + (value >> 3) + (unsigned long)ch);
167
+ }
168
+ }
169
+ return (value % table->size);
170
+ }
171
+
172
+ /**
173
+ * xmlHashCreate:
174
+ * @size: the size of the hash table
175
+ *
176
+ * Create a new xmlHashTablePtr.
177
+ *
178
+ * Returns the newly created object, or NULL if an error occurred.
179
+ */
180
+ xmlHashTablePtr
181
+ xmlHashCreate(int size) {
182
+ xmlHashTablePtr table;
183
+
184
+ if (size <= 0)
185
+ size = 256;
186
+
187
+ table = xmlMalloc(sizeof(xmlHashTable));
188
+ if (table) {
189
+ table->dict = NULL;
190
+ table->size = size;
191
+ table->nbElems = 0;
192
+ table->table = xmlMalloc(size * sizeof(xmlHashEntry));
193
+ if (table->table) {
194
+ memset(table->table, 0, size * sizeof(xmlHashEntry));
195
+ #ifdef HASH_RANDOMIZATION
196
+ table->random_seed = __xmlRandom();
197
+ #endif
198
+ return(table);
199
+ }
200
+ xmlFree(table);
201
+ }
202
+ return(NULL);
203
+ }
204
+
205
+ /**
206
+ * xmlHashCreateDict:
207
+ * @size: the size of the hash table
208
+ * @dict: a dictionary to use for the hash
209
+ *
210
+ * Create a new xmlHashTablePtr which will use @dict as the internal dictionary
211
+ *
212
+ * Returns the newly created object, or NULL if an error occurred.
213
+ */
214
+ xmlHashTablePtr
215
+ xmlHashCreateDict(int size, xmlDictPtr dict) {
216
+ xmlHashTablePtr table;
217
+
218
+ table = xmlHashCreate(size);
219
+ if (table != NULL) {
220
+ table->dict = dict;
221
+ xmlDictReference(dict);
222
+ }
223
+ return(table);
224
+ }
225
+
226
+ /**
227
+ * xmlHashGrow:
228
+ * @table: the hash table
229
+ * @size: the new size of the hash table
230
+ *
231
+ * resize the hash table
232
+ *
233
+ * Returns 0 in case of success, -1 in case of failure
234
+ */
235
+ static int
236
+ xmlHashGrow(xmlHashTablePtr table, int size) {
237
+ unsigned long key;
238
+ int oldsize, i;
239
+ xmlHashEntryPtr iter, next;
240
+ struct _xmlHashEntry *oldtable;
241
+ #ifdef DEBUG_GROW
242
+ unsigned long nbElem = 0;
243
+ #endif
244
+
245
+ if (table == NULL)
246
+ return(-1);
247
+ if (size < 8)
248
+ return(-1);
249
+ if (size > 8 * 2048)
250
+ return(-1);
251
+
252
+ oldsize = table->size;
253
+ oldtable = table->table;
254
+ if (oldtable == NULL)
255
+ return(-1);
256
+
257
+ table->table = xmlMalloc(size * sizeof(xmlHashEntry));
258
+ if (table->table == NULL) {
259
+ table->table = oldtable;
260
+ return(-1);
261
+ }
262
+ memset(table->table, 0, size * sizeof(xmlHashEntry));
263
+ table->size = size;
264
+
265
+ /* If the two loops are merged, there would be situations where
266
+ a new entry needs to allocated and data copied into it from
267
+ the main table. So instead, we run through the array twice, first
268
+ copying all the elements in the main array (where we can't get
269
+ conflicts) and then the rest, so we only free (and don't allocate)
270
+ */
271
+ for (i = 0; i < oldsize; i++) {
272
+ if (oldtable[i].valid == 0)
273
+ continue;
274
+ key = xmlHashComputeKey(table, oldtable[i].name, oldtable[i].name2,
275
+ oldtable[i].name3);
276
+ memcpy(&(table->table[key]), &(oldtable[i]), sizeof(xmlHashEntry));
277
+ table->table[key].next = NULL;
278
+ }
279
+
280
+ for (i = 0; i < oldsize; i++) {
281
+ iter = oldtable[i].next;
282
+ while (iter) {
283
+ next = iter->next;
284
+
285
+ /*
286
+ * put back the entry in the new table
287
+ */
288
+
289
+ key = xmlHashComputeKey(table, iter->name, iter->name2,
290
+ iter->name3);
291
+ if (table->table[key].valid == 0) {
292
+ memcpy(&(table->table[key]), iter, sizeof(xmlHashEntry));
293
+ table->table[key].next = NULL;
294
+ xmlFree(iter);
295
+ } else {
296
+ iter->next = table->table[key].next;
297
+ table->table[key].next = iter;
298
+ }
299
+
300
+ #ifdef DEBUG_GROW
301
+ nbElem++;
302
+ #endif
303
+
304
+ iter = next;
305
+ }
306
+ }
307
+
308
+ xmlFree(oldtable);
309
+
310
+ #ifdef DEBUG_GROW
311
+ xmlGenericError(xmlGenericErrorContext,
312
+ "xmlHashGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
313
+ #endif
314
+
315
+ return(0);
316
+ }
317
+
318
+ /**
319
+ * xmlHashFree:
320
+ * @table: the hash table
321
+ * @f: the deallocator function for items in the hash
322
+ *
323
+ * Free the hash @table and its contents. The userdata is
324
+ * deallocated with @f if provided.
325
+ */
326
+ void
327
+ xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
328
+ int i;
329
+ xmlHashEntryPtr iter;
330
+ xmlHashEntryPtr next;
331
+ int inside_table = 0;
332
+ int nbElems;
333
+
334
+ if (table == NULL)
335
+ return;
336
+ if (table->table) {
337
+ nbElems = table->nbElems;
338
+ for(i = 0; (i < table->size) && (nbElems > 0); i++) {
339
+ iter = &(table->table[i]);
340
+ if (iter->valid == 0)
341
+ continue;
342
+ inside_table = 1;
343
+ while (iter) {
344
+ next = iter->next;
345
+ if ((f != NULL) && (iter->payload != NULL))
346
+ f(iter->payload, iter->name);
347
+ if (table->dict == NULL) {
348
+ if (iter->name)
349
+ xmlFree(iter->name);
350
+ if (iter->name2)
351
+ xmlFree(iter->name2);
352
+ if (iter->name3)
353
+ xmlFree(iter->name3);
354
+ }
355
+ iter->payload = NULL;
356
+ if (!inside_table)
357
+ xmlFree(iter);
358
+ nbElems--;
359
+ inside_table = 0;
360
+ iter = next;
361
+ }
362
+ }
363
+ xmlFree(table->table);
364
+ }
365
+ if (table->dict)
366
+ xmlDictFree(table->dict);
367
+ xmlFree(table);
368
+ }
369
+
370
+ /**
371
+ * xmlHashDefaultDeallocator:
372
+ * @entry: the hash table entry
373
+ * @name: the entry's name
374
+ *
375
+ * Free a hash table entry with xmlFree.
376
+ */
377
+ void
378
+ xmlHashDefaultDeallocator(void *entry, const xmlChar *name ATTRIBUTE_UNUSED) {
379
+ xmlFree(entry);
380
+ }
381
+
382
+ /**
383
+ * xmlHashAddEntry:
384
+ * @table: the hash table
385
+ * @name: the name of the userdata
386
+ * @userdata: a pointer to the userdata
387
+ *
388
+ * Add the @userdata to the hash @table. This can later be retrieved
389
+ * by using the @name. Duplicate names generate errors.
390
+ *
391
+ * Returns 0 the addition succeeded and -1 in case of error.
392
+ */
393
+ int
394
+ xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
395
+ return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
396
+ }
397
+
398
+ /**
399
+ * xmlHashAddEntry2:
400
+ * @table: the hash table
401
+ * @name: the name of the userdata
402
+ * @name2: a second name of the userdata
403
+ * @userdata: a pointer to the userdata
404
+ *
405
+ * Add the @userdata to the hash @table. This can later be retrieved
406
+ * by using the (@name, @name2) tuple. Duplicate tuples generate errors.
407
+ *
408
+ * Returns 0 the addition succeeded and -1 in case of error.
409
+ */
410
+ int
411
+ xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
412
+ const xmlChar *name2, void *userdata) {
413
+ return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
414
+ }
415
+
416
+ /**
417
+ * xmlHashUpdateEntry:
418
+ * @table: the hash table
419
+ * @name: the name of the userdata
420
+ * @userdata: a pointer to the userdata
421
+ * @f: the deallocator function for replaced item (if any)
422
+ *
423
+ * Add the @userdata to the hash @table. This can later be retrieved
424
+ * by using the @name. Existing entry for this @name will be removed
425
+ * and freed with @f if found.
426
+ *
427
+ * Returns 0 the addition succeeded and -1 in case of error.
428
+ */
429
+ int
430
+ xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
431
+ void *userdata, xmlHashDeallocator f) {
432
+ return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
433
+ }
434
+
435
+ /**
436
+ * xmlHashUpdateEntry2:
437
+ * @table: the hash table
438
+ * @name: the name of the userdata
439
+ * @name2: a second name of the userdata
440
+ * @userdata: a pointer to the userdata
441
+ * @f: the deallocator function for replaced item (if any)
442
+ *
443
+ * Add the @userdata to the hash @table. This can later be retrieved
444
+ * by using the (@name, @name2) tuple. Existing entry for this tuple will
445
+ * be removed and freed with @f if found.
446
+ *
447
+ * Returns 0 the addition succeeded and -1 in case of error.
448
+ */
449
+ int
450
+ xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
451
+ const xmlChar *name2, void *userdata,
452
+ xmlHashDeallocator f) {
453
+ return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
454
+ }
455
+
456
+ /**
457
+ * xmlHashLookup:
458
+ * @table: the hash table
459
+ * @name: the name of the userdata
460
+ *
461
+ * Find the userdata specified by the @name.
462
+ *
463
+ * Returns the pointer to the userdata
464
+ */
465
+ void *
466
+ xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
467
+ return(xmlHashLookup3(table, name, NULL, NULL));
468
+ }
469
+
470
+ /**
471
+ * xmlHashLookup2:
472
+ * @table: the hash table
473
+ * @name: the name of the userdata
474
+ * @name2: a second name of the userdata
475
+ *
476
+ * Find the userdata specified by the (@name, @name2) tuple.
477
+ *
478
+ * Returns the pointer to the userdata
479
+ */
480
+ void *
481
+ xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
482
+ const xmlChar *name2) {
483
+ return(xmlHashLookup3(table, name, name2, NULL));
484
+ }
485
+
486
+ /**
487
+ * xmlHashQLookup:
488
+ * @table: the hash table
489
+ * @prefix: the prefix of the userdata
490
+ * @name: the name of the userdata
491
+ *
492
+ * Find the userdata specified by the QName @prefix:@name/@name.
493
+ *
494
+ * Returns the pointer to the userdata
495
+ */
496
+ void *
497
+ xmlHashQLookup(xmlHashTablePtr table, const xmlChar *prefix,
498
+ const xmlChar *name) {
499
+ return(xmlHashQLookup3(table, prefix, name, NULL, NULL, NULL, NULL));
500
+ }
501
+
502
+ /**
503
+ * xmlHashQLookup2:
504
+ * @table: the hash table
505
+ * @prefix: the prefix of the userdata
506
+ * @name: the name of the userdata
507
+ * @prefix2: the second prefix of the userdata
508
+ * @name2: a second name of the userdata
509
+ *
510
+ * Find the userdata specified by the QNames tuple
511
+ *
512
+ * Returns the pointer to the userdata
513
+ */
514
+ void *
515
+ xmlHashQLookup2(xmlHashTablePtr table, const xmlChar *prefix,
516
+ const xmlChar *name, const xmlChar *prefix2,
517
+ const xmlChar *name2) {
518
+ return(xmlHashQLookup3(table, prefix, name, prefix2, name2, NULL, NULL));
519
+ }
520
+
521
+ /**
522
+ * xmlHashAddEntry3:
523
+ * @table: the hash table
524
+ * @name: the name of the userdata
525
+ * @name2: a second name of the userdata
526
+ * @name3: a third name of the userdata
527
+ * @userdata: a pointer to the userdata
528
+ *
529
+ * Add the @userdata to the hash @table. This can later be retrieved
530
+ * by using the tuple (@name, @name2, @name3). Duplicate entries generate
531
+ * errors.
532
+ *
533
+ * Returns 0 the addition succeeded and -1 in case of error.
534
+ */
535
+ int
536
+ xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
537
+ const xmlChar *name2, const xmlChar *name3,
538
+ void *userdata) {
539
+ unsigned long key, len = 0;
540
+ xmlHashEntryPtr entry;
541
+ xmlHashEntryPtr insert;
542
+
543
+ if ((table == NULL) || (name == NULL))
544
+ return(-1);
545
+
546
+ /*
547
+ * If using a dict internalize if needed
548
+ */
549
+ if (table->dict) {
550
+ if (!xmlDictOwns(table->dict, name)) {
551
+ name = xmlDictLookup(table->dict, name, -1);
552
+ if (name == NULL)
553
+ return(-1);
554
+ }
555
+ if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
556
+ name2 = xmlDictLookup(table->dict, name2, -1);
557
+ if (name2 == NULL)
558
+ return(-1);
559
+ }
560
+ if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
561
+ name3 = xmlDictLookup(table->dict, name3, -1);
562
+ if (name3 == NULL)
563
+ return(-1);
564
+ }
565
+ }
566
+
567
+ /*
568
+ * Check for duplicate and insertion location.
569
+ */
570
+ key = xmlHashComputeKey(table, name, name2, name3);
571
+ if (table->table[key].valid == 0) {
572
+ insert = NULL;
573
+ } else {
574
+ if (table->dict) {
575
+ for (insert = &(table->table[key]); insert->next != NULL;
576
+ insert = insert->next) {
577
+ if ((insert->name == name) &&
578
+ (insert->name2 == name2) &&
579
+ (insert->name3 == name3))
580
+ return(-1);
581
+ len++;
582
+ }
583
+ if ((insert->name == name) &&
584
+ (insert->name2 == name2) &&
585
+ (insert->name3 == name3))
586
+ return(-1);
587
+ } else {
588
+ for (insert = &(table->table[key]); insert->next != NULL;
589
+ insert = insert->next) {
590
+ if ((xmlStrEqual(insert->name, name)) &&
591
+ (xmlStrEqual(insert->name2, name2)) &&
592
+ (xmlStrEqual(insert->name3, name3)))
593
+ return(-1);
594
+ len++;
595
+ }
596
+ if ((xmlStrEqual(insert->name, name)) &&
597
+ (xmlStrEqual(insert->name2, name2)) &&
598
+ (xmlStrEqual(insert->name3, name3)))
599
+ return(-1);
600
+ }
601
+ }
602
+
603
+ if (insert == NULL) {
604
+ entry = &(table->table[key]);
605
+ } else {
606
+ entry = xmlMalloc(sizeof(xmlHashEntry));
607
+ if (entry == NULL)
608
+ return(-1);
609
+ }
610
+
611
+ if (table->dict != NULL) {
612
+ entry->name = (xmlChar *) name;
613
+ entry->name2 = (xmlChar *) name2;
614
+ entry->name3 = (xmlChar *) name3;
615
+ } else {
616
+ entry->name = xmlStrdup(name);
617
+ entry->name2 = xmlStrdup(name2);
618
+ entry->name3 = xmlStrdup(name3);
619
+ }
620
+ entry->payload = userdata;
621
+ entry->next = NULL;
622
+ entry->valid = 1;
623
+
624
+
625
+ if (insert != NULL)
626
+ insert->next = entry;
627
+
628
+ table->nbElems++;
629
+
630
+ if (len > MAX_HASH_LEN)
631
+ xmlHashGrow(table, MAX_HASH_LEN * table->size);
632
+
633
+ return(0);
634
+ }
635
+
636
+ /**
637
+ * xmlHashUpdateEntry3:
638
+ * @table: the hash table
639
+ * @name: the name of the userdata
640
+ * @name2: a second name of the userdata
641
+ * @name3: a third name of the userdata
642
+ * @userdata: a pointer to the userdata
643
+ * @f: the deallocator function for replaced item (if any)
644
+ *
645
+ * Add the @userdata to the hash @table. This can later be retrieved
646
+ * by using the tuple (@name, @name2, @name3). Existing entry for this tuple
647
+ * will be removed and freed with @f if found.
648
+ *
649
+ * Returns 0 the addition succeeded and -1 in case of error.
650
+ */
651
+ int
652
+ xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
653
+ const xmlChar *name2, const xmlChar *name3,
654
+ void *userdata, xmlHashDeallocator f) {
655
+ unsigned long key;
656
+ xmlHashEntryPtr entry;
657
+ xmlHashEntryPtr insert;
658
+
659
+ if ((table == NULL) || name == NULL)
660
+ return(-1);
661
+
662
+ /*
663
+ * If using a dict internalize if needed
664
+ */
665
+ if (table->dict) {
666
+ if (!xmlDictOwns(table->dict, name)) {
667
+ name = xmlDictLookup(table->dict, name, -1);
668
+ if (name == NULL)
669
+ return(-1);
670
+ }
671
+ if ((name2 != NULL) && (!xmlDictOwns(table->dict, name2))) {
672
+ name2 = xmlDictLookup(table->dict, name2, -1);
673
+ if (name2 == NULL)
674
+ return(-1);
675
+ }
676
+ if ((name3 != NULL) && (!xmlDictOwns(table->dict, name3))) {
677
+ name3 = xmlDictLookup(table->dict, name3, -1);
678
+ if (name3 == NULL)
679
+ return(-1);
680
+ }
681
+ }
682
+
683
+ /*
684
+ * Check for duplicate and insertion location.
685
+ */
686
+ key = xmlHashComputeKey(table, name, name2, name3);
687
+ if (table->table[key].valid == 0) {
688
+ insert = NULL;
689
+ } else {
690
+ if (table ->dict) {
691
+ for (insert = &(table->table[key]); insert->next != NULL;
692
+ insert = insert->next) {
693
+ if ((insert->name == name) &&
694
+ (insert->name2 == name2) &&
695
+ (insert->name3 == name3)) {
696
+ if (f)
697
+ f(insert->payload, insert->name);
698
+ insert->payload = userdata;
699
+ return(0);
700
+ }
701
+ }
702
+ if ((insert->name == name) &&
703
+ (insert->name2 == name2) &&
704
+ (insert->name3 == name3)) {
705
+ if (f)
706
+ f(insert->payload, insert->name);
707
+ insert->payload = userdata;
708
+ return(0);
709
+ }
710
+ } else {
711
+ for (insert = &(table->table[key]); insert->next != NULL;
712
+ insert = insert->next) {
713
+ if ((xmlStrEqual(insert->name, name)) &&
714
+ (xmlStrEqual(insert->name2, name2)) &&
715
+ (xmlStrEqual(insert->name3, name3))) {
716
+ if (f)
717
+ f(insert->payload, insert->name);
718
+ insert->payload = userdata;
719
+ return(0);
720
+ }
721
+ }
722
+ if ((xmlStrEqual(insert->name, name)) &&
723
+ (xmlStrEqual(insert->name2, name2)) &&
724
+ (xmlStrEqual(insert->name3, name3))) {
725
+ if (f)
726
+ f(insert->payload, insert->name);
727
+ insert->payload = userdata;
728
+ return(0);
729
+ }
730
+ }
731
+ }
732
+
733
+ if (insert == NULL) {
734
+ entry = &(table->table[key]);
735
+ } else {
736
+ entry = xmlMalloc(sizeof(xmlHashEntry));
737
+ if (entry == NULL)
738
+ return(-1);
739
+ }
740
+
741
+ if (table->dict != NULL) {
742
+ entry->name = (xmlChar *) name;
743
+ entry->name2 = (xmlChar *) name2;
744
+ entry->name3 = (xmlChar *) name3;
745
+ } else {
746
+ entry->name = xmlStrdup(name);
747
+ entry->name2 = xmlStrdup(name2);
748
+ entry->name3 = xmlStrdup(name3);
749
+ }
750
+ entry->payload = userdata;
751
+ entry->next = NULL;
752
+ entry->valid = 1;
753
+ table->nbElems++;
754
+
755
+
756
+ if (insert != NULL) {
757
+ insert->next = entry;
758
+ }
759
+ return(0);
760
+ }
761
+
762
+ /**
763
+ * xmlHashLookup3:
764
+ * @table: the hash table
765
+ * @name: the name of the userdata
766
+ * @name2: a second name of the userdata
767
+ * @name3: a third name of the userdata
768
+ *
769
+ * Find the userdata specified by the (@name, @name2, @name3) tuple.
770
+ *
771
+ * Returns the a pointer to the userdata
772
+ */
773
+ void *
774
+ xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
775
+ const xmlChar *name2, const xmlChar *name3) {
776
+ unsigned long key;
777
+ xmlHashEntryPtr entry;
778
+
779
+ if (table == NULL)
780
+ return(NULL);
781
+ if (name == NULL)
782
+ return(NULL);
783
+ key = xmlHashComputeKey(table, name, name2, name3);
784
+ if (table->table[key].valid == 0)
785
+ return(NULL);
786
+ if (table->dict) {
787
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
788
+ if ((entry->name == name) &&
789
+ (entry->name2 == name2) &&
790
+ (entry->name3 == name3))
791
+ return(entry->payload);
792
+ }
793
+ }
794
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
795
+ if ((xmlStrEqual(entry->name, name)) &&
796
+ (xmlStrEqual(entry->name2, name2)) &&
797
+ (xmlStrEqual(entry->name3, name3)))
798
+ return(entry->payload);
799
+ }
800
+ return(NULL);
801
+ }
802
+
803
+ /**
804
+ * xmlHashQLookup3:
805
+ * @table: the hash table
806
+ * @prefix: the prefix of the userdata
807
+ * @name: the name of the userdata
808
+ * @prefix2: the second prefix of the userdata
809
+ * @name2: a second name of the userdata
810
+ * @prefix3: the third prefix of the userdata
811
+ * @name3: a third name of the userdata
812
+ *
813
+ * Find the userdata specified by the (@name, @name2, @name3) tuple.
814
+ *
815
+ * Returns the a pointer to the userdata
816
+ */
817
+ void *
818
+ xmlHashQLookup3(xmlHashTablePtr table,
819
+ const xmlChar *prefix, const xmlChar *name,
820
+ const xmlChar *prefix2, const xmlChar *name2,
821
+ const xmlChar *prefix3, const xmlChar *name3) {
822
+ unsigned long key;
823
+ xmlHashEntryPtr entry;
824
+
825
+ if (table == NULL)
826
+ return(NULL);
827
+ if (name == NULL)
828
+ return(NULL);
829
+ key = xmlHashComputeQKey(table, prefix, name, prefix2,
830
+ name2, prefix3, name3);
831
+ if (table->table[key].valid == 0)
832
+ return(NULL);
833
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
834
+ if ((xmlStrQEqual(prefix, name, entry->name)) &&
835
+ (xmlStrQEqual(prefix2, name2, entry->name2)) &&
836
+ (xmlStrQEqual(prefix3, name3, entry->name3)))
837
+ return(entry->payload);
838
+ }
839
+ return(NULL);
840
+ }
841
+
842
+ typedef struct {
843
+ xmlHashScanner hashscanner;
844
+ void *data;
845
+ } stubData;
846
+
847
+ static void
848
+ stubHashScannerFull (void *payload, void *data, const xmlChar *name,
849
+ const xmlChar *name2 ATTRIBUTE_UNUSED,
850
+ const xmlChar *name3 ATTRIBUTE_UNUSED) {
851
+ stubData *stubdata = (stubData *) data;
852
+ stubdata->hashscanner (payload, stubdata->data, (xmlChar *) name);
853
+ }
854
+
855
+ /**
856
+ * xmlHashScan:
857
+ * @table: the hash table
858
+ * @f: the scanner function for items in the hash
859
+ * @data: extra data passed to f
860
+ *
861
+ * Scan the hash @table and applied @f to each value.
862
+ */
863
+ void
864
+ xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
865
+ stubData stubdata;
866
+ stubdata.data = data;
867
+ stubdata.hashscanner = f;
868
+ xmlHashScanFull (table, stubHashScannerFull, &stubdata);
869
+ }
870
+
871
+ /**
872
+ * xmlHashScanFull:
873
+ * @table: the hash table
874
+ * @f: the scanner function for items in the hash
875
+ * @data: extra data passed to f
876
+ *
877
+ * Scan the hash @table and applied @f to each value.
878
+ */
879
+ void
880
+ xmlHashScanFull(xmlHashTablePtr table, xmlHashScannerFull f, void *data) {
881
+ int i, nb;
882
+ xmlHashEntryPtr iter;
883
+ xmlHashEntryPtr next;
884
+
885
+ if (table == NULL)
886
+ return;
887
+ if (f == NULL)
888
+ return;
889
+
890
+ if (table->table) {
891
+ for(i = 0; i < table->size; i++) {
892
+ if (table->table[i].valid == 0)
893
+ continue;
894
+ iter = &(table->table[i]);
895
+ while (iter) {
896
+ next = iter->next;
897
+ nb = table->nbElems;
898
+ if ((f != NULL) && (iter->payload != NULL))
899
+ f(iter->payload, data, iter->name,
900
+ iter->name2, iter->name3);
901
+ if (nb != table->nbElems) {
902
+ /* table was modified by the callback, be careful */
903
+ if (iter == &(table->table[i])) {
904
+ if (table->table[i].valid == 0)
905
+ iter = NULL;
906
+ if (table->table[i].next != next)
907
+ iter = &(table->table[i]);
908
+ } else
909
+ iter = next;
910
+ } else
911
+ iter = next;
912
+ }
913
+ }
914
+ }
915
+ }
916
+
917
+ /**
918
+ * xmlHashScan3:
919
+ * @table: the hash table
920
+ * @name: the name of the userdata or NULL
921
+ * @name2: a second name of the userdata or NULL
922
+ * @name3: a third name of the userdata or NULL
923
+ * @f: the scanner function for items in the hash
924
+ * @data: extra data passed to f
925
+ *
926
+ * Scan the hash @table and applied @f to each value matching
927
+ * (@name, @name2, @name3) tuple. If one of the names is null,
928
+ * the comparison is considered to match.
929
+ */
930
+ void
931
+ xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
932
+ const xmlChar *name2, const xmlChar *name3,
933
+ xmlHashScanner f, void *data) {
934
+ stubData stubdata;
935
+ stubdata.data = data;
936
+ stubdata.hashscanner = f;
937
+ xmlHashScanFull3(table, name, name2, name3, stubHashScannerFull,
938
+ &stubdata);
939
+ }
940
+
941
+ /**
942
+ * xmlHashScanFull3:
943
+ * @table: the hash table
944
+ * @name: the name of the userdata or NULL
945
+ * @name2: a second name of the userdata or NULL
946
+ * @name3: a third name of the userdata or NULL
947
+ * @f: the scanner function for items in the hash
948
+ * @data: extra data passed to f
949
+ *
950
+ * Scan the hash @table and applied @f to each value matching
951
+ * (@name, @name2, @name3) tuple. If one of the names is null,
952
+ * the comparison is considered to match.
953
+ */
954
+ void
955
+ xmlHashScanFull3(xmlHashTablePtr table, const xmlChar *name,
956
+ const xmlChar *name2, const xmlChar *name3,
957
+ xmlHashScannerFull f, void *data) {
958
+ int i;
959
+ xmlHashEntryPtr iter;
960
+ xmlHashEntryPtr next;
961
+
962
+ if (table == NULL)
963
+ return;
964
+ if (f == NULL)
965
+ return;
966
+
967
+ if (table->table) {
968
+ for(i = 0; i < table->size; i++) {
969
+ if (table->table[i].valid == 0)
970
+ continue;
971
+ iter = &(table->table[i]);
972
+ while (iter) {
973
+ next = iter->next;
974
+ if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
975
+ ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
976
+ ((name3 == NULL) || (xmlStrEqual(name3, iter->name3))) &&
977
+ (iter->payload != NULL)) {
978
+ f(iter->payload, data, iter->name,
979
+ iter->name2, iter->name3);
980
+ }
981
+ iter = next;
982
+ }
983
+ }
984
+ }
985
+ }
986
+
987
+ /**
988
+ * xmlHashCopy:
989
+ * @table: the hash table
990
+ * @f: the copier function for items in the hash
991
+ *
992
+ * Scan the hash @table and applied @f to each value.
993
+ *
994
+ * Returns the new table or NULL in case of error.
995
+ */
996
+ xmlHashTablePtr
997
+ xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
998
+ int i;
999
+ xmlHashEntryPtr iter;
1000
+ xmlHashEntryPtr next;
1001
+ xmlHashTablePtr ret;
1002
+
1003
+ if (table == NULL)
1004
+ return(NULL);
1005
+ if (f == NULL)
1006
+ return(NULL);
1007
+
1008
+ ret = xmlHashCreate(table->size);
1009
+ if (ret == NULL)
1010
+ return(NULL);
1011
+
1012
+ if (table->table) {
1013
+ for(i = 0; i < table->size; i++) {
1014
+ if (table->table[i].valid == 0)
1015
+ continue;
1016
+ iter = &(table->table[i]);
1017
+ while (iter) {
1018
+ next = iter->next;
1019
+ xmlHashAddEntry3(ret, iter->name, iter->name2,
1020
+ iter->name3, f(iter->payload, iter->name));
1021
+ iter = next;
1022
+ }
1023
+ }
1024
+ }
1025
+ ret->nbElems = table->nbElems;
1026
+ return(ret);
1027
+ }
1028
+
1029
+ /**
1030
+ * xmlHashSize:
1031
+ * @table: the hash table
1032
+ *
1033
+ * Query the number of elements installed in the hash @table.
1034
+ *
1035
+ * Returns the number of elements in the hash table or
1036
+ * -1 in case of error
1037
+ */
1038
+ int
1039
+ xmlHashSize(xmlHashTablePtr table) {
1040
+ if (table == NULL)
1041
+ return(-1);
1042
+ return(table->nbElems);
1043
+ }
1044
+
1045
+ /**
1046
+ * xmlHashRemoveEntry:
1047
+ * @table: the hash table
1048
+ * @name: the name of the userdata
1049
+ * @f: the deallocator function for removed item (if any)
1050
+ *
1051
+ * Find the userdata specified by the @name and remove
1052
+ * it from the hash @table. Existing userdata for this tuple will be removed
1053
+ * and freed with @f.
1054
+ *
1055
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
1056
+ */
1057
+ int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
1058
+ xmlHashDeallocator f) {
1059
+ return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
1060
+ }
1061
+
1062
+ /**
1063
+ * xmlHashRemoveEntry2:
1064
+ * @table: the hash table
1065
+ * @name: the name of the userdata
1066
+ * @name2: a second name of the userdata
1067
+ * @f: the deallocator function for removed item (if any)
1068
+ *
1069
+ * Find the userdata specified by the (@name, @name2) tuple and remove
1070
+ * it from the hash @table. Existing userdata for this tuple will be removed
1071
+ * and freed with @f.
1072
+ *
1073
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
1074
+ */
1075
+ int
1076
+ xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
1077
+ const xmlChar *name2, xmlHashDeallocator f) {
1078
+ return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
1079
+ }
1080
+
1081
+ /**
1082
+ * xmlHashRemoveEntry3:
1083
+ * @table: the hash table
1084
+ * @name: the name of the userdata
1085
+ * @name2: a second name of the userdata
1086
+ * @name3: a third name of the userdata
1087
+ * @f: the deallocator function for removed item (if any)
1088
+ *
1089
+ * Find the userdata specified by the (@name, @name2, @name3) tuple and remove
1090
+ * it from the hash @table. Existing userdata for this tuple will be removed
1091
+ * and freed with @f.
1092
+ *
1093
+ * Returns 0 if the removal succeeded and -1 in case of error or not found.
1094
+ */
1095
+ int
1096
+ xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
1097
+ const xmlChar *name2, const xmlChar *name3, xmlHashDeallocator f) {
1098
+ unsigned long key;
1099
+ xmlHashEntryPtr entry;
1100
+ xmlHashEntryPtr prev = NULL;
1101
+
1102
+ if (table == NULL || name == NULL)
1103
+ return(-1);
1104
+
1105
+ key = xmlHashComputeKey(table, name, name2, name3);
1106
+ if (table->table[key].valid == 0) {
1107
+ return(-1);
1108
+ } else {
1109
+ for (entry = &(table->table[key]); entry != NULL; entry = entry->next) {
1110
+ if (xmlStrEqual(entry->name, name) &&
1111
+ xmlStrEqual(entry->name2, name2) &&
1112
+ xmlStrEqual(entry->name3, name3)) {
1113
+ if ((f != NULL) && (entry->payload != NULL))
1114
+ f(entry->payload, entry->name);
1115
+ entry->payload = NULL;
1116
+ if (table->dict == NULL) {
1117
+ if(entry->name)
1118
+ xmlFree(entry->name);
1119
+ if(entry->name2)
1120
+ xmlFree(entry->name2);
1121
+ if(entry->name3)
1122
+ xmlFree(entry->name3);
1123
+ }
1124
+ if(prev) {
1125
+ prev->next = entry->next;
1126
+ xmlFree(entry);
1127
+ } else {
1128
+ if (entry->next == NULL) {
1129
+ entry->valid = 0;
1130
+ } else {
1131
+ entry = entry->next;
1132
+ memcpy(&(table->table[key]), entry, sizeof(xmlHashEntry));
1133
+ xmlFree(entry);
1134
+ }
1135
+ }
1136
+ table->nbElems--;
1137
+ return(0);
1138
+ }
1139
+ prev = entry;
1140
+ }
1141
+ return(-1);
1142
+ }
1143
+ }
1144
+
1145
+ #define bottom_hash
1146
+ #include "elfgcchack.h"