Annotation of XML/entities.c, revision 1.6
1.1 httpng 1: /*
2: * entities.c : implementation for the XML entities handking
3: */
4:
5: #include <stdio.h>
6: #include <malloc.h>
1.2 httpng 7: #include <strings.h>
1.1 httpng 8: #include "entities.h"
9:
10: /*
1.3 httpng 11: * A buffer used for converting entities to their equivalent and back.
12: */
1.6 ! veillard 13: static CHAR *buffer = NULL;
1.3 httpng 14: static int buffer_size = 0;
15:
16: void growBuffer(void) {
1.6 ! veillard 17: CHAR *old = buffer;
! 18:
1.3 httpng 19: buffer_size *= 2;
20: buffer = (CHAR *) realloc(buffer, buffer_size * sizeof(CHAR));
21: if (buffer == NULL) {
22: perror("realloc failed");
23: exit(1);
24: }
25: }
26:
27: /*
1.2 httpng 28: * xmlFreeEntity : clean-up an entity record.
1.1 httpng 29: */
30:
1.2 httpng 31: void xmlFreeEntity(xmlEntityPtr entity) {
32: if (entity == NULL) return;
33:
34: entity->value = (CHAR) -1;
35: if (entity->id != NULL)
36: free((char *) entity->id);
37: }
1.1 httpng 38:
39: /*
1.2 httpng 40: * xmlAddDocEntity : register a new entity for an entities table.
1.1 httpng 41: */
1.2 httpng 42: static void xmlAddEntity(xmlEntitiesTablePtr table, CHAR value, const CHAR *id) {
43: int i;
44: xmlEntityPtr cur;
1.1 httpng 45:
1.2 httpng 46: for (i = 0;i < table->nb_entities;i++) {
47: cur = &table->table[i];
48: if ((cur->value == value) &&
49: (!strcmp(cur->id, id))) return;
50: }
51: if (table->nb_entities >= table->max_entities) {
52: /*
53: * need more elements.
54: */
55: table->max_entities *= 2;
56: table->table = (xmlEntityPtr)
57: realloc(table->table, table->max_entities * sizeof(xmlEntity));
58: if (table->table) {
59: perror("realloc failed");
60: exit(1);
61: }
62: }
63: cur = &table->table[table->nb_entities];
64: cur->value = value;
65: cur->id = strdup(id);
66: table->nb_entities++;
67: }
1.1 httpng 68:
69:
70: /*
1.2 httpng 71: * xmlAddDtdEntity : register a new entity for this document.
1.1 httpng 72: */
1.2 httpng 73: void xmlAddDtdEntity(xmlDtdPtr dtd, CHAR value, const CHAR *id) {
74: xmlEntitiesTablePtr table;
1.1 httpng 75:
1.2 httpng 76: table = (xmlEntitiesTablePtr) dtd->entities;
77: if (table == NULL) {
78: table = xmlCreateEntitiesTable();
79: dtd->entities = table;
1.1 httpng 80: }
1.2 httpng 81: xmlAddEntity(table, value, id);
1.1 httpng 82: }
83:
84: /*
1.2 httpng 85: * xmlAddDocEntity : register a new entity for this document.
1.1 httpng 86: */
1.2 httpng 87: void xmlAddDocEntity(xmlDocPtr doc, CHAR value, const CHAR *id) {
88: xmlEntitiesTablePtr table;
1.1 httpng 89:
1.2 httpng 90: table = (xmlEntitiesTablePtr) doc->entities;
91: if (table == NULL) {
92: table = xmlCreateEntitiesTable();
93: doc->entities = table;
94: }
95: xmlAddEntity(table, value, id);
1.1 httpng 96: }
97:
98: /*
99: * xmlGetEntity : do an entity lookup in the hash table and
100: * returns the corrsponding CHAR, if found, zero otherwise.
101: */
102: CHAR xmlGetEntity(xmlDocPtr doc, const CHAR *id) {
1.2 httpng 103: int i;
104: xmlEntityPtr cur;
105: xmlEntitiesTablePtr table;
106:
107: if (doc->entities == NULL) return(0);
1.5 veillard 108: table = (xmlEntitiesTablePtr) doc->entities;
1.2 httpng 109: for (i = 0;i < table->nb_entities;i++) {
110: cur = &table->table[i];
111: if (!strcmp(cur->id, id)) return(cur->value);
112: }
113: return(0);
1.1 httpng 114: }
115:
116: /*
1.6 ! veillard 117: * xmlReadEntities : read an entity.
1.1 httpng 118: */
1.3 httpng 119: const CHAR *xmlReadEntity(xmlDocPtr doc, const CHAR *input, CHAR **value) {
120: static CHAR entity[100];
121: int i;
122:
123: *value = NULL;
124: if (*input == '&') {
125: input++;
126: if (*input == '#') {
127: } else {
128: for (i = 0;i < 99;i++) {
1.4 veillard 129: /* !!!!!!! */
1.3 httpng 130: }
131: }
132: }
133: return(input);
134: }
135:
136: /*
137: * xmlSubstituteEntities : do a global entities lookup on a input string
138: * and returns a duplicate after the entities substitution.
139: */
1.1 httpng 140: CHAR *xmlSubstituteEntities(xmlDocPtr doc, const CHAR *input) {
1.3 httpng 141: CHAR *cur = input;
142: CHAR *out = buffer;
143: int i;
144:
145: if (buffer == NULL) {
146: buffer_size = 1000;
147: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
148: if (buffer == NULL) {
149: perror("malloc failed");
150: exit(1);
151: }
152: out = buffer;
153: }
154: for (i = 0;*cur != 0;cur++) {
155: if (*cur == '&') {
156: CHAR *entity;
157:
158: cur = xmlReadEntity(doc, cur, &entity);
159: if (entity != NULL)
160: while (*entity != 0) {
161: *out++ = *entity++;
162: i++;
1.6 ! veillard 163: if (i + 10 > buffer_size) {
! 164: int index = out - buffer;
! 165:
! 166: growBuffer();
! 167: out = &buffer[index];
! 168: }
1.3 httpng 169: }
170: } else if (*cur == '%') {
1.6 ! veillard 171: /* !!!!!!!!!! */
1.3 httpng 172: } else {
173: *out++ == *cur;
174: i++;
175: }
176:
1.6 ! veillard 177: if (i + 10 > buffer_size) {
! 178: int index = out - buffer;
! 179:
! 180: growBuffer();
! 181: out = &buffer[index];
! 182: }
1.3 httpng 183: }
184: *out++ == 0;
185: return(buffer);
1.1 httpng 186: }
187:
188: /*
1.2 httpng 189: * xmlEncodeEntities : do a global encoding of a string, replacing the
190: * basic values with their entyties form.
1.1 httpng 191: */
1.2 httpng 192: CHAR *xmlEncodeEntities(xmlDocPtr doc, const CHAR *input) {
1.3 httpng 193: CHAR *cur = input;
194: CHAR *out = buffer;
195:
196: if (buffer == NULL) {
197: buffer_size = 1000;
198: buffer = (CHAR *) malloc(buffer_size * sizeof(CHAR));
199: if (buffer == NULL) {
200: perror("malloc failed");
201: exit(1);
202: }
203: out = buffer;
204: }
1.6 ! veillard 205: while (*cur != '\0') {
! 206: if (out - buffer > buffer_size - 100) {
! 207: int index = out - buffer;
! 208:
! 209: growBuffer();
! 210: out = &buffer[index];
! 211: }
! 212:
! 213: /*
! 214: * Check first for entities encoding defined by Dtd's
! 215: * !!!!!!!!!!!
! 216: */
! 217: /*
! 218: * By default one have to encode '<' and '&' !
! 219: */
! 220: if (*cur == '<') {
! 221: *out++ = '&';
! 222: *out++ = 'l';
! 223: *out++ = 't';
! 224: *out++ = ';';
! 225: } else if (*cur == '&') {
! 226: *out++ = '&';
! 227: *out++ = 'a';
! 228: *out++ = 'm';
! 229: *out++ = 'p';
! 230: *out++ = ';';
! 231: } else {
! 232: /*
! 233: * default case, just copy !
! 234: */
! 235: *out++ = *cur;
! 236: }
! 237: cur++;
! 238: }
! 239: *out++ = 0;
! 240: return(buffer);
1.2 httpng 241: }
242:
243: /*
244: * xmlCreateEntitiesTable : create and initialize an enmpty hash table
245: */
246: xmlEntitiesTablePtr xmlCreateEntitiesTable(void) {
247: xmlEntitiesTablePtr ret;
1.1 httpng 248:
1.2 httpng 249: ret = (xmlEntitiesTablePtr)
250: malloc(sizeof(xmlEntitiesTable));
1.1 httpng 251: if (ret == NULL) {
1.2 httpng 252: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
253: sizeof(xmlEntitiesTable));
254: return(NULL);
255: }
256: ret->max_entities = XML_MIN_ENTITIES_TABLE;
257: ret->nb_entities = 0;
258: ret->table = (xmlEntityPtr )
259: malloc(ret->max_entities * sizeof(xmlEntity));
260: if (ret == NULL) {
261: fprintf(stderr, "xmlCreateEntitiesTable : malloc(%d) failed\n",
262: ret->max_entities * sizeof(xmlEntity));
263: free(ret);
1.1 httpng 264: return(NULL);
265: }
266: return(ret);
267: }
268:
269: /*
1.2 httpng 270: * xmlFreeEntitiesTable : clean up and free an entities hash table.
1.1 httpng 271: */
1.2 httpng 272: void xmlFreeEntitiesTable(xmlEntitiesTablePtr table) {
1.1 httpng 273: int i;
274:
275: if (table == NULL) return;
276:
1.2 httpng 277: for (i = 0;i < table->nb_entities;i++) {
278: xmlFreeEntity(&table->table[i]);
1.1 httpng 279: }
1.2 httpng 280: free(table->table);
1.1 httpng 281: free(table);
282: }
283:
Webmaster