Annotation of XML/entities.c, revision 1.32
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.32 ! daniel 59: const CHAR *ExternalID, const CHAR *SystemID, const 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.32 ! daniel 181: const CHAR *ExternalID, const CHAR *SystemID, const 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.32 ! daniel 210: const CHAR *ExternalID, const CHAR *SystemID, const 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: *
1.31 daniel 347: * TODO: remove this, once we are not afraid of breaking binary compatibility
1.28 daniel 348: */
349: static int buffer_size = 0;
350: static CHAR *buffer = NULL;
351:
352: void growBuffer(void) {
353: buffer_size *= 2;
354: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
355: if (buffer == NULL) {
356: perror("realloc failed");
357: exit(1);
358: }
359: }
360:
361:
1.22 daniel 362: /**
363: * xmlEncodeEntities:
364: * @doc: the document containing the string
365: * @input: A string to convert to XML.
366: *
367: * Do a global encoding of a string, replacing the predefined entities
368: * and non ASCII values with their entities and CharRef counterparts.
369: *
1.31 daniel 370: * TODO: remove this, once we are not afraid of breaking binary compatibility
1.28 daniel 371: *
372: * People must migrate their code to xmlEncodeEntitiesReentrant !
1.31 daniel 373: * This routine will issue a warning when encountered.
1.28 daniel 374: *
375: * Returns A newly allocated string with the substitution done.
376: */
377: const CHAR *
378: xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
379: const CHAR *cur = input;
380: CHAR *out = buffer;
1.31 daniel 381: static int warning = 1;
382:
383: if (warning) {
384: fprintf(stderr, "Deprecated API xmlEncodeEntities() used\n");
385: fprintf(stderr, " change code to use xmlEncodeEntitiesReentrant()\n");
386: warning = 0;
387: }
1.28 daniel 388:
389: if (input == NULL) return(NULL);
390: if (buffer == NULL) {
391: buffer_size = 1000;
392: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
393: if (buffer == NULL) {
394: perror("malloc failed");
395: exit(1);
396: }
397: out = buffer;
398: }
399: while (*cur != '\0') {
400: if (out - buffer > buffer_size - 100) {
401: int index = out - buffer;
402:
403: growBuffer();
404: out = &buffer[index];
405: }
406:
407: /*
408: * By default one have to encode at least '<', '>', '"' and '&' !
409: */
410: if (*cur == '<') {
411: *out++ = '&';
412: *out++ = 'l';
413: *out++ = 't';
414: *out++ = ';';
415: } else if (*cur == '>') {
416: *out++ = '&';
417: *out++ = 'g';
418: *out++ = 't';
419: *out++ = ';';
420: } else if (*cur == '&') {
421: *out++ = '&';
422: *out++ = 'a';
423: *out++ = 'm';
424: *out++ = 'p';
425: *out++ = ';';
426: } else if (*cur == '"') {
427: *out++ = '&';
428: *out++ = 'q';
429: *out++ = 'u';
430: *out++ = 'o';
431: *out++ = 't';
432: *out++ = ';';
433: } else if (*cur == '\'') {
434: *out++ = '&';
435: *out++ = 'a';
436: *out++ = 'p';
437: *out++ = 'o';
438: *out++ = 's';
439: *out++ = ';';
440: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
441: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
442: /*
443: * default case, just copy !
444: */
445: *out++ = *cur;
446: #ifndef USE_UTF_8
447: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
448: char buf[10], *ptr;
449: #ifdef HAVE_SNPRINTF
450: snprintf(buf, 9, "&#%d;", *cur);
451: #else
452: sprintf(buf, "&#%d;", *cur);
453: #endif
454: ptr = buf;
455: while (*ptr != 0) *out++ = *ptr++;
456: #endif
457: } else if (IS_CHAR(*cur)) {
458: char buf[10], *ptr;
459:
460: #ifdef HAVE_SNPRINTF
461: snprintf(buf, 9, "&#%d;", *cur);
462: #else
463: sprintf(buf, "&#%d;", *cur);
464: #endif
465: ptr = buf;
466: while (*ptr != 0) *out++ = *ptr++;
467: }
468: #if 0
469: else {
470: /*
471: * default case, this is not a valid char !
472: * Skip it...
473: */
474: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
475: }
476: #endif
477: cur++;
478: }
479: *out++ = 0;
480: return(buffer);
481: }
482:
483: /*
484: * Macro used to grow the current buffer.
485: */
486: #define growBufferReentrant() { \
487: buffer_size *= 2; \
488: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR)); \
489: if (buffer == NULL) { \
490: perror("realloc failed"); \
491: exit(1); \
492: } \
493: }
494:
495:
496: /**
497: * xmlEncodeEntitiesReentrant:
498: * @doc: the document containing the string
499: * @input: A string to convert to XML.
500: *
501: * Do a global encoding of a string, replacing the predefined entities
502: * and non ASCII values with their entities and CharRef counterparts.
503: * Contrary to xmlEncodeEntities, this routine is reentrant, and result
504: * must be deallocated.
505: *
506: * TODO !!!! Once moved to UTF-8 internal encoding, the encoding of non-ascii
507: * get erroneous.
508: *
1.24 daniel 509: * Returns A newly allocated string with the substitution done.
1.1 httpng 510: */
1.22 daniel 511: CHAR *
1.28 daniel 512: xmlEncodeEntitiesReentrant(xmlDocPtr doc, const CHAR *input) {
1.7 veillard 513: const CHAR *cur = input;
1.26 daniel 514: CHAR *buffer = NULL;
515: CHAR *out = NULL;
516: int buffer_size = 0;
1.3 httpng 517:
1.19 daniel 518: if (input == NULL) return(NULL);
1.26 daniel 519:
520: /*
521: * allocate an translation buffer.
522: */
523: buffer_size = 1000;
524: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
1.3 httpng 525: if (buffer == NULL) {
1.26 daniel 526: perror("malloc failed");
527: exit(1);
1.3 httpng 528: }
1.26 daniel 529: out = buffer;
530:
1.6 veillard 531: while (*cur != '\0') {
532: if (out - buffer > buffer_size - 100) {
533: int index = out - buffer;
534:
1.28 daniel 535: growBufferReentrant();
1.6 veillard 536: out = &buffer[index];
537: }
538:
539: /*
1.7 veillard 540: * By default one have to encode at least '<', '>', '"' and '&' !
1.6 veillard 541: */
542: if (*cur == '<') {
543: *out++ = '&';
544: *out++ = 'l';
545: *out++ = 't';
546: *out++ = ';';
1.7 veillard 547: } else if (*cur == '>') {
548: *out++ = '&';
549: *out++ = 'g';
550: *out++ = 't';
551: *out++ = ';';
1.6 veillard 552: } else if (*cur == '&') {
553: *out++ = '&';
554: *out++ = 'a';
555: *out++ = 'm';
556: *out++ = 'p';
1.7 veillard 557: *out++ = ';';
558: } else if (*cur == '"') {
559: *out++ = '&';
560: *out++ = 'q';
561: *out++ = 'u';
562: *out++ = 'o';
563: *out++ = 't';
564: *out++ = ';';
565: } else if (*cur == '\'') {
566: *out++ = '&';
567: *out++ = 'a';
568: *out++ = 'p';
569: *out++ = 'o';
570: *out++ = 's';
1.6 veillard 571: *out++ = ';';
1.21 daniel 572: } else if (((*cur >= 0x20) && (*cur < 0x80)) ||
573: (*cur == '\n') || (*cur == '\r') || (*cur == '\t')) {
574: /*
575: * default case, just copy !
576: */
577: *out++ = *cur;
1.19 daniel 578: #ifndef USE_UTF_8
579: } else if ((sizeof(CHAR) == 1) && (*cur >= 0x80)) {
580: char buf[10], *ptr;
581: #ifdef HAVE_SNPRINTF
582: snprintf(buf, 9, "&#%d;", *cur);
583: #else
584: sprintf(buf, "&#%d;", *cur);
585: #endif
586: ptr = buf;
587: while (*ptr != 0) *out++ = *ptr++;
588: #endif
1.21 daniel 589: } else if (IS_CHAR(*cur)) {
1.20 daniel 590: char buf[10], *ptr;
591:
592: #ifdef HAVE_SNPRINTF
593: snprintf(buf, 9, "&#%d;", *cur);
594: #else
595: sprintf(buf, "&#%d;", *cur);
596: #endif
597: ptr = buf;
598: while (*ptr != 0) *out++ = *ptr++;
1.21 daniel 599: }
600: #if 0
601: else {
1.6 veillard 602: /*
1.21 daniel 603: * default case, this is not a valid char !
604: * Skip it...
1.6 veillard 605: */
1.21 daniel 606: fprintf(stderr, "xmlEncodeEntities: invalid char %d\n", (int) *cur);
1.6 veillard 607: }
1.21 daniel 608: #endif
1.6 veillard 609: cur++;
610: }
611: *out++ = 0;
612: return(buffer);
1.2 httpng 613: }
614:
1.22 daniel 615: /**
616: * xmlCreateEntitiesTable:
617: *
618: * create and initialize an empty entities hash table.
619: *
1.24 daniel 620: * Returns the xmlEntitiesTablePtr just created or NULL in case of error.
1.2 httpng 621: */
1.22 daniel 622: xmlEntitiesTablePtr
623: xmlCreateEntitiesTable(void) {
1.2 httpng 624: xmlEntitiesTablePtr ret;
1.1 httpng 625:
1.2 httpng 626: ret = (xmlEntitiesTablePtr)
627: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 628: if (ret == NULL) {
1.28 daniel 629: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
630: (long)sizeof(xmlEntitiesTable));
1.2 httpng 631: return(NULL);
632: }
633: ret->max_entities = XML_MIN_ENTITIES_TABLE;
634: ret->nb_entities = 0;
635: ret->table = (xmlEntityPtr )
636: malloc(ret->max_entities * sizeof(xmlEntity));
637: if (ret == NULL) {
1.28 daniel 638: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%ld) failed\n",
639: ret->max_entities * (long)sizeof(xmlEntity));
1.2 httpng 640: free(ret);
1.1 httpng 641: return(NULL);
642: }
643: return(ret);
644: }
645:
1.22 daniel 646: /**
647: * xmlFreeEntitiesTable:
648: * @table: An entity table
649: *
650: * Deallocate the memory used by an entities hash table.
1.1 httpng 651: */
1.22 daniel 652: void
653: xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 654: int i;
655:
656: if (table == NULL) return;
657:
1.2 httpng 658: for (i = 0;i < table->nb_entities;i++) {
659: xmlFreeEntity(&table->table[i]);
1.1 httpng 660: }
1.2 httpng 661: free(table->table);
1.1 httpng 662: free(table);
663: }
664:
1.22 daniel 665: /**
666: * xmlCopyEntitiesTable:
667: * @table: An entity table
668: *
669: * Build a copy of an entity table.
670: *
1.24 daniel 671: * Returns the new xmlEntitiesTablePtr or NULL in case of error.
1.22 daniel 672: */
673: xmlEntitiesTablePtr
674: xmlCopyEntitiesTable(xmlEntitiesTablePtr table) {
675: xmlEntitiesTablePtr ret;
676: xmlEntityPtr cur, ent;
677: int i;
678:
679: ret = (xmlEntitiesTablePtr) malloc(sizeof(xmlEntitiesTable));
680: if (ret == NULL) {
681: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
682: return(NULL);
683: }
684: ret->table = (xmlEntityPtr) malloc(table->max_entities *
685: sizeof(xmlEntity));
686: if (ret->table == NULL) {
687: fprintf(stderr, "xmlCopyEntitiesTable: out of memory !\n");
688: free(ret);
689: return(NULL);
690: }
691: ret->max_entities = table->max_entities;
692: ret->nb_entities = table->nb_entities;
693: for (i = 0;i < ret->nb_entities;i++) {
694: cur = &ret->table[i];
695: ent = &table->table[i];
696: cur->len = ent->len;
697: cur->type = ent->type;
698: if (ent->name != NULL)
699: cur->name = xmlStrdup(ent->name);
700: else
701: cur->name = NULL;
702: if (ent->ExternalID != NULL)
703: cur->ExternalID = xmlStrdup(ent->ExternalID);
704: else
705: cur->ExternalID = NULL;
706: if (ent->SystemID != NULL)
707: cur->SystemID = xmlStrdup(ent->SystemID);
708: else
709: cur->SystemID = NULL;
710: if (ent->content != NULL)
711: cur->content = xmlStrdup(ent->content);
712: else
713: cur->content = NULL;
1.27 daniel 714: if (ent->orig != NULL)
715: cur->orig = xmlStrdup(ent->orig);
716: else
717: cur->orig = NULL;
1.22 daniel 718: }
719: return(ret);
720: }
721:
722: /**
723: * xmlDumpEntitiesTable:
1.25 daniel 724: * @buf: An XML buffer.
1.22 daniel 725: * @table: An entity table
726: *
727: * This will dump the content of the entity table as an XML DTD definition
1.13 daniel 728: */
1.22 daniel 729: void
1.25 daniel 730: xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) {
1.14 daniel 731: int i;
732: xmlEntityPtr cur;
733:
734: if (table == NULL) return;
735:
736: for (i = 0;i < table->nb_entities;i++) {
737: cur = &table->table[i];
738: switch (cur->type) {
739: case XML_INTERNAL_GENERAL_ENTITY:
1.25 daniel 740: xmlBufferWriteChar(buf, "<!ENTITY ");
741: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 742: xmlBufferWriteChar(buf, " ");
743: if (cur->orig != NULL)
744: xmlBufferWriteQuotedString(buf, cur->orig);
745: else
746: xmlBufferWriteQuotedString(buf, cur->content);
747: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 748: break;
749: case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
1.25 daniel 750: xmlBufferWriteChar(buf, "<!ENTITY ");
751: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 752: if (cur->ExternalID != NULL) {
1.27 daniel 753: xmlBufferWriteChar(buf, " PUBLIC ");
754: xmlBufferWriteQuotedString(buf, cur->ExternalID);
755: xmlBufferWriteChar(buf, " ");
756: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 757: } else {
1.27 daniel 758: xmlBufferWriteChar(buf, " SYSTEM ");
759: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 760: }
1.25 daniel 761: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 762: break;
763: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
1.25 daniel 764: xmlBufferWriteChar(buf, "<!ENTITY ");
765: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 766: if (cur->ExternalID != NULL) {
1.27 daniel 767: xmlBufferWriteChar(buf, " PUBLIC ");
768: xmlBufferWriteQuotedString(buf, cur->ExternalID);
769: xmlBufferWriteChar(buf, " ");
770: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 771: } else {
1.27 daniel 772: xmlBufferWriteChar(buf, " SYSTEM ");
773: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 774: }
775: if (cur->content != NULL) { /* Should be true ! */
1.25 daniel 776: xmlBufferWriteChar(buf, " NDATA ");
1.27 daniel 777: if (cur->orig != NULL)
778: xmlBufferWriteCHAR(buf, cur->orig);
779: else
780: xmlBufferWriteCHAR(buf, cur->content);
1.14 daniel 781: }
1.25 daniel 782: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 783: break;
784: case XML_INTERNAL_PARAMETER_ENTITY:
1.25 daniel 785: xmlBufferWriteChar(buf, "<!ENTITY % ");
786: xmlBufferWriteCHAR(buf, cur->name);
1.27 daniel 787: xmlBufferWriteChar(buf, " ");
788: if (cur->orig == NULL)
789: xmlBufferWriteQuotedString(buf, cur->content);
790: else
791: xmlBufferWriteQuotedString(buf, cur->orig);
792: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 793: break;
794: case XML_EXTERNAL_PARAMETER_ENTITY:
1.25 daniel 795: xmlBufferWriteChar(buf, "<!ENTITY % ");
796: xmlBufferWriteCHAR(buf, cur->name);
1.14 daniel 797: if (cur->ExternalID != NULL) {
1.27 daniel 798: xmlBufferWriteChar(buf, " PUBLIC ");
799: xmlBufferWriteQuotedString(buf, cur->ExternalID);
800: xmlBufferWriteChar(buf, " ");
801: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 802: } else {
1.27 daniel 803: xmlBufferWriteChar(buf, " SYSTEM ");
804: xmlBufferWriteQuotedString(buf, cur->SystemID);
1.14 daniel 805: }
1.25 daniel 806: xmlBufferWriteChar(buf, ">\n");
1.14 daniel 807: break;
808: default:
809: fprintf(stderr,
810: "xmlDumpEntitiesTable: internal: unknown type %d\n",
811: cur->type);
812: }
813: }
1.13 daniel 814: }
Webmaster