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