Annotation of XML/entities.c, revision 1.30
1.1 httpng 1: /*
2: * entities.c : implementation for the XML entities handking
1.9 veillard 3: *
4: * See Copyright for the status of this software.
5: *
1.23 daniel 6: * Daniel.Veillard@w3.org
1.1 httpng 7: */
8:
9: #include <stdio.h>
1.17 daniel 10: #include <stdlib.h>
1.10 daniel 11: #include <string.h>
1.1 httpng 12: #include "entities.h"
13:
14: /*
1.15 daniel 15: * The XML predefined entities.
16: */
17:
18: struct xmlPredefinedEntityValue {
19: const char *name;
20: const char *value;
21: };
22: struct xmlPredefinedEntityValue xmlPredefinedEntityValues[] = {
23: { "lt", "<" },
24: { "gt", ">" },
25: { "apos", "'" },
26: { "quot", "\"" },
27: { "amp", "&" }
28: };
29:
30: xmlEntitiesTablePtr xmlPredefinedEntities = NULL;
31:
32: /*
1.2 httpng 33: * xmlFreeEntity : clean-up an entity record.
1.1 httpng 34: */
1.2 httpng 35: void xmlFreeEntity(xmlEntityPtr entity) {
36: if (entity == NULL) return;
37:
1.11 daniel 38: if (entity->name != NULL)
39: free((char *) entity->name);
1.14 daniel 40: if (entity->ExternalID != NULL)
41: free((char *) entity->ExternalID);
42: if (entity->SystemID != NULL)
43: free((char *) entity->SystemID);
44: if (entity->content != NULL)
45: free((char *) entity->content);
1.27 daniel 46: if (entity->orig != NULL)
47: free((char *) entity->orig);
1.14 daniel 48: memset(entity, -1, sizeof(xmlEntity));
1.2 httpng 49: }
1.1 httpng 50:
51: /*
1.22 daniel 52: * xmlAddEntity : register a new entity for an entities table.
1.13 daniel 53: *
54: * TODO !!! We should check here that the combination of type
55: * ExternalID and SystemID is valid.
1.1 httpng 56: */
1.22 daniel 57: static void
58: xmlAddEntity(xmlEntitiesTablePtr table, const CHAR *name, int type,
1.13 daniel 59: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 60: int i;
61: xmlEntityPtr cur;
1.14 daniel 62: int len;
1.1 httpng 63:
1.2 httpng 64: for (i = 0;i < table->nb_entities;i++) {
65: cur = &table->table[i];
1.11 daniel 66: if (!xmlStrcmp(cur->name, name)) {
1.13 daniel 67: /*
68: * The entity is already defined in this Dtd, the spec says to NOT
69: * override it ... Is it worth a Warning ??? !!!
70: */
1.30 ! daniel 71: if (((type == XML_INTERNAL_PARAMETER_ENTITY) ||
! 72: (type == XML_EXTERNAL_PARAMETER_ENTITY)) &&
! 73: ((cur->type == XML_INTERNAL_PARAMETER_ENTITY) ||
! 74: (cur->type == XML_EXTERNAL_PARAMETER_ENTITY)))
! 75: return;
! 76: else
! 77: if (((type != XML_INTERNAL_PARAMETER_ENTITY) &&
! 78: (type != XML_EXTERNAL_PARAMETER_ENTITY)) &&
! 79: ((cur->type != XML_INTERNAL_PARAMETER_ENTITY) &&
! 80: (cur->type != XML_EXTERNAL_PARAMETER_ENTITY)))
! 81: return;
1.7 veillard 82: }
1.2 httpng 83: }
84: if (table->nb_entities >= table->max_entities) {
85: /*
86: * need more elements.
87: */
88: table->max_entities *= 2;
89: table->table = (xmlEntityPtr)
90: realloc(table->table, table->max_entities * sizeof(xmlEntity));
1.29 daniel 91: if (table->table == NULL) {
1.2 httpng 92: perror("realloc failed");
1.29 daniel 93: return;
1.2 httpng 94: }
95: }
96: cur = &table->table[table->nb_entities];
1.11 daniel 97: cur->name = xmlStrdup(name);
1.14 daniel 98: for (len = 0;name[0] != 0;name++)len++;
99: cur->len = len;
1.13 daniel 100: cur->type = type;
101: if (ExternalID != NULL)
102: cur->ExternalID = xmlStrdup(ExternalID);
1.14 daniel 103: else
104: cur->ExternalID = NULL;
1.13 daniel 105: if (SystemID != NULL)
1.14 daniel 106: cur->SystemID = xmlStrdup(SystemID);
107: else
108: cur->SystemID = NULL;
1.13 daniel 109: if (content != NULL)
110: cur->content = xmlStrdup(content);
1.14 daniel 111: else
112: cur->content = NULL;
1.27 daniel 113: cur->orig = NULL;
1.2 httpng 114: table->nb_entities++;
115: }
1.1 httpng 116:
1.22 daniel 117: /**
118: * xmlInitializePredefinedEntities:
119: *
120: * Set up the predefined entities.
1.15 daniel 121: */
122: void xmlInitializePredefinedEntities(void) {
123: int i;
124: CHAR name[50];
125: CHAR value[50];
126: const char *in;
127: CHAR *out;
128:
129: if (xmlPredefinedEntities != NULL) return;
130:
131: xmlPredefinedEntities = xmlCreateEntitiesTable();
132: for (i = 0;i < sizeof(xmlPredefinedEntityValues) /
133: sizeof(xmlPredefinedEntityValues[0]);i++) {
134: in = xmlPredefinedEntityValues[i].name;
135: out = &name[0];
136: for (;(*out++ = (CHAR) *in);)in++;
137: in = xmlPredefinedEntityValues[i].value;
138: out = &value[0];
139: for (;(*out++ = (CHAR) *in);)in++;
140: xmlAddEntity(xmlPredefinedEntities, (const CHAR *) &name[0],
1.18 daniel 141: XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL,
1.15 daniel 142: &value[0]);
143: }
144: }
1.17 daniel 145:
146: /**
147: * xmlGetPredefinedEntity:
148: * @name: the entity name
149: *
150: * Check whether this name is an predefined entity.
151: *
1.24 daniel 152: * Returns NULL if not, othervise the entity
1.17 daniel 153: */
154: xmlEntityPtr
155: xmlGetPredefinedEntity(const CHAR *name) {
156: int i;
157: xmlEntityPtr cur;
158:
159: if (xmlPredefinedEntities == NULL)
160: xmlInitializePredefinedEntities();
161: for (i = 0;i < xmlPredefinedEntities->nb_entities;i++) {
162: cur = &xmlPredefinedEntities->table[i];
163: if (!xmlStrcmp(cur->name, name)) return(cur);
164: }
165: return(NULL);
166: }
167:
1.22 daniel 168: /**
169: * xmlAddDtdEntity:
170: * @doc: the document
171: * @name: the entity name
172: * @type: the entity type XML_xxx_yyy_ENTITY
173: * @ExternalID: the entity external ID if available
174: * @SystemID: the entity system ID if available
175: * @content: the entity content
176: *
177: * Register a new entity for this document DTD.
1.1 httpng 178: */
1.22 daniel 179: void
180: xmlAddDtdEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 181: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.2 httpng 182: xmlEntitiesTablePtr table;
1.1 httpng 183:
1.22 daniel 184: if (doc->extSubset == NULL) {
185: fprintf(stderr,
186: "xmlAddDtdEntity: document without external subset !\n");
1.16 daniel 187: return;
188: }
1.22 daniel 189: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.2 httpng 190: if (table == NULL) {
191: table = xmlCreateEntitiesTable();
1.22 daniel 192: doc->extSubset->entities = table;
1.1 httpng 193: }
1.13 daniel 194: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 195: }
196:
1.22 daniel 197: /**
198: * xmlAddDocEntity:
199: * @doc: the document
200: * @name: the entity name
201: * @type: the entity type XML_xxx_yyy_ENTITY
202: * @ExternalID: the entity external ID if available
203: * @SystemID: the entity system ID if available
204: * @content: the entity content
205: *
206: * Register a new entity for this document.
1.1 httpng 207: */
1.22 daniel 208: void
209: xmlAddDocEntity(xmlDocPtr doc, const CHAR *name, int type,
1.13 daniel 210: const CHAR *ExternalID, const CHAR *SystemID, CHAR *content) {
1.16 daniel 211: xmlEntitiesTablePtr table;
212:
1.22 daniel 213: if (doc == NULL) {
214: fprintf(stderr,
215: "xmlAddDocEntity: document is NULL !\n");
216: return;
217: }
218: if (doc->intSubset == NULL) {
219: fprintf(stderr,
220: "xmlAddDtdEntity: document without internal subset !\n");
221: return;
222: }
223: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 224: if (table == NULL) {
225: table = xmlCreateEntitiesTable();
1.22 daniel 226: doc->intSubset->entities = table;
1.2 httpng 227: }
1.22 daniel 228: xmlAddEntity(table, name, type, ExternalID, SystemID, content);
1.1 httpng 229: }
230:
1.22 daniel 231: /**
1.30 ! daniel 232: * xmlGetParameterEntity:
! 233: * @doc: the document referencing the entity
! 234: * @name: the entity name
! 235: *
! 236: * Do an entity lookup in the internal and external subsets and
! 237: * returns the corresponding parameter entity, if found.
! 238: *
! 239: * Returns A pointer to the entity structure or NULL if not found.
! 240: */
! 241: xmlEntityPtr
! 242: xmlGetParameterEntity(xmlDocPtr doc, const CHAR *name) {
! 243: int i;
! 244: xmlEntityPtr cur;
! 245: xmlEntitiesTablePtr table;
! 246:
! 247: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
! 248: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
! 249: for (i = 0;i < table->nb_entities;i++) {
! 250: cur = &table->table[i];
! 251: if (((cur->type == XML_INTERNAL_PARAMETER_ENTITY) ||
! 252: (cur->type == XML_EXTERNAL_PARAMETER_ENTITY)) &&
! 253: (!xmlStrcmp(cur->name, name))) return(cur);
! 254: }
! 255: }
! 256: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
! 257: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
! 258: for (i = 0;i < table->nb_entities;i++) {
! 259: cur = &table->table[i];
! 260: if (((cur->type == XML_INTERNAL_PARAMETER_ENTITY) ||
! 261: (cur->type == XML_EXTERNAL_PARAMETER_ENTITY)) &&
! 262: (!xmlStrcmp(cur->name, name))) return(cur);
! 263: }
! 264: }
! 265: return(NULL);
! 266: }
! 267:
! 268: /**
1.22 daniel 269: * xmlGetDtdEntity:
270: * @doc: the document referencing the entity
271: * @name: the entity name
272: *
273: * Do an entity lookup in the Dtd entity hash table and
274: * returns the corresponding entity, if found.
275: *
1.24 daniel 276: * Returns A pointer to the entity structure or NULL if not found.
1.1 httpng 277: */
1.22 daniel 278: xmlEntityPtr
279: xmlGetDtdEntity(xmlDocPtr doc, const CHAR *name) {
1.2 httpng 280: int i;
281: xmlEntityPtr cur;
282: xmlEntitiesTablePtr table;
283:
1.22 daniel 284: if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) {
285: table = (xmlEntitiesTablePtr) doc->extSubset->entities;
1.15 daniel 286: for (i = 0;i < table->nb_entities;i++) {
287: cur = &table->table[i];
1.30 ! daniel 288: if ((cur->type != XML_INTERNAL_PARAMETER_ENTITY) &&
! 289: (cur->type != XML_EXTERNAL_PARAMETER_ENTITY) &&
! 290: (!xmlStrcmp(cur->name, name))) return(cur);
1.15 daniel 291: }
292: }
1.7 veillard 293: return(NULL);
1.3 httpng 294: }
295:
1.22 daniel 296: /**
297: * xmlGetDocEntity:
298: * @doc: the document referencing the entity
299: * @name: the entity name
300: *
301: * Do an entity lookup in the document entity hash table and
302: * returns the corrsponding entity, otherwise a lookup is done
303: * in the predefined entities too.
304: *
1.24 daniel 305: * Returns A pointer to the entity structure or NULL if not found.
1.14 daniel 306: */
1.22 daniel 307: xmlEntityPtr
308: xmlGetDocEntity(xmlDocPtr doc, const CHAR *name) {
1.14 daniel 309: int i;
1.16 daniel 310: xmlEntityPtr cur;
1.14 daniel 311: xmlEntitiesTablePtr table;
312:
1.22 daniel 313: if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) {
314: table = (xmlEntitiesTablePtr) doc->intSubset->entities;
1.16 daniel 315: for (i = 0;i < table->nb_entities;i++) {
316: cur = &table->table[i];
1.30 ! daniel 317: if ((cur->type != XML_INTERNAL_PARAMETER_ENTITY) &&
! 318: (cur->type != XML_EXTERNAL_PARAMETER_ENTITY) &&
! 319: (!xmlStrcmp(cur->name, name))) return(cur);
1.16 daniel 320: }
321: }
1.15 daniel 322: if (xmlPredefinedEntities == NULL)
323: xmlInitializePredefinedEntities();
1.16 daniel 324: table = xmlPredefinedEntities;
325: for (i = 0;i < table->nb_entities;i++) {
326: cur = &table->table[i];
1.30 ! daniel 327: if ((cur->type != XML_INTERNAL_PARAMETER_ENTITY) &&
! 328: (cur->type != XML_EXTERNAL_PARAMETER_ENTITY) &&
! 329: (!xmlStrcmp(cur->name, name))) return(cur);
1.14 daniel 330: }
331:
332: return(NULL);
1.1 httpng 333: }
334:
335: /*
1.21 daniel 336: * [2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD]
337: * | [#x10000-#x10FFFF]
338: * any Unicode character, excluding the surrogate blocks, FFFE, and FFFF.
339: */
340: #define IS_CHAR(c) \
341: (((c) == 0x09) || ((c) == 0x0a) || ((c) == 0x0d) || \
342: (((c) >= 0x20) && ((c) != 0xFFFE) && ((c) != 0xFFFF)))
343:
1.28 daniel 344: /*
345: * A buffer used for converting entities to their equivalent and back.
346: *
347: * TODO: remove this, this helps performances but forbid reentrancy in a
348: * stupid way.
349: */
350: static int buffer_size = 0;
351: static CHAR *buffer = NULL;
352:
353: void growBuffer(void) {
354: buffer_size *= 2;
355: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
356: if (buffer == NULL) {
357: perror("realloc failed");
358: exit(1);
359: }
360: }
361:
362:
1.22 daniel 363: /**
364: * xmlEncodeEntities:
365: * @doc: the document containing the string
366: * @input: A string to convert to XML.
367: *
368: * Do a global encoding of a string, replacing the predefined entities
369: * and non ASCII values with their entities and CharRef counterparts.
370: *
1.19 daniel 371: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
372: * get erroneous.
1.22 daniel 373: *
1.28 daniel 374: * TODO This routine is not reentrant, the interface
375: * should not be modified though.
376: *
377: * People must migrate their code to xmlEncodeEntitiesReentrant !
378: *
379: * Returns A newly allocated string with the substitution done.
380: */
381: const CHAR *
382: xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
383: const CHAR *cur = input;
384: CHAR *out = buffer;
385:
386: if (input == NULL) return(NULL);
387: if (buffer == NULL) {
388: buffer_size = 1000;
389: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
390: if (buffer == NULL) {
391: perror("malloc failed");
392: exit(1);
393: }
394: out = buffer;
395: }
396: while (*cur != '\0') {
397: if (out - buffer > buffer_size - 100) {
398: int index = out - buffer;
399:
400: growBuffer();
401: out = &buffer[index];
402: }
403:
404: /*
405: * By default one have to encode at least '<', '>', '"' and '&' !
406: */
407: if (*cur == '<') {
408: *out++ = '&';
409: *out++ = 'l';
410: *out++ = 't';
411: *out++ = ';';
412: } else if (*cur == '>') {
413: *out++ = '&';
414: *out++ = 'g';
415: *out++ = 't';
416: *out++ = ';';
417: } else if (*cur == '&') {
418: *out++ = '&';
419: *out++ = 'a';
420: *out++ = 'm';
421: *out++ = 'p';
422: *out++ = ';';
423: } else if (*cur == '"') {
424: *out++ = '&';
425: *out++ = 'q';
426: *out++ = 'u';
427: *out++ = 'o';
428: *out++ = 't';
429: *out++ = ';';
430: } else if (*cur == '\'') {
431: *out++ = '&';
432: *out++ = 'a';
433: *out++ = 'p';
434: *out++ = 'o';
435: *out++ = 's';
436: *out++ = ';';
437: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
438: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
439: /*
440: * default case, just copy !
441: */
442: *out++ = *cur;
443: #ifndef USE_UTF_8
444: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
445: char buf[10], *ptr;
446: #ifdef HAVE_SNPRINTF
447: snprintf(buf, 9, "&#%d;", *cur);
448: #else
449: sprintf(buf, "&#%d;", *cur);
450: #endif
451: ptr = buf;
452: while (*ptr != 0) *out++ = *ptr++;
453: #endif
454: } else if (IS_CHAR(*cur)) {
455: char buf[10], *ptr;
456:
457: #ifdef HAVE_SNPRINTF
458: snprintf(buf, 9, "&#%d;", *cur);
459: #else
460: sprintf(buf, "&#%d;", *cur);
461: #endif
462: ptr = buf;
463: while (*ptr != 0) *out++ = *ptr++;
464: }
465: #if 0
466: else {
467: /*
468: * default case, this is not a valid char !
469: * Skip it...
470: */
471: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
472: }
473: #endif
474: cur++;
475: }
476: *out++ = 0;
477: return(buffer);
478: }
479:
480: /*
481: * Macro used to grow the current buffer.
482: */
483: #define growBufferReentrant() { \
484: buffer_size *= 2; \
485: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); \
486: if (buffer == NULL) { \
487: perror("realloc failed"); \
488: exit(1); \
489: } \
490: }
491:
492:
493: /**
494: * xmlEncodeEntitiesReentrant:
495: * @doc: the document containing the string
496: * @input: A string to convert to XML.
497: *
498: * Do a global encoding of a string, replacing the predefined entities
499: * and non ASCII values with their entities and CharRef counterparts.
500: * Contrary to xmlEncodeEntities, this routine is reentrant, and result
501: * must be deallocated.
502: *
503: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
504: * get erroneous.
505: *
1.24 daniel 506: * Returns A newly allocated string with the substitution done.
1.1 httpng 507: */
1.22 daniel 508: CHAR *
1.28 daniel 509: xmlEncodeEntitiesReentrant(xmlDocPtr doc, const CHAR *input) {
1.7 veillard 510: const CHAR *cur = input;
1.26 daniel 511: CHAR *buffer = NULL;
512: CHAR *out = NULL;
513: int buffer_size = 0;
1.3 httpng 514:
1.19 daniel 515: if (input == NULL) return(NULL);
1.26 daniel 516:
517: /*
518: * allocate an translation buffer.
519: */
520: buffer_size = 1000;
521: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
1.3 httpng 522: if (buffer == NULL) {
1.26 daniel 523: perror("malloc failed");
524: exit(1);
1.3 httpng 525: }
1.26 daniel 526: out = buffer;
527:
1.6 veillard 528: while (*cur != '\0') {
529: if (out - buffer > buffer_size - 100) {
530: int index = out - buffer;
531:
1.28 daniel 532: growBufferReentrant();
1.6 veillard 533: out = &buffer[index];
534: }
535:
536: /*
1.7 veillard 537: * By default one have to encode at least '<', '>', '"' and '&' !
1.6 veillard 538: */
539: if (*cur == '<') {
540: *out++ = '&';
541: *out++ = 'l';
542: *out++ = 't';
543: *out++ = ';';
1.7 veillard 544: } else if (*cur == '>') {
545: *out++ = '&';
546: *out++ = 'g';
547: *out++ = 't';
548: *out++ = ';';
1.6 veillard 549: } else if (*cur == '&') {
550: *out++ = '&';
551: *out++ = 'a';
552: *out++ = 'm';
553: *out++ = 'p';
1.7 veillard 554: *out++ = ';';
555: } else if (*cur == '"') {
556: *out++ = '&';
557: *out++ = 'q';
558: *out++ = 'u';
559: *out++ = 'o';
560: *out++ = 't';
561: *out++ = ';';
562: } else if (*cur == '\'') {
563: *out++ = '&';
564: *out++ = 'a';
565: *out++ = 'p';
566: *out++ = 'o';
567: *out++ = 's';
1.6 veillard 568: *out++ = ';';
1.21 daniel 569: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
570: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
571: /*
572: * default case, just copy !
573: */
574: *out++ = *cur;
1.19 daniel 575: #ifndef USE_UTF_8
576: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
577: char buf[10], *ptr;
578: #ifdef HAVE_SNPRINTF
579: snprintf(buf, 9, "&#%d;", *cur);
580: #else
581: sprintf(buf, "&#%d;", *cur);
582: #endif
583: ptr = buf;
584: while (*ptr != 0) *out++ = *ptr++;
585: #endif
1.21 daniel 586: } else if (IS_CHAR(*cur)) {
1.20 daniel 587: char buf[10], *ptr;
588:
589: #ifdef HAVE_SNPRINTF
590: snprintf(buf, 9, "&#%d;", *cur);
591: #else
592: sprintf(buf, "&#%d;", *cur);
593: #endif
594: ptr = buf;
595: while (*ptr != 0) *out++ = *ptr++;
1.21 daniel 596: }
597: #if 0
598: else {
1.6 veillard 599: /*
1.21 daniel 600: * default case, this is not a valid char !
601: * Skip it...
1.6 veillard 602: */
1.21 daniel 603: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
1.6 veillard 604: }
1.21 daniel 605: #endif
1.6 veillard 606: cur++;
607: }
608: *out++ = 0;
609: return(buffer);
1.2 httpng 610: }
611:
1.22 daniel 612: /**
613: * xmlCreateEntitiesTable:
614: *
615: * create and initialize an empty entities hash table.
616: *
1.24 daniel 617: * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
1.2 httpng 618: */
1.22 daniel 619: xmlEntitiesTablePtr
620: xmlCreateEntitiesTable(void) {
1.2 httpng 621: xmlEntitiesTablePtr ret;
1.1 httpng 622:
1.2 httpng 623: ret = (xmlEntitiesTablePtr)
624: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 625: if (ret == NULL) {
1.28 daniel 626: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
627: (long)sizeof(xmlEntitiesTable));
1.2 httpng 628: return(NULL);
629: }
630: ret->max_entities = XML_MIN_ENTITIES_TABLE;
631: ret->nb_entities = 0;
632: ret->table = (xmlEntityPtr )
633: malloc(ret->max_entities * sizeof(xmlEntity));
634: if (ret == NULL) {
1.28 daniel 635: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
636: ret->max_entities * (long)sizeof(xmlEntity));
1.2 httpng 637: free(ret);
1.1 httpng 638: return(NULL);
639: }
640: return(ret);
641: }
642:
1.22 daniel 643: /**
644: * xmlFreeEntitiesTable:
645: * @table: An entity table
646: *
647: * Deallocate the memory used by an entities hash table.
1.1 httpng 648: */
1.22 daniel 649: void
650: xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 651: int i;
652:
653: if (table == NULL) return;
654:
1.2 httpng 655: for (i = 0;i < table->nb_entities;i++) {
656: xmlFreeEntity(&table->table[i]);
1.1 httpng 657: }
1.2 httpng 658: free(table->table);
1.1 httpng 659: free(table);
660: }
661:
1.22 daniel 662: /**
663: * xmlCopyEntitiesTable:
664: * @table: An entity table
665: *
666: * Build a copy of an entity table.
667: *
1.24 daniel 668: * Returns the new xmlEntitiesTablePtr or NULL in case of error.
1.22 daniel 669: */
670: xmlEntitiesTablePtr
671: xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
672: xmlEntitiesTablePtr ret;
673: xmlEntityPtr cur, ent;
674: int i;
675:
676: ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable));
677: if (ret == NULL) {
678: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
679: return(NULL);
680: }
681: ret->table = (xmlEntityPtr) malloc(table->max_entities *
682: sizeof(xmlEntity));
683: if (ret->table == NULL) {
684: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
685: free(ret);
686: return(NULL);
687: }
688: ret->max_entities = table->max_entities;
689: ret->nb_entities = table->nb_entities;
690: for (i = 0;i < ret->nb_entities;i++) {
691: cur = &ret->table[i];
692: ent = &table->table[i];
693: cur->len = ent->len;
694: cur->type = ent->type;
695: if (ent->name != NULL)
696: cur->name = xmlStrdup(ent->name);
697: else
698: cur->name = NULL;
699: if (ent->ExternalID != NULL)
700: cur->ExternalID = xmlStrdup(ent->ExternalID);
701: else
702: cur->ExternalID = NULL;
703: if (ent->SystemID != NULL)
704: cur->SystemID = xmlStrdup(ent->SystemID);
705: else
706: cur->SystemID = NULL;
707: if (ent->content != NULL)
708: cur->content = xmlStrdup(ent->content);
709: else
710: cur->content = NULL;
1.27 daniel 711: if (ent->orig != NULL)
712: cur->orig = xmlStrdup(ent->orig);
713: else
714: cur->orig = NULL;
1.22 daniel 715: }
716: return(ret);
717: }
718:
719: /**
720: * xmlDumpEntitiesTable:
1.25 daniel 721: * @buf: An XML buffer.
1.22 daniel 722: * @table: An entity table
723: *
724: * This will dump the content of the entity table as an XML DTD definition
1.13 daniel 725: */
1.22 daniel 726: void
1.25 daniel 727: xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1.14 daniel 728: int i;
729: xmlEntityPtr cur;
730:
731: if (table == NULL) return;
732:
733: for (i = 0;i < table->nb_entities;i++) {
734: cur = &table->table[i];
735: switch (cur->type) {
736: case XML_INTERNAL_GENERAL_ENTITY:
1.25 daniel 737: xmlBufferWriteChar(buf, "<!ENTITY ");
738: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 739: xmlBufferWriteChar(buf, " ");
740: if (cur->orig != NULL)
741: xmlBufferWriteQuotedString(buf, cur->orig);
742: else
743: xmlBufferWriteQuotedString(buf, cur->content);
744: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 745: break;
746: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1.25 daniel 747: xmlBufferWriteChar(buf, "<!ENTITY ");
748: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 749: if (cur->ExternalID != NULL) {
1.27 daniel 750: xmlBufferWriteChar(buf, " PUBLIC ");
751: xmlBufferWriteQuotedString(buf, cur->ExternalID);
752: xmlBufferWriteChar(buf, " ");
753: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 754: } else {
1.27 daniel 755: xmlBufferWriteChar(buf, " SYSTEM ");
756: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 757: }
1.25 daniel 758: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 759: break;
760: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1.25 daniel 761: xmlBufferWriteChar(buf, "<!ENTITY ");
762: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 763: if (cur->ExternalID != NULL) {
1.27 daniel 764: xmlBufferWriteChar(buf, " PUBLIC ");
765: xmlBufferWriteQuotedString(buf, cur->ExternalID);
766: xmlBufferWriteChar(buf, " ");
767: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 768: } else {
1.27 daniel 769: xmlBufferWriteChar(buf, " SYSTEM ");
770: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 771: }
772: if (cur->content != NULL) { /* Should be true ! */
1.25 daniel 773: xmlBufferWriteChar(buf, " NDATA ");
1.27 daniel 774: if (cur->orig != NULL)
775: xmlBufferWriteCHAR(buf, cur->orig);
776: else
777: xmlBufferWriteCHAR(buf, cur->content);
1.14 daniel 778: }
1.25 daniel 779: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 780: break;
781: case XML_INTERNAL_PARAMETER_ENTITY:
1.25 daniel 782: xmlBufferWriteChar(buf, "<!ENTITY % ");
783: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 784: xmlBufferWriteChar(buf, " ");
785: if (cur->orig == NULL)
786: xmlBufferWriteQuotedString(buf, cur->content);
787: else
788: xmlBufferWriteQuotedString(buf, cur->orig);
789: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 790: break;
791: case XML_EXTERNAL_PARAMETER_ENTITY:
1.25 daniel 792: xmlBufferWriteChar(buf, "<!ENTITY % ");
793: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 794: if (cur->ExternalID != NULL) {
1.27 daniel 795: xmlBufferWriteChar(buf, " PUBLIC ");
796: xmlBufferWriteQuotedString(buf, cur->ExternalID);
797: xmlBufferWriteChar(buf, " ");
798: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 799: } else {
1.27 daniel 800: xmlBufferWriteChar(buf, " SYSTEM ");
801: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 802: }
1.25 daniel 803: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 804: break;
805: default:
806: fprintf(stderr,
807: "xmlDumpEntitiesTable: internal: unknown type %d\n",
808: cur->type);
809: }
810: }
1.13 daniel 811: }
Webmaster