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

Side by Side Diff: third_party/libxml/dict.c

Issue 2951008: Update libxml to 2.7.7. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Created 10 years, 5 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
OLDNEW
1 /* 1 /*
2 * dict.c: dictionary of reusable strings, just used to avoid allocation 2 * dict.c: dictionary of reusable strings, just used to avoid allocation
3 * and freeing operations. 3 * and freeing operations.
4 * 4 *
5 * Copyright (C) 2003 Daniel Veillard. 5 * Copyright (C) 2003 Daniel Veillard.
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND 13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER. 14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 * 15 *
16 * Author: daniel@veillard.com 16 * Author: daniel@veillard.com
17 */ 17 */
18 18
19 #define IN_LIBXML 19 #define IN_LIBXML
20 #include "libxml.h" 20 #include "libxml.h"
21 21
22 #include <string.h> 22 #include <string.h>
23 #ifdef HAVE_STDINT_H
24 #include <stdint.h>
25 #else
26 #ifdef HAVE_INTTYPES_H
27 #include <inttypes.h>
28 #elif defined(WIN32)
29 typedef unsigned __int32 uint32_t;
30 #endif
31 #endif
23 #include <libxml/tree.h> 32 #include <libxml/tree.h>
24 #include <libxml/dict.h> 33 #include <libxml/dict.h>
25 #include <libxml/xmlmemory.h> 34 #include <libxml/xmlmemory.h>
26 #include <libxml/xmlerror.h> 35 #include <libxml/xmlerror.h>
27 #include <libxml/globals.h> 36 #include <libxml/globals.h>
28 37
29 #define MAX_HASH_LEN 4 38 /* #define DEBUG_GROW */
39 /* #define DICT_DEBUG_PATTERNS */
40
41 #define MAX_HASH_LEN 3
30 #define MIN_DICT_SIZE 128 42 #define MIN_DICT_SIZE 128
31 #define MAX_DICT_HASH 8 * 2048 43 #define MAX_DICT_HASH 8 * 2048
44 #define WITH_BIG_KEY
32 45
33 /* #define ALLOW_REMOVAL */ 46 #ifdef WITH_BIG_KEY
34 /* #define DEBUG_GROW */ 47 #define xmlDictComputeKey(dict, name, len)» » » \
48 (((dict)->size == MIN_DICT_SIZE) ?» » » » \
49 xmlDictComputeFastKey(name, len) :»» » » \
50 xmlDictComputeBigKey(name, len))
51
52 #define xmlDictComputeQKey(dict, prefix, plen, name, len)» \
53 (((prefix) == NULL) ?» » » » » \
54 (xmlDictComputeKey(dict, name, len)) :» » » \
55 (((dict)->size == MIN_DICT_SIZE) ?» » » \
56 xmlDictComputeFastQKey(prefix, plen, name, len) :» \
57 xmlDictComputeBigQKey(prefix, plen, name, len)))
58
59 #else /* !WITH_BIG_KEY */
60 #define xmlDictComputeKey(dict, name, len)» » » \
61 xmlDictComputeFastKey(name, len)
62 #define xmlDictComputeQKey(dict, prefix, plen, name, len)» \
63 xmlDictComputeFastQKey(prefix, plen, name, len)
64 #endif /* WITH_BIG_KEY */
35 65
36 /* 66 /*
37 * An entry in the dictionnary 67 * An entry in the dictionnary
38 */ 68 */
39 typedef struct _xmlDictEntry xmlDictEntry; 69 typedef struct _xmlDictEntry xmlDictEntry;
40 typedef xmlDictEntry *xmlDictEntryPtr; 70 typedef xmlDictEntry *xmlDictEntryPtr;
41 struct _xmlDictEntry { 71 struct _xmlDictEntry {
42 struct _xmlDictEntry *next; 72 struct _xmlDictEntry *next;
43 const xmlChar *name; 73 const xmlChar *name;
44 int len; 74 int len;
45 int valid; 75 int valid;
76 unsigned long okey;
46 }; 77 };
47 78
48 typedef struct _xmlDictStrings xmlDictStrings; 79 typedef struct _xmlDictStrings xmlDictStrings;
49 typedef xmlDictStrings *xmlDictStringsPtr; 80 typedef xmlDictStrings *xmlDictStringsPtr;
50 struct _xmlDictStrings { 81 struct _xmlDictStrings {
51 xmlDictStringsPtr next; 82 xmlDictStringsPtr next;
52 xmlChar *free; 83 xmlChar *free;
53 xmlChar *end; 84 xmlChar *end;
54 int size; 85 int size;
55 int nbStrings; 86 int nbStrings;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 * Add the string to the array[s] 153 * Add the string to the array[s]
123 * 154 *
124 * Returns the pointer of the local string, or NULL in case of error. 155 * Returns the pointer of the local string, or NULL in case of error.
125 */ 156 */
126 static const xmlChar * 157 static const xmlChar *
127 xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) { 158 xmlDictAddString(xmlDictPtr dict, const xmlChar *name, int namelen) {
128 xmlDictStringsPtr pool; 159 xmlDictStringsPtr pool;
129 const xmlChar *ret; 160 const xmlChar *ret;
130 int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ 161 int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
131 162
163 #ifdef DICT_DEBUG_PATTERNS
164 fprintf(stderr, "-");
165 #endif
132 pool = dict->strings; 166 pool = dict->strings;
133 while (pool != NULL) { 167 while (pool != NULL) {
134 if (pool->end - pool->free > namelen) 168 if (pool->end - pool->free > namelen)
135 goto found_pool; 169 goto found_pool;
136 if (pool->size > size) size = pool->size; 170 if (pool->size > size) size = pool->size;
137 pool = pool->next; 171 pool = pool->next;
138 } 172 }
139 /* 173 /*
140 * Not found, need to allocate 174 * Not found, need to allocate
141 */ 175 */
142 if (pool == NULL) { 176 if (pool == NULL) {
143 if (size == 0) size = 1000; 177 if (size == 0) size = 1000;
144 else size *= 4; /* exponential growth */ 178 else size *= 4; /* exponential growth */
145 if (size < 4 * namelen) 179 if (size < 4 * namelen)
146 size = 4 * namelen; /* just in case ! */ 180 size = 4 * namelen; /* just in case ! */
147 pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); 181 pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
148 if (pool == NULL) 182 if (pool == NULL)
149 return(NULL); 183 return(NULL);
150 pool->size = size; 184 pool->size = size;
151 pool->nbStrings = 0; 185 pool->nbStrings = 0;
152 pool->free = &pool->array[0]; 186 pool->free = &pool->array[0];
153 pool->end = &pool->array[size]; 187 pool->end = &pool->array[size];
154 pool->next = dict->strings; 188 pool->next = dict->strings;
155 dict->strings = pool; 189 dict->strings = pool;
190 #ifdef DICT_DEBUG_PATTERNS
191 fprintf(stderr, "+");
192 #endif
156 } 193 }
157 found_pool: 194 found_pool:
158 ret = pool->free; 195 ret = pool->free;
159 memcpy(pool->free, name, namelen); 196 memcpy(pool->free, name, namelen);
160 pool->free += namelen; 197 pool->free += namelen;
161 *(pool->free++) = 0; 198 *(pool->free++) = 0;
199 pool->nbStrings++;
162 return(ret); 200 return(ret);
163 } 201 }
164 202
165 /* 203 /*
166 * xmlDictAddQString: 204 * xmlDictAddQString:
167 * @dict: the dictionnary 205 * @dict: the dictionnary
168 * @prefix: the prefix of the userdata 206 * @prefix: the prefix of the userdata
207 * @plen: the prefix length
169 * @name: the name of the userdata 208 * @name: the name of the userdata
170 * @len: the length of the name, if -1 it is recomputed 209 * @len: the length of the name, if -1 it is recomputed
171 * 210 *
172 * Add the QName to the array[s] 211 * Add the QName to the array[s]
173 * 212 *
174 * Returns the pointer of the local string, or NULL in case of error. 213 * Returns the pointer of the local string, or NULL in case of error.
175 */ 214 */
176 static const xmlChar * 215 static const xmlChar *
177 xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, 216 xmlDictAddQString(xmlDictPtr dict, const xmlChar *prefix, int plen,
178 const xmlChar *name, int namelen) 217 const xmlChar *name, int namelen)
179 { 218 {
180 xmlDictStringsPtr pool; 219 xmlDictStringsPtr pool;
181 const xmlChar *ret; 220 const xmlChar *ret;
182 int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */ 221 int size = 0; /* + sizeof(_xmlDictStrings) == 1024 */
183 int plen;
184 222
185 if (prefix == NULL) return(xmlDictAddString(dict, name, namelen)); 223 if (prefix == NULL) return(xmlDictAddString(dict, name, namelen));
186 plen = xmlStrlen(prefix);
187 224
225 #ifdef DICT_DEBUG_PATTERNS
226 fprintf(stderr, "=");
227 #endif
188 pool = dict->strings; 228 pool = dict->strings;
189 while (pool != NULL) { 229 while (pool != NULL) {
190 » if (pool->end - pool->free > namelen) 230 » if (pool->end - pool->free > namelen + plen + 1)
191 goto found_pool; 231 goto found_pool;
192 if (pool->size > size) size = pool->size; 232 if (pool->size > size) size = pool->size;
193 pool = pool->next; 233 pool = pool->next;
194 } 234 }
195 /* 235 /*
196 * Not found, need to allocate 236 * Not found, need to allocate
197 */ 237 */
198 if (pool == NULL) { 238 if (pool == NULL) {
199 if (size == 0) size = 1000; 239 if (size == 0) size = 1000;
200 else size *= 4; /* exponential growth */ 240 else size *= 4; /* exponential growth */
201 if (size < 4 * namelen) 241 if (size < 4 * (namelen + plen + 1))
202 » size = 4 * namelen; /* just in case ! */ 242 » size = 4 * (namelen + plen + 1); /* just in case ! */
203 pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size); 243 pool = (xmlDictStringsPtr) xmlMalloc(sizeof(xmlDictStrings) + size);
204 if (pool == NULL) 244 if (pool == NULL)
205 return(NULL); 245 return(NULL);
206 pool->size = size; 246 pool->size = size;
207 pool->nbStrings = 0; 247 pool->nbStrings = 0;
208 pool->free = &pool->array[0]; 248 pool->free = &pool->array[0];
209 pool->end = &pool->array[size]; 249 pool->end = &pool->array[size];
210 pool->next = dict->strings; 250 pool->next = dict->strings;
211 dict->strings = pool; 251 dict->strings = pool;
252 #ifdef DICT_DEBUG_PATTERNS
253 fprintf(stderr, "+");
254 #endif
212 } 255 }
213 found_pool: 256 found_pool:
214 ret = pool->free; 257 ret = pool->free;
215 memcpy(pool->free, prefix, plen); 258 memcpy(pool->free, prefix, plen);
216 pool->free += plen; 259 pool->free += plen;
217 *(pool->free++) = ':'; 260 *(pool->free++) = ':';
218 namelen -= plen + 1;
219 memcpy(pool->free, name, namelen); 261 memcpy(pool->free, name, namelen);
220 pool->free += namelen; 262 pool->free += namelen;
221 *(pool->free++) = 0; 263 *(pool->free++) = 0;
264 pool->nbStrings++;
222 return(ret); 265 return(ret);
223 } 266 }
224 267
268 #ifdef WITH_BIG_KEY
225 /* 269 /*
226 * xmlDictComputeKey: 270 * xmlDictComputeBigKey:
227 * Calculate the hash key 271 *
272 * Calculate a hash key using a good hash function that works well for
273 * larger hash table sizes.
274 *
275 * Hash function by "One-at-a-Time Hash" see
276 * http://burtleburtle.net/bob/hash/doobs.html
277 */
278
279 static uint32_t
280 xmlDictComputeBigKey(const xmlChar* data, int namelen) {
281 uint32_t hash;
282 int i;
283
284 if (namelen <= 0 || data == NULL) return(0);
285
286 hash = 0;
287
288 for (i = 0;i < namelen; i++) {
289 hash += data[i];
290 » hash += (hash << 10);
291 » hash ^= (hash >> 6);
292 }
293 hash += (hash << 3);
294 hash ^= (hash >> 11);
295 hash += (hash << 15);
296
297 return hash;
298 }
299
300 /*
301 * xmlDictComputeBigQKey:
302 *
303 * Calculate a hash key for two strings using a good hash function
304 * that works well for larger hash table sizes.
305 *
306 * Hash function by "One-at-a-Time Hash" see
307 * http://burtleburtle.net/bob/hash/doobs.html
308 *
309 * Neither of the two strings must be NULL.
228 */ 310 */
229 static unsigned long 311 static unsigned long
230 xmlDictComputeKey(const xmlChar *name, int namelen) { 312 xmlDictComputeBigQKey(const xmlChar *prefix, int plen,
313 const xmlChar *name, int len)
314 {
315 uint32_t hash;
316 int i;
317
318 hash = 0;
319
320 for (i = 0;i < plen; i++) {
321 hash += prefix[i];
322 » hash += (hash << 10);
323 » hash ^= (hash >> 6);
324 }
325 hash += ':';
326 hash += (hash << 10);
327 hash ^= (hash >> 6);
328
329 for (i = 0;i < len; i++) {
330 hash += name[i];
331 » hash += (hash << 10);
332 » hash ^= (hash >> 6);
333 }
334 hash += (hash << 3);
335 hash ^= (hash >> 11);
336 hash += (hash << 15);
337
338 return hash;
339 }
340 #endif /* WITH_BIG_KEY */
341
342 /*
343 * xmlDictComputeFastKey:
344 *
345 * Calculate a hash key using a fast hash function that works well
346 * for low hash table fill.
347 */
348 static unsigned long
349 xmlDictComputeFastKey(const xmlChar *name, int namelen) {
231 unsigned long value = 0L; 350 unsigned long value = 0L;
232 351
233 if (name == NULL) return(0); 352 if (name == NULL) return(0);
234 value = *name; 353 value = *name;
235 value <<= 5; 354 value <<= 5;
236 if (namelen > 10) { 355 if (namelen > 10) {
237 value += name[namelen - 1]; 356 value += name[namelen - 1];
238 namelen = 10; 357 namelen = 10;
239 } 358 }
240 switch (namelen) { 359 switch (namelen) {
241 case 10: value += name[9]; 360 case 10: value += name[9];
242 case 9: value += name[8]; 361 case 9: value += name[8];
243 case 8: value += name[7]; 362 case 8: value += name[7];
244 case 7: value += name[6]; 363 case 7: value += name[6];
245 case 6: value += name[5]; 364 case 6: value += name[5];
246 case 5: value += name[4]; 365 case 5: value += name[4];
247 case 4: value += name[3]; 366 case 4: value += name[3];
248 case 3: value += name[2]; 367 case 3: value += name[2];
249 case 2: value += name[1]; 368 case 2: value += name[1];
250 default: break; 369 default: break;
251 } 370 }
252 return(value); 371 return(value);
253 } 372 }
254 373
255 /* 374 /*
256 * xmlDictComputeQKey: 375 * xmlDictComputeFastQKey:
257 * Calculate the hash key 376 *
377 * Calculate a hash key for two strings using a fast hash function
378 * that works well for low hash table fill.
379 *
380 * Neither of the two strings must be NULL.
258 */ 381 */
259 static unsigned long 382 static unsigned long
260 xmlDictComputeQKey(const xmlChar *prefix, const xmlChar *name, int len) 383 xmlDictComputeFastQKey(const xmlChar *prefix, int plen,
384 const xmlChar *name, int len)
261 { 385 {
262 unsigned long value = 0L; 386 unsigned long value = 0L;
263 int plen;
264
265 if (prefix == NULL)
266 return(xmlDictComputeKey(name, len));
267 387
268 plen = xmlStrlen(prefix);
269 if (plen == 0) 388 if (plen == 0)
270 value += 30 * (unsigned long) ':'; 389 value += 30 * (unsigned long) ':';
271 else 390 else
272 value += 30 * (*prefix); 391 value += 30 * (*prefix);
273 392
274 if (len > 10) { 393 if (len > 10) {
275 value += name[len - (plen + 1 + 1)]; 394 value += name[len - (plen + 1 + 1)];
276 len = 10; 395 len = 10;
277 if (plen > 10) 396 if (plen > 10)
278 plen = 10; 397 plen = 10;
279 } 398 }
280 switch (plen) { 399 switch (plen) {
281 case 10: value += prefix[9]; 400 case 10: value += prefix[9];
282 case 9: value += prefix[8]; 401 case 9: value += prefix[8];
283 case 8: value += prefix[7]; 402 case 8: value += prefix[7];
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 * 437 *
319 * Returns the newly created dictionnary, or NULL if an error occured. 438 * Returns the newly created dictionnary, or NULL if an error occured.
320 */ 439 */
321 xmlDictPtr 440 xmlDictPtr
322 xmlDictCreate(void) { 441 xmlDictCreate(void) {
323 xmlDictPtr dict; 442 xmlDictPtr dict;
324 443
325 if (!xmlDictInitialized) 444 if (!xmlDictInitialized)
326 if (!xmlInitializeDict()) 445 if (!xmlInitializeDict())
327 return(NULL); 446 return(NULL);
328 447
448 #ifdef DICT_DEBUG_PATTERNS
449 fprintf(stderr, "C");
450 #endif
451
329 dict = xmlMalloc(sizeof(xmlDict)); 452 dict = xmlMalloc(sizeof(xmlDict));
330 if (dict) { 453 if (dict) {
331 dict->ref_counter = 1; 454 dict->ref_counter = 1;
332 455
333 dict->size = MIN_DICT_SIZE; 456 dict->size = MIN_DICT_SIZE;
334 dict->nbElems = 0; 457 dict->nbElems = 0;
335 dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry)); 458 dict->dict = xmlMalloc(MIN_DICT_SIZE * sizeof(xmlDictEntry));
336 dict->strings = NULL; 459 dict->strings = NULL;
337 dict->subdict = NULL; 460 dict->subdict = NULL;
338 if (dict->dict) { 461 if (dict->dict) {
(...skipping 12 matching lines...) Expand all
351 * Create a new dictionary, inheriting strings from the read-only 474 * Create a new dictionary, inheriting strings from the read-only
352 * dictionnary @sub. On lookup, strings are first searched in the 475 * dictionnary @sub. On lookup, strings are first searched in the
353 * new dictionnary, then in @sub, and if not found are created in the 476 * new dictionnary, then in @sub, and if not found are created in the
354 * new dictionnary. 477 * new dictionnary.
355 * 478 *
356 * Returns the newly created dictionnary, or NULL if an error occured. 479 * Returns the newly created dictionnary, or NULL if an error occured.
357 */ 480 */
358 xmlDictPtr 481 xmlDictPtr
359 xmlDictCreateSub(xmlDictPtr sub) { 482 xmlDictCreateSub(xmlDictPtr sub) {
360 xmlDictPtr dict = xmlDictCreate(); 483 xmlDictPtr dict = xmlDictCreate();
361 484
362 if ((dict != NULL) && (sub != NULL)) { 485 if ((dict != NULL) && (sub != NULL)) {
486 #ifdef DICT_DEBUG_PATTERNS
487 fprintf(stderr, "R");
488 #endif
363 dict->subdict = sub; 489 dict->subdict = sub;
364 xmlDictReference(dict->subdict); 490 xmlDictReference(dict->subdict);
365 } 491 }
366 return(dict); 492 return(dict);
367 } 493 }
368 494
369 /** 495 /**
370 * xmlDictReference: 496 * xmlDictReference:
371 * @dict: the dictionnary 497 * @dict: the dictionnary
372 * 498 *
(...skipping 18 matching lines...) Expand all
391 * xmlDictGrow: 517 * xmlDictGrow:
392 * @dict: the dictionnary 518 * @dict: the dictionnary
393 * @size: the new size of the dictionnary 519 * @size: the new size of the dictionnary
394 * 520 *
395 * resize the dictionnary 521 * resize the dictionnary
396 * 522 *
397 * Returns 0 in case of success, -1 in case of failure 523 * Returns 0 in case of success, -1 in case of failure
398 */ 524 */
399 static int 525 static int
400 xmlDictGrow(xmlDictPtr dict, int size) { 526 xmlDictGrow(xmlDictPtr dict, int size) {
401 unsigned long key; 527 unsigned long key, okey;
402 int oldsize, i; 528 int oldsize, i;
403 xmlDictEntryPtr iter, next; 529 xmlDictEntryPtr iter, next;
404 struct _xmlDictEntry *olddict; 530 struct _xmlDictEntry *olddict;
405 #ifdef DEBUG_GROW 531 #ifdef DEBUG_GROW
406 unsigned long nbElem = 0; 532 unsigned long nbElem = 0;
407 #endif 533 #endif
408 534 int ret = 0;
535 int keep_keys = 1;
536
409 if (dict == NULL) 537 if (dict == NULL)
410 return(-1); 538 return(-1);
411 if (size < 8) 539 if (size < 8)
412 return(-1); 540 return(-1);
413 if (size > 8 * 2048) 541 if (size > 8 * 2048)
414 return(-1); 542 return(-1);
415 543
544 #ifdef DICT_DEBUG_PATTERNS
545 fprintf(stderr, "*");
546 #endif
547
416 oldsize = dict->size; 548 oldsize = dict->size;
417 olddict = dict->dict; 549 olddict = dict->dict;
418 if (olddict == NULL) 550 if (olddict == NULL)
419 return(-1); 551 return(-1);
420 552 if (oldsize == MIN_DICT_SIZE)
553 keep_keys = 0;
554
421 dict->dict = xmlMalloc(size * sizeof(xmlDictEntry)); 555 dict->dict = xmlMalloc(size * sizeof(xmlDictEntry));
422 if (dict->dict == NULL) { 556 if (dict->dict == NULL) {
423 dict->dict = olddict; 557 dict->dict = olddict;
424 return(-1); 558 return(-1);
425 } 559 }
426 memset(dict->dict, 0, size * sizeof(xmlDictEntry)); 560 memset(dict->dict, 0, size * sizeof(xmlDictEntry));
427 dict->size = size; 561 dict->size = size;
428 562
429 /* If the two loops are merged, there would be situations where 563 /* If the two loops are merged, there would be situations where
430 » a new entry needs to allocated and data copied into it from 564 » a new entry needs to allocated and data copied into it from
431 » the main dict. So instead, we run through the array twice, first 565 » the main dict. It is nicer to run through the array twice, first
432 » copying all the elements in the main array (where we can't get 566 » copying all the elements in the main array (less probability of
433 » conflicts) and then the rest, so we only free (and don't allocate) 567 » allocate) and then the rest, so we only free in the second loop.
434 */ 568 */
435 for (i = 0; i < oldsize; i++) { 569 for (i = 0; i < oldsize; i++) {
436 » if (olddict[i].valid == 0) 570 » if (olddict[i].valid == 0)
437 continue; 571 continue;
438 » key = xmlDictComputeKey(olddict[i].name, olddict[i].len) % dict->size; 572
439 » memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry)); 573 » if (keep_keys)
440 » dict->dict[key].next = NULL; 574 » okey = olddict[i].okey;
575 » else
576 » okey = xmlDictComputeKey(dict, olddict[i].name, olddict[i].len);
577 » key = okey % dict->size;
578
579 » if (dict->dict[key].valid == 0) {
580 » memcpy(&(dict->dict[key]), &(olddict[i]), sizeof(xmlDictEntry));
581 » dict->dict[key].next = NULL;
582 » dict->dict[key].okey = okey;
583 » } else {
584 » xmlDictEntryPtr entry;
585
586 » entry = xmlMalloc(sizeof(xmlDictEntry));
587 » if (entry != NULL) {
588 » » entry->name = olddict[i].name;
589 » » entry->len = olddict[i].len;
590 » » entry->okey = okey;
591 » » entry->next = dict->dict[key].next;
592 » » entry->valid = 1;
593 » » dict->dict[key].next = entry;
594 » } else {
595 » /*
596 » » * we don't have much ways to alert from herei
597 » » * result is loosing an entry and unicity garantee
598 » » */
599 » ret = -1;
600 » }
601 » }
441 #ifdef DEBUG_GROW 602 #ifdef DEBUG_GROW
442 nbElem++; 603 nbElem++;
443 #endif 604 #endif
444 } 605 }
445 606
446 for (i = 0; i < oldsize; i++) { 607 for (i = 0; i < oldsize; i++) {
447 iter = olddict[i].next; 608 iter = olddict[i].next;
448 while (iter) { 609 while (iter) {
449 next = iter->next; 610 next = iter->next;
450 611
451 /* 612 /*
452 * put back the entry in the new dict 613 * put back the entry in the new dict
453 */ 614 */
454 615
455 » key = xmlDictComputeKey(iter->name, iter->len) % dict->size; 616 » if (keep_keys)
617 » » okey = iter->okey;
618 » else
619 » » okey = xmlDictComputeKey(dict, iter->name, iter->len);
620 » key = okey % dict->size;
456 if (dict->dict[key].valid == 0) { 621 if (dict->dict[key].valid == 0) {
457 memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry)); 622 memcpy(&(dict->dict[key]), iter, sizeof(xmlDictEntry));
458 dict->dict[key].next = NULL; 623 dict->dict[key].next = NULL;
459 dict->dict[key].valid = 1; 624 dict->dict[key].valid = 1;
625 dict->dict[key].okey = okey;
460 xmlFree(iter); 626 xmlFree(iter);
461 } else { 627 } else {
462 » » iter->next = dict->dict[key].next; 628 » » iter->next = dict->dict[key].next;
463 » » dict->dict[key].next = iter; 629 » » iter->okey = okey;
630 » » dict->dict[key].next = iter;
464 } 631 }
465 632
466 #ifdef DEBUG_GROW 633 #ifdef DEBUG_GROW
467 nbElem++; 634 nbElem++;
468 #endif 635 #endif
469 636
470 iter = next; 637 iter = next;
471 } 638 }
472 } 639 }
473 640
474 xmlFree(olddict); 641 xmlFree(olddict);
475 642
476 #ifdef DEBUG_GROW 643 #ifdef DEBUG_GROW
477 xmlGenericError(xmlGenericErrorContext, 644 xmlGenericError(xmlGenericErrorContext,
478 "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem); 645 "xmlDictGrow : from %d to %d, %d elems\n", oldsize, size, nbElem);
479 #endif 646 #endif
480 647
481 return(0); 648 return(ret);
482 } 649 }
483 650
484 /** 651 /**
485 * xmlDictFree: 652 * xmlDictFree:
486 * @dict: the dictionnary 653 * @dict: the dictionnary
487 * 654 *
488 * Free the hash @dict and its contents. The userdata is 655 * Free the hash @dict and its contents. The userdata is
489 * deallocated with @f if provided. 656 * deallocated with @f if provided.
490 */ 657 */
491 void 658 void
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 continue; 691 continue;
525 inside_dict = 1; 692 inside_dict = 1;
526 while (iter) { 693 while (iter) {
527 next = iter->next; 694 next = iter->next;
528 if (!inside_dict) 695 if (!inside_dict)
529 xmlFree(iter); 696 xmlFree(iter);
530 dict->nbElems--; 697 dict->nbElems--;
531 inside_dict = 0; 698 inside_dict = 0;
532 iter = next; 699 iter = next;
533 } 700 }
534 inside_dict = 0;
535 } 701 }
536 xmlFree(dict->dict); 702 xmlFree(dict->dict);
537 } 703 }
538 pool = dict->strings; 704 pool = dict->strings;
539 while (pool != NULL) { 705 while (pool != NULL) {
540 nextp = pool->next; 706 nextp = pool->next;
541 xmlFree(pool); 707 xmlFree(pool);
542 pool = nextp; 708 pool = nextp;
543 } 709 }
544 xmlFree(dict); 710 xmlFree(dict);
(...skipping 13 matching lines...) Expand all
558 xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) { 724 xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len) {
559 unsigned long key, okey, nbi = 0; 725 unsigned long key, okey, nbi = 0;
560 xmlDictEntryPtr entry; 726 xmlDictEntryPtr entry;
561 xmlDictEntryPtr insert; 727 xmlDictEntryPtr insert;
562 const xmlChar *ret; 728 const xmlChar *ret;
563 729
564 if ((dict == NULL) || (name == NULL)) 730 if ((dict == NULL) || (name == NULL))
565 return(NULL); 731 return(NULL);
566 732
567 if (len < 0) 733 if (len < 0)
568 len = xmlStrlen(name); 734 len = strlen((const char *) name);
569 735
570 /* 736 /*
571 * Check for duplicate and insertion location. 737 * Check for duplicate and insertion location.
572 */ 738 */
573 okey = xmlDictComputeKey(name, len); 739 okey = xmlDictComputeKey(dict, name, len);
574 key = okey % dict->size; 740 key = okey % dict->size;
575 if (dict->dict[key].valid == 0) { 741 if (dict->dict[key].valid == 0) {
576 insert = NULL; 742 insert = NULL;
577 } else { 743 } else {
578 for (insert = &(dict->dict[key]); insert->next != NULL; 744 for (insert = &(dict->dict[key]); insert->next != NULL;
579 insert = insert->next) { 745 insert = insert->next) {
580 #ifdef __GNUC__ 746 #ifdef __GNUC__
581 » if (insert->len == len) { 747 » if ((insert->okey == okey) && (insert->len == len)) {
582 if (!memcmp(insert->name, name, len)) 748 if (!memcmp(insert->name, name, len))
583 return(insert->name); 749 return(insert->name);
584 } 750 }
585 #else 751 #else
586 » if ((insert->len == len) && 752 » if ((insert->okey == okey) && (insert->len == len) &&
587 (!xmlStrncmp(insert->name, name, len))) 753 (!xmlStrncmp(insert->name, name, len)))
588 return(insert->name); 754 return(insert->name);
589 #endif 755 #endif
590 nbi++; 756 nbi++;
591 } 757 }
592 #ifdef __GNUC__ 758 #ifdef __GNUC__
593 » if (insert->len == len) { 759 » if ((insert->okey == okey) && (insert->len == len)) {
594 if (!memcmp(insert->name, name, len)) 760 if (!memcmp(insert->name, name, len))
595 return(insert->name); 761 return(insert->name);
596 } 762 }
597 #else 763 #else
598 » if ((insert->len == len) && 764 » if ((insert->okey == okey) && (insert->len == len) &&
599 (!xmlStrncmp(insert->name, name, len))) 765 (!xmlStrncmp(insert->name, name, len)))
600 return(insert->name); 766 return(insert->name);
601 #endif 767 #endif
602 } 768 }
603 769
604 if (dict->subdict) { 770 if (dict->subdict) {
605 » key = okey % dict->subdict->size; 771 unsigned long skey;
772
773 /* we cannot always reuse the same okey for the subdict */
774 if (((dict->size == MIN_DICT_SIZE) &&
775 » (dict->subdict->size != MIN_DICT_SIZE)) ||
776 ((dict->size != MIN_DICT_SIZE) &&
777 » (dict->subdict->size == MIN_DICT_SIZE)))
778 » skey = xmlDictComputeKey(dict->subdict, name, len);
779 » else
780 » skey = okey;
781
782 » key = skey % dict->subdict->size;
606 if (dict->subdict->dict[key].valid != 0) { 783 if (dict->subdict->dict[key].valid != 0) {
607 xmlDictEntryPtr tmp; 784 xmlDictEntryPtr tmp;
608 785
609 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 786 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
610 tmp = tmp->next) { 787 tmp = tmp->next) {
611 #ifdef __GNUC__ 788 #ifdef __GNUC__
612 » » if (tmp->len == len) { 789 » » if ((tmp->okey == skey) && (tmp->len == len)) {
613 if (!memcmp(tmp->name, name, len)) 790 if (!memcmp(tmp->name, name, len))
614 return(tmp->name); 791 return(tmp->name);
615 } 792 }
616 #else 793 #else
617 » » if ((tmp->len == len) && 794 » » if ((tmp->okey == skey) && (tmp->len == len) &&
618 (!xmlStrncmp(tmp->name, name, len))) 795 (!xmlStrncmp(tmp->name, name, len)))
619 return(tmp->name); 796 return(tmp->name);
620 #endif 797 #endif
621 nbi++; 798 nbi++;
622 } 799 }
623 #ifdef __GNUC__ 800 #ifdef __GNUC__
624 » if (tmp->len == len) { 801 » if ((tmp->okey == skey) && (tmp->len == len)) {
625 if (!memcmp(tmp->name, name, len)) 802 if (!memcmp(tmp->name, name, len))
626 return(tmp->name); 803 return(tmp->name);
627 } 804 }
628 #else 805 #else
629 » if ((tmp->len == len) && 806 » if ((tmp->okey == skey) && (tmp->len == len) &&
630 (!xmlStrncmp(tmp->name, name, len))) 807 (!xmlStrncmp(tmp->name, name, len)))
631 return(tmp->name); 808 return(tmp->name);
632 #endif 809 #endif
633 } 810 }
634 key = okey % dict->size; 811 key = okey % dict->size;
635 } 812 }
636 813
637 ret = xmlDictAddString(dict, name, len); 814 ret = xmlDictAddString(dict, name, len);
638 if (ret == NULL) 815 if (ret == NULL)
639 return(NULL); 816 return(NULL);
640 if (insert == NULL) { 817 if (insert == NULL) {
641 entry = &(dict->dict[key]); 818 entry = &(dict->dict[key]);
642 } else { 819 } else {
643 entry = xmlMalloc(sizeof(xmlDictEntry)); 820 entry = xmlMalloc(sizeof(xmlDictEntry));
644 if (entry == NULL) 821 if (entry == NULL)
645 return(NULL); 822 return(NULL);
646 } 823 }
647 entry->name = ret; 824 entry->name = ret;
648 entry->len = len; 825 entry->len = len;
649 entry->next = NULL; 826 entry->next = NULL;
650 entry->valid = 1; 827 entry->valid = 1;
828 entry->okey = okey;
651 829
652 830
653 if (insert != NULL) 831 if (insert != NULL)
654 insert->next = entry; 832 insert->next = entry;
655 833
656 dict->nbElems++; 834 dict->nbElems++;
657 835
658 if ((nbi > MAX_HASH_LEN) && 836 if ((nbi > MAX_HASH_LEN) &&
659 (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) 837 (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) {
660 » xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size); 838 » if (xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size) != 0)
839 » return(NULL);
840 }
661 /* Note that entry may have been freed at this point by xmlDictGrow */ 841 /* Note that entry may have been freed at this point by xmlDictGrow */
662 842
663 return(ret); 843 return(ret);
664 } 844 }
665 845
666 /** 846 /**
667 * xmlDictExists: 847 * xmlDictExists:
668 * @dict: the dictionnary 848 * @dict: the dictionnary
669 * @name: the name of the userdata 849 * @name: the name of the userdata
670 * @len: the length of the name, if -1 it is recomputed 850 * @len: the length of the name, if -1 it is recomputed
671 * 851 *
672 * Check if the @name exists in the dictionnary @dict. 852 * Check if the @name exists in the dictionnary @dict.
673 * 853 *
674 * Returns the internal copy of the name or NULL if not found. 854 * Returns the internal copy of the name or NULL if not found.
675 */ 855 */
676 const xmlChar * 856 const xmlChar *
677 xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) { 857 xmlDictExists(xmlDictPtr dict, const xmlChar *name, int len) {
678 unsigned long key, okey, nbi = 0; 858 unsigned long key, okey, nbi = 0;
679 xmlDictEntryPtr insert; 859 xmlDictEntryPtr insert;
680 860
681 if ((dict == NULL) || (name == NULL)) 861 if ((dict == NULL) || (name == NULL))
682 return(NULL); 862 return(NULL);
683 863
684 if (len < 0) 864 if (len < 0)
685 len = xmlStrlen(name); 865 len = strlen((const char *) name);
686 866
687 /* 867 /*
688 * Check for duplicate and insertion location. 868 * Check for duplicate and insertion location.
689 */ 869 */
690 okey = xmlDictComputeKey(name, len); 870 okey = xmlDictComputeKey(dict, name, len);
691 key = okey % dict->size; 871 key = okey % dict->size;
692 if (dict->dict[key].valid == 0) { 872 if (dict->dict[key].valid == 0) {
693 insert = NULL; 873 insert = NULL;
694 } else { 874 } else {
695 for (insert = &(dict->dict[key]); insert->next != NULL; 875 for (insert = &(dict->dict[key]); insert->next != NULL;
696 insert = insert->next) { 876 insert = insert->next) {
697 #ifdef __GNUC__ 877 #ifdef __GNUC__
698 » if (insert->len == len) { 878 » if ((insert->okey == okey) && (insert->len == len)) {
699 if (!memcmp(insert->name, name, len)) 879 if (!memcmp(insert->name, name, len))
700 return(insert->name); 880 return(insert->name);
701 } 881 }
702 #else 882 #else
703 » if ((insert->len == len) && 883 » if ((insert->okey == okey) && (insert->len == len) &&
704 (!xmlStrncmp(insert->name, name, len))) 884 (!xmlStrncmp(insert->name, name, len)))
705 return(insert->name); 885 return(insert->name);
706 #endif 886 #endif
707 nbi++; 887 nbi++;
708 } 888 }
709 #ifdef __GNUC__ 889 #ifdef __GNUC__
710 » if (insert->len == len) { 890 » if ((insert->okey == okey) && (insert->len == len)) {
711 if (!memcmp(insert->name, name, len)) 891 if (!memcmp(insert->name, name, len))
712 return(insert->name); 892 return(insert->name);
713 } 893 }
714 #else 894 #else
715 » if ((insert->len == len) && 895 » if ((insert->okey == okey) && (insert->len == len) &&
716 (!xmlStrncmp(insert->name, name, len))) 896 (!xmlStrncmp(insert->name, name, len)))
717 return(insert->name); 897 return(insert->name);
718 #endif 898 #endif
719 } 899 }
720 900
721 if (dict->subdict) { 901 if (dict->subdict) {
722 » key = okey % dict->subdict->size; 902 unsigned long skey;
903
904 /* we cannot always reuse the same okey for the subdict */
905 if (((dict->size == MIN_DICT_SIZE) &&
906 » (dict->subdict->size != MIN_DICT_SIZE)) ||
907 ((dict->size != MIN_DICT_SIZE) &&
908 » (dict->subdict->size == MIN_DICT_SIZE)))
909 » skey = xmlDictComputeKey(dict->subdict, name, len);
910 » else
911 » skey = okey;
912
913 » key = skey % dict->subdict->size;
723 if (dict->subdict->dict[key].valid != 0) { 914 if (dict->subdict->dict[key].valid != 0) {
724 xmlDictEntryPtr tmp; 915 xmlDictEntryPtr tmp;
725 916
726 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 917 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
727 tmp = tmp->next) { 918 tmp = tmp->next) {
728 #ifdef __GNUC__ 919 #ifdef __GNUC__
729 » » if (tmp->len == len) { 920 » » if ((tmp->okey == skey) && (tmp->len == len)) {
730 if (!memcmp(tmp->name, name, len)) 921 if (!memcmp(tmp->name, name, len))
731 return(tmp->name); 922 return(tmp->name);
732 } 923 }
733 #else 924 #else
734 » » if ((tmp->len == len) && 925 » » if ((tmp->okey == skey) && (tmp->len == len) &&
735 (!xmlStrncmp(tmp->name, name, len))) 926 (!xmlStrncmp(tmp->name, name, len)))
736 return(tmp->name); 927 return(tmp->name);
737 #endif 928 #endif
738 nbi++; 929 nbi++;
739 } 930 }
740 #ifdef __GNUC__ 931 #ifdef __GNUC__
741 » if (tmp->len == len) { 932 » if ((tmp->okey == skey) && (tmp->len == len)) {
742 if (!memcmp(tmp->name, name, len)) 933 if (!memcmp(tmp->name, name, len))
743 return(tmp->name); 934 return(tmp->name);
744 } 935 }
745 #else 936 #else
746 » if ((tmp->len == len) && 937 » if ((tmp->okey == skey) && (tmp->len == len) &&
747 (!xmlStrncmp(tmp->name, name, len))) 938 (!xmlStrncmp(tmp->name, name, len)))
748 return(tmp->name); 939 return(tmp->name);
749 #endif 940 #endif
750 } 941 }
751 key = okey % dict->size;
752 } 942 }
753 943
754 /* not found */ 944 /* not found */
755 return(NULL); 945 return(NULL);
756 } 946 }
757 947
758 /** 948 /**
759 * xmlDictQLookup: 949 * xmlDictQLookup:
760 * @dict: the dictionnary 950 * @dict: the dictionnary
761 * @prefix: the prefix 951 * @prefix: the prefix
762 * @name: the name 952 * @name: the name
763 * 953 *
764 * Add the QName @prefix:@name to the hash @dict if not present. 954 * Add the QName @prefix:@name to the hash @dict if not present.
765 * 955 *
766 * Returns the internal copy of the QName or NULL in case of internal error 956 * Returns the internal copy of the QName or NULL in case of internal error
767 */ 957 */
768 const xmlChar * 958 const xmlChar *
769 xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) { 959 xmlDictQLookup(xmlDictPtr dict, const xmlChar *prefix, const xmlChar *name) {
770 unsigned long okey, key, nbi = 0; 960 unsigned long okey, key, nbi = 0;
771 xmlDictEntryPtr entry; 961 xmlDictEntryPtr entry;
772 xmlDictEntryPtr insert; 962 xmlDictEntryPtr insert;
773 const xmlChar *ret; 963 const xmlChar *ret;
774 int len; 964 int len, plen, l;
775 965
776 if ((dict == NULL) || (name == NULL)) 966 if ((dict == NULL) || (name == NULL))
777 return(NULL); 967 return(NULL);
968 if (prefix == NULL)
969 return(xmlDictLookup(dict, name, -1));
778 970
779 len = xmlStrlen(name); 971 l = len = strlen((const char *) name);
780 if (prefix != NULL) 972 plen = strlen((const char *) prefix);
781 len += 1 + xmlStrlen(prefix); 973 len += 1 + plen;
782 974
783 /* 975 /*
784 * Check for duplicate and insertion location. 976 * Check for duplicate and insertion location.
785 */ 977 */
786 okey = xmlDictComputeQKey(prefix, name, len); 978 okey = xmlDictComputeQKey(dict, prefix, plen, name, l);
787 key = okey % dict->size; 979 key = okey % dict->size;
788 if (dict->dict[key].valid == 0) { 980 if (dict->dict[key].valid == 0) {
789 insert = NULL; 981 insert = NULL;
790 } else { 982 } else {
791 for (insert = &(dict->dict[key]); insert->next != NULL; 983 for (insert = &(dict->dict[key]); insert->next != NULL;
792 insert = insert->next) { 984 insert = insert->next) {
793 » if ((insert->len == len) && 985 » if ((insert->okey == okey) && (insert->len == len) &&
794 (xmlStrQEqual(prefix, name, insert->name))) 986 (xmlStrQEqual(prefix, name, insert->name)))
795 return(insert->name); 987 return(insert->name);
796 nbi++; 988 nbi++;
797 } 989 }
798 » if ((insert->len == len) && 990 » if ((insert->okey == okey) && (insert->len == len) &&
799 (xmlStrQEqual(prefix, name, insert->name))) 991 (xmlStrQEqual(prefix, name, insert->name)))
800 return(insert->name); 992 return(insert->name);
801 } 993 }
802 994
803 if (dict->subdict) { 995 if (dict->subdict) {
804 » key = okey % dict->subdict->size; 996 unsigned long skey;
997
998 /* we cannot always reuse the same okey for the subdict */
999 if (((dict->size == MIN_DICT_SIZE) &&
1000 » (dict->subdict->size != MIN_DICT_SIZE)) ||
1001 ((dict->size != MIN_DICT_SIZE) &&
1002 » (dict->subdict->size == MIN_DICT_SIZE)))
1003 » skey = xmlDictComputeQKey(dict->subdict, prefix, plen, name, l);
1004 » else
1005 » skey = okey;
1006
1007 » key = skey % dict->subdict->size;
805 if (dict->subdict->dict[key].valid != 0) { 1008 if (dict->subdict->dict[key].valid != 0) {
806 xmlDictEntryPtr tmp; 1009 xmlDictEntryPtr tmp;
807 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL; 1010 for (tmp = &(dict->subdict->dict[key]); tmp->next != NULL;
808 tmp = tmp->next) { 1011 tmp = tmp->next) {
809 » » if ((tmp->len == len) && 1012 » » if ((tmp->okey == skey) && (tmp->len == len) &&
810 (xmlStrQEqual(prefix, name, tmp->name))) 1013 (xmlStrQEqual(prefix, name, tmp->name)))
811 return(tmp->name); 1014 return(tmp->name);
812 nbi++; 1015 nbi++;
813 } 1016 }
814 » if ((tmp->len == len) && 1017 » if ((tmp->okey == skey) && (tmp->len == len) &&
815 (xmlStrQEqual(prefix, name, tmp->name))) 1018 (xmlStrQEqual(prefix, name, tmp->name)))
816 return(tmp->name); 1019 return(tmp->name);
817 } 1020 }
818 key = okey % dict->size; 1021 key = okey % dict->size;
819 } 1022 }
820 1023
821 ret = xmlDictAddQString(dict, prefix, name, len); 1024 ret = xmlDictAddQString(dict, prefix, plen, name, l);
822 if (ret == NULL) 1025 if (ret == NULL)
823 return(NULL); 1026 return(NULL);
824 if (insert == NULL) { 1027 if (insert == NULL) {
825 entry = &(dict->dict[key]); 1028 entry = &(dict->dict[key]);
826 } else { 1029 } else {
827 entry = xmlMalloc(sizeof(xmlDictEntry)); 1030 entry = xmlMalloc(sizeof(xmlDictEntry));
828 if (entry == NULL) 1031 if (entry == NULL)
829 return(NULL); 1032 return(NULL);
830 } 1033 }
831 entry->name = ret; 1034 entry->name = ret;
832 entry->len = len; 1035 entry->len = len;
833 entry->next = NULL; 1036 entry->next = NULL;
834 entry->valid = 1; 1037 entry->valid = 1;
1038 entry->okey = okey;
835 1039
836 if (insert != NULL) 1040 if (insert != NULL)
837 insert->next = entry; 1041 insert->next = entry;
838 1042
839 dict->nbElems++; 1043 dict->nbElems++;
840 1044
841 if ((nbi > MAX_HASH_LEN) && 1045 if ((nbi > MAX_HASH_LEN) &&
842 (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN))) 1046 (dict->size <= ((MAX_DICT_HASH / 2) / MAX_HASH_LEN)))
843 xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size); 1047 xmlDictGrow(dict, MAX_HASH_LEN * 2 * dict->size);
844 /* Note that entry may have been freed at this point by xmlDictGrow */ 1048 /* Note that entry may have been freed at this point by xmlDictGrow */
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
887 if (dict == NULL) 1091 if (dict == NULL)
888 return(-1); 1092 return(-1);
889 if (dict->subdict) 1093 if (dict->subdict)
890 return(dict->nbElems + dict->subdict->nbElems); 1094 return(dict->nbElems + dict->subdict->nbElems);
891 return(dict->nbElems); 1095 return(dict->nbElems);
892 } 1096 }
893 1097
894 1098
895 #define bottom_dict 1099 #define bottom_dict
896 #include "elfgcchack.h" 1100 #include "elfgcchack.h"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698