Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenentities.c
Go to the documentation of this file.
00001 /* 00002 * entities.c : implementation for the XML entities handling 00003 * 00004 * See Copyright for the status of this software. 00005 * 00006 * daniel@veillard.com 00007 */ 00008 00009 #define IN_LIBXML 00010 #include "libxml.h" 00011 00012 #include <string.h> 00013 #ifdef HAVE_STDLIB_H 00014 #include <stdlib.h> 00015 #endif 00016 #include <libxml/xmlmemory.h> 00017 #include <libxml/hash.h> 00018 #include <libxml/entities.h> 00019 #include <libxml/parser.h> 00020 #include <libxml/parserInternals.h> 00021 #include <libxml/xmlerror.h> 00022 #include <libxml/globals.h> 00023 #include <libxml/dict.h> 00024 00025 /* 00026 * The XML predefined entities. 00027 */ 00028 00029 static xmlEntity xmlEntityLt = { 00030 NULL, XML_ENTITY_DECL, BAD_CAST "lt", 00031 NULL, NULL, NULL, NULL, NULL, NULL, 00032 BAD_CAST "<", BAD_CAST "<", 1, 00033 XML_INTERNAL_PREDEFINED_ENTITY, 00034 NULL, NULL, NULL, NULL, 0, 1 00035 }; 00036 static xmlEntity xmlEntityGt = { 00037 NULL, XML_ENTITY_DECL, BAD_CAST "gt", 00038 NULL, NULL, NULL, NULL, NULL, NULL, 00039 BAD_CAST ">", BAD_CAST ">", 1, 00040 XML_INTERNAL_PREDEFINED_ENTITY, 00041 NULL, NULL, NULL, NULL, 0, 1 00042 }; 00043 static xmlEntity xmlEntityAmp = { 00044 NULL, XML_ENTITY_DECL, BAD_CAST "amp", 00045 NULL, NULL, NULL, NULL, NULL, NULL, 00046 BAD_CAST "&", BAD_CAST "&", 1, 00047 XML_INTERNAL_PREDEFINED_ENTITY, 00048 NULL, NULL, NULL, NULL, 0, 1 00049 }; 00050 static xmlEntity xmlEntityQuot = { 00051 NULL, XML_ENTITY_DECL, BAD_CAST "quot", 00052 NULL, NULL, NULL, NULL, NULL, NULL, 00053 BAD_CAST "\"", BAD_CAST "\"", 1, 00054 XML_INTERNAL_PREDEFINED_ENTITY, 00055 NULL, NULL, NULL, NULL, 0, 1 00056 }; 00057 static xmlEntity xmlEntityApos = { 00058 NULL, XML_ENTITY_DECL, BAD_CAST "apos", 00059 NULL, NULL, NULL, NULL, NULL, NULL, 00060 BAD_CAST "'", BAD_CAST "'", 1, 00061 XML_INTERNAL_PREDEFINED_ENTITY, 00062 NULL, NULL, NULL, NULL, 0, 1 00063 }; 00064 00071 static void 00072 xmlEntitiesErrMemory(const char *extra) 00073 { 00074 __xmlSimpleError(XML_FROM_TREE, XML_ERR_NO_MEMORY, NULL, NULL, extra); 00075 } 00076 00084 static void 00085 xmlEntitiesErr(xmlParserErrors code, const char *msg) 00086 { 00087 __xmlSimpleError(XML_FROM_TREE, code, NULL, msg, NULL); 00088 } 00089 00090 /* 00091 * xmlFreeEntity : clean-up an entity record. 00092 */ 00093 static void 00094 xmlFreeEntity(xmlEntityPtr entity) 00095 { 00096 xmlDictPtr dict = NULL; 00097 00098 if (entity == NULL) 00099 return; 00100 00101 if (entity->doc != NULL) 00102 dict = entity->doc->dict; 00103 00104 00105 if ((entity->children) && (entity->owner == 1) && 00106 (entity == (xmlEntityPtr) entity->children->parent)) 00107 xmlFreeNodeList(entity->children); 00108 if (dict != NULL) { 00109 if ((entity->name != NULL) && (!xmlDictOwns(dict, entity->name))) 00110 xmlFree((char *) entity->name); 00111 if ((entity->ExternalID != NULL) && 00112 (!xmlDictOwns(dict, entity->ExternalID))) 00113 xmlFree((char *) entity->ExternalID); 00114 if ((entity->SystemID != NULL) && 00115 (!xmlDictOwns(dict, entity->SystemID))) 00116 xmlFree((char *) entity->SystemID); 00117 if ((entity->URI != NULL) && (!xmlDictOwns(dict, entity->URI))) 00118 xmlFree((char *) entity->URI); 00119 if ((entity->content != NULL) 00120 && (!xmlDictOwns(dict, entity->content))) 00121 xmlFree((char *) entity->content); 00122 if ((entity->orig != NULL) && (!xmlDictOwns(dict, entity->orig))) 00123 xmlFree((char *) entity->orig); 00124 } else { 00125 if (entity->name != NULL) 00126 xmlFree((char *) entity->name); 00127 if (entity->ExternalID != NULL) 00128 xmlFree((char *) entity->ExternalID); 00129 if (entity->SystemID != NULL) 00130 xmlFree((char *) entity->SystemID); 00131 if (entity->URI != NULL) 00132 xmlFree((char *) entity->URI); 00133 if (entity->content != NULL) 00134 xmlFree((char *) entity->content); 00135 if (entity->orig != NULL) 00136 xmlFree((char *) entity->orig); 00137 } 00138 xmlFree(entity); 00139 } 00140 00141 /* 00142 * xmlCreateEntity: 00143 * 00144 * internal routine doing the entity node strutures allocations 00145 */ 00146 static xmlEntityPtr 00147 xmlCreateEntity(xmlDictPtr dict, const xmlChar *name, int type, 00148 const xmlChar *ExternalID, const xmlChar *SystemID, 00149 const xmlChar *content) { 00150 xmlEntityPtr ret; 00151 00152 ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); 00153 if (ret == NULL) { 00154 xmlEntitiesErrMemory("xmlCreateEntity: malloc failed"); 00155 return(NULL); 00156 } 00157 memset(ret, 0, sizeof(xmlEntity)); 00158 ret->type = XML_ENTITY_DECL; 00159 ret->checked = 0; 00160 00161 /* 00162 * fill the structure. 00163 */ 00164 ret->etype = (xmlEntityType) type; 00165 if (dict == NULL) { 00166 ret->name = xmlStrdup(name); 00167 if (ExternalID != NULL) 00168 ret->ExternalID = xmlStrdup(ExternalID); 00169 if (SystemID != NULL) 00170 ret->SystemID = xmlStrdup(SystemID); 00171 } else { 00172 ret->name = xmlDictLookup(dict, name, -1); 00173 if (ExternalID != NULL) 00174 ret->ExternalID = xmlDictLookup(dict, ExternalID, -1); 00175 if (SystemID != NULL) 00176 ret->SystemID = xmlDictLookup(dict, SystemID, -1); 00177 } 00178 if (content != NULL) { 00179 ret->length = xmlStrlen(content); 00180 if ((dict != NULL) && (ret->length < 5)) 00181 ret->content = (xmlChar *) 00182 xmlDictLookup(dict, content, ret->length); 00183 else 00184 ret->content = xmlStrndup(content, ret->length); 00185 } else { 00186 ret->length = 0; 00187 ret->content = NULL; 00188 } 00189 ret->URI = NULL; /* to be computed by the layer knowing 00190 the defining entity */ 00191 ret->orig = NULL; 00192 ret->owner = 0; 00193 00194 return(ret); 00195 } 00196 00197 /* 00198 * xmlAddEntity : register a new entity for an entities table. 00199 */ 00200 static xmlEntityPtr 00201 xmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, 00202 const xmlChar *ExternalID, const xmlChar *SystemID, 00203 const xmlChar *content) { 00204 xmlDictPtr dict = NULL; 00205 xmlEntitiesTablePtr table = NULL; 00206 xmlEntityPtr ret; 00207 00208 if (name == NULL) 00209 return(NULL); 00210 if (dtd == NULL) 00211 return(NULL); 00212 if (dtd->doc != NULL) 00213 dict = dtd->doc->dict; 00214 00215 switch (type) { 00216 case XML_INTERNAL_GENERAL_ENTITY: 00217 case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 00218 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 00219 if (dtd->entities == NULL) 00220 dtd->entities = xmlHashCreateDict(0, dict); 00221 table = dtd->entities; 00222 break; 00223 case XML_INTERNAL_PARAMETER_ENTITY: 00224 case XML_EXTERNAL_PARAMETER_ENTITY: 00225 if (dtd->pentities == NULL) 00226 dtd->pentities = xmlHashCreateDict(0, dict); 00227 table = dtd->pentities; 00228 break; 00229 case XML_INTERNAL_PREDEFINED_ENTITY: 00230 return(NULL); 00231 } 00232 if (table == NULL) 00233 return(NULL); 00234 ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content); 00235 if (ret == NULL) 00236 return(NULL); 00237 ret->doc = dtd->doc; 00238 00239 if (xmlHashAddEntry(table, name, ret)) { 00240 /* 00241 * entity was already defined at another level. 00242 */ 00243 xmlFreeEntity(ret); 00244 return(NULL); 00245 } 00246 return(ret); 00247 } 00248 00257 xmlEntityPtr 00258 xmlGetPredefinedEntity(const xmlChar *name) { 00259 if (name == NULL) return(NULL); 00260 switch (name[0]) { 00261 case 'l': 00262 if (xmlStrEqual(name, BAD_CAST "lt")) 00263 return(&xmlEntityLt); 00264 break; 00265 case 'g': 00266 if (xmlStrEqual(name, BAD_CAST "gt")) 00267 return(&xmlEntityGt); 00268 break; 00269 case 'a': 00270 if (xmlStrEqual(name, BAD_CAST "amp")) 00271 return(&xmlEntityAmp); 00272 if (xmlStrEqual(name, BAD_CAST "apos")) 00273 return(&xmlEntityApos); 00274 break; 00275 case 'q': 00276 if (xmlStrEqual(name, BAD_CAST "quot")) 00277 return(&xmlEntityQuot); 00278 break; 00279 default: 00280 break; 00281 } 00282 return(NULL); 00283 } 00284 00298 xmlEntityPtr 00299 xmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type, 00300 const xmlChar *ExternalID, const xmlChar *SystemID, 00301 const xmlChar *content) { 00302 xmlEntityPtr ret; 00303 xmlDtdPtr dtd; 00304 00305 if (doc == NULL) { 00306 xmlEntitiesErr(XML_DTD_NO_DOC, 00307 "xmlAddDtdEntity: document is NULL"); 00308 return(NULL); 00309 } 00310 if (doc->extSubset == NULL) { 00311 xmlEntitiesErr(XML_DTD_NO_DTD, 00312 "xmlAddDtdEntity: document without external subset"); 00313 return(NULL); 00314 } 00315 dtd = doc->extSubset; 00316 ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); 00317 if (ret == NULL) return(NULL); 00318 00319 /* 00320 * Link it to the DTD 00321 */ 00322 ret->parent = dtd; 00323 ret->doc = dtd->doc; 00324 if (dtd->last == NULL) { 00325 dtd->children = dtd->last = (xmlNodePtr) ret; 00326 } else { 00327 dtd->last->next = (xmlNodePtr) ret; 00328 ret->prev = dtd->last; 00329 dtd->last = (xmlNodePtr) ret; 00330 } 00331 return(ret); 00332 } 00333 00347 xmlEntityPtr 00348 xmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, 00349 const xmlChar *ExternalID, const xmlChar *SystemID, 00350 const xmlChar *content) { 00351 xmlEntityPtr ret; 00352 xmlDtdPtr dtd; 00353 00354 if (doc == NULL) { 00355 xmlEntitiesErr(XML_DTD_NO_DOC, 00356 "xmlAddDocEntity: document is NULL"); 00357 return(NULL); 00358 } 00359 if (doc->intSubset == NULL) { 00360 xmlEntitiesErr(XML_DTD_NO_DTD, 00361 "xmlAddDocEntity: document without internal subset"); 00362 return(NULL); 00363 } 00364 dtd = doc->intSubset; 00365 ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); 00366 if (ret == NULL) return(NULL); 00367 00368 /* 00369 * Link it to the DTD 00370 */ 00371 ret->parent = dtd; 00372 ret->doc = dtd->doc; 00373 if (dtd->last == NULL) { 00374 dtd->children = dtd->last = (xmlNodePtr) ret; 00375 } else { 00376 dtd->last->next = (xmlNodePtr) ret; 00377 ret->prev = dtd->last; 00378 dtd->last = (xmlNodePtr) ret; 00379 } 00380 return(ret); 00381 } 00382 00400 xmlEntityPtr 00401 xmlNewEntity(xmlDocPtr doc, const xmlChar *name, int type, 00402 const xmlChar *ExternalID, const xmlChar *SystemID, 00403 const xmlChar *content) { 00404 xmlEntityPtr ret; 00405 xmlDictPtr dict; 00406 00407 if ((doc != NULL) && (doc->intSubset != NULL)) { 00408 return(xmlAddDocEntity(doc, name, type, ExternalID, SystemID, content)); 00409 } 00410 if (doc != NULL) 00411 dict = doc->dict; 00412 else 00413 dict = NULL; 00414 ret = xmlCreateEntity(dict, name, type, ExternalID, SystemID, content); 00415 if (ret == NULL) 00416 return(NULL); 00417 ret->doc = doc; 00418 return(ret); 00419 } 00420 00432 static xmlEntityPtr 00433 xmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) { 00434 return((xmlEntityPtr) xmlHashLookup(table, name)); 00435 } 00436 00447 xmlEntityPtr 00448 xmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) { 00449 xmlEntitiesTablePtr table; 00450 xmlEntityPtr ret; 00451 00452 if (doc == NULL) 00453 return(NULL); 00454 if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) { 00455 table = (xmlEntitiesTablePtr) doc->intSubset->pentities; 00456 ret = xmlGetEntityFromTable(table, name); 00457 if (ret != NULL) 00458 return(ret); 00459 } 00460 if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) { 00461 table = (xmlEntitiesTablePtr) doc->extSubset->pentities; 00462 return(xmlGetEntityFromTable(table, name)); 00463 } 00464 return(NULL); 00465 } 00466 00478 xmlEntityPtr 00479 xmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) { 00480 xmlEntitiesTablePtr table; 00481 00482 if (doc == NULL) 00483 return(NULL); 00484 if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { 00485 table = (xmlEntitiesTablePtr) doc->extSubset->entities; 00486 return(xmlGetEntityFromTable(table, name)); 00487 } 00488 return(NULL); 00489 } 00490 00502 xmlEntityPtr 00503 xmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) { 00504 xmlEntityPtr cur; 00505 xmlEntitiesTablePtr table; 00506 00507 if (doc != NULL) { 00508 if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) { 00509 table = (xmlEntitiesTablePtr) doc->intSubset->entities; 00510 cur = xmlGetEntityFromTable(table, name); 00511 if (cur != NULL) 00512 return(cur); 00513 } 00514 if (doc->standalone != 1) { 00515 if ((doc->extSubset != NULL) && 00516 (doc->extSubset->entities != NULL)) { 00517 table = (xmlEntitiesTablePtr) doc->extSubset->entities; 00518 cur = xmlGetEntityFromTable(table, name); 00519 if (cur != NULL) 00520 return(cur); 00521 } 00522 } 00523 } 00524 return(xmlGetPredefinedEntity(name)); 00525 } 00526 00527 /* 00528 * Macro used to grow the current buffer. 00529 */ 00530 #define growBufferReentrant() { \ 00531 buffer_size *= 2; \ 00532 buffer = (xmlChar *) \ 00533 xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \ 00534 if (buffer == NULL) { \ 00535 xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: realloc failed");\ 00536 return(NULL); \ 00537 } \ 00538 } 00539 00540 00553 xmlChar * 00554 xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) { 00555 const xmlChar *cur = input; 00556 xmlChar *buffer = NULL; 00557 xmlChar *out = NULL; 00558 int buffer_size = 0; 00559 int html = 0; 00560 00561 if (input == NULL) return(NULL); 00562 if (doc != NULL) 00563 html = (doc->type == XML_HTML_DOCUMENT_NODE); 00564 00565 /* 00566 * allocate an translation buffer. 00567 */ 00568 buffer_size = 1000; 00569 buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); 00570 if (buffer == NULL) { 00571 xmlEntitiesErrMemory("xmlEncodeEntitiesReentrant: malloc failed"); 00572 return(NULL); 00573 } 00574 out = buffer; 00575 00576 while (*cur != '\0') { 00577 if (out - buffer > buffer_size - 100) { 00578 int indx = out - buffer; 00579 00580 growBufferReentrant(); 00581 out = &buffer[indx]; 00582 } 00583 00584 /* 00585 * By default one have to encode at least '<', '>', '"' and '&' ! 00586 */ 00587 if (*cur == '<') { 00588 *out++ = '&'; 00589 *out++ = 'l'; 00590 *out++ = 't'; 00591 *out++ = ';'; 00592 } else if (*cur == '>') { 00593 *out++ = '&'; 00594 *out++ = 'g'; 00595 *out++ = 't'; 00596 *out++ = ';'; 00597 } else if (*cur == '&') { 00598 *out++ = '&'; 00599 *out++ = 'a'; 00600 *out++ = 'm'; 00601 *out++ = 'p'; 00602 *out++ = ';'; 00603 } else if (((*cur >= 0x20) && (*cur < 0x80)) || 00604 (*cur == '\n') || (*cur == '\t') || ((html) && (*cur == '\r'))) { 00605 /* 00606 * default case, just copy ! 00607 */ 00608 *out++ = *cur; 00609 } else if (*cur >= 0x80) { 00610 if (((doc != NULL) && (doc->encoding != NULL)) || (html)) { 00611 /* 00612 * Bjørn Reese <br@sseusa.com> provided the patch 00613 xmlChar xc; 00614 xc = (*cur & 0x3F) << 6; 00615 if (cur[1] != 0) { 00616 xc += *(++cur) & 0x3F; 00617 *out++ = xc; 00618 } else 00619 */ 00620 *out++ = *cur; 00621 } else { 00622 /* 00623 * We assume we have UTF-8 input. 00624 */ 00625 char buf[11], *ptr; 00626 int val = 0, l = 1; 00627 00628 if (*cur < 0xC0) { 00629 xmlEntitiesErr(XML_CHECK_NOT_UTF8, 00630 "xmlEncodeEntitiesReentrant : input not UTF-8"); 00631 if (doc != NULL) 00632 doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 00633 snprintf(buf, sizeof(buf), "&#%d;", *cur); 00634 buf[sizeof(buf) - 1] = 0; 00635 ptr = buf; 00636 while (*ptr != 0) *out++ = *ptr++; 00637 cur++; 00638 continue; 00639 } else if (*cur < 0xE0) { 00640 val = (cur[0]) & 0x1F; 00641 val <<= 6; 00642 val |= (cur[1]) & 0x3F; 00643 l = 2; 00644 } else if (*cur < 0xF0) { 00645 val = (cur[0]) & 0x0F; 00646 val <<= 6; 00647 val |= (cur[1]) & 0x3F; 00648 val <<= 6; 00649 val |= (cur[2]) & 0x3F; 00650 l = 3; 00651 } else if (*cur < 0xF8) { 00652 val = (cur[0]) & 0x07; 00653 val <<= 6; 00654 val |= (cur[1]) & 0x3F; 00655 val <<= 6; 00656 val |= (cur[2]) & 0x3F; 00657 val <<= 6; 00658 val |= (cur[3]) & 0x3F; 00659 l = 4; 00660 } 00661 if ((l == 1) || (!IS_CHAR(val))) { 00662 xmlEntitiesErr(XML_ERR_INVALID_CHAR, 00663 "xmlEncodeEntitiesReentrant : char out of range\n"); 00664 if (doc != NULL) 00665 doc->encoding = xmlStrdup(BAD_CAST "ISO-8859-1"); 00666 snprintf(buf, sizeof(buf), "&#%d;", *cur); 00667 buf[sizeof(buf) - 1] = 0; 00668 ptr = buf; 00669 while (*ptr != 0) *out++ = *ptr++; 00670 cur++; 00671 continue; 00672 } 00673 /* 00674 * We could do multiple things here. Just save as a char ref 00675 */ 00676 snprintf(buf, sizeof(buf), "&#x%X;", val); 00677 buf[sizeof(buf) - 1] = 0; 00678 ptr = buf; 00679 while (*ptr != 0) *out++ = *ptr++; 00680 cur += l; 00681 continue; 00682 } 00683 } else if (IS_BYTE_CHAR(*cur)) { 00684 char buf[11], *ptr; 00685 00686 snprintf(buf, sizeof(buf), "&#%d;", *cur); 00687 buf[sizeof(buf) - 1] = 0; 00688 ptr = buf; 00689 while (*ptr != 0) *out++ = *ptr++; 00690 } 00691 cur++; 00692 } 00693 *out = 0; 00694 return(buffer); 00695 } 00696 00707 xmlChar * 00708 xmlEncodeSpecialChars(xmlDocPtr doc ATTRIBUTE_UNUSED, const xmlChar *input) { 00709 const xmlChar *cur = input; 00710 xmlChar *buffer = NULL; 00711 xmlChar *out = NULL; 00712 int buffer_size = 0; 00713 if (input == NULL) return(NULL); 00714 00715 /* 00716 * allocate an translation buffer. 00717 */ 00718 buffer_size = 1000; 00719 buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); 00720 if (buffer == NULL) { 00721 xmlEntitiesErrMemory("xmlEncodeSpecialChars: malloc failed"); 00722 return(NULL); 00723 } 00724 out = buffer; 00725 00726 while (*cur != '\0') { 00727 if (out - buffer > buffer_size - 10) { 00728 int indx = out - buffer; 00729 00730 growBufferReentrant(); 00731 out = &buffer[indx]; 00732 } 00733 00734 /* 00735 * By default one have to encode at least '<', '>', '"' and '&' ! 00736 */ 00737 if (*cur == '<') { 00738 *out++ = '&'; 00739 *out++ = 'l'; 00740 *out++ = 't'; 00741 *out++ = ';'; 00742 } else if (*cur == '>') { 00743 *out++ = '&'; 00744 *out++ = 'g'; 00745 *out++ = 't'; 00746 *out++ = ';'; 00747 } else if (*cur == '&') { 00748 *out++ = '&'; 00749 *out++ = 'a'; 00750 *out++ = 'm'; 00751 *out++ = 'p'; 00752 *out++ = ';'; 00753 } else if (*cur == '"') { 00754 *out++ = '&'; 00755 *out++ = 'q'; 00756 *out++ = 'u'; 00757 *out++ = 'o'; 00758 *out++ = 't'; 00759 *out++ = ';'; 00760 } else if (*cur == '\r') { 00761 *out++ = '&'; 00762 *out++ = '#'; 00763 *out++ = '1'; 00764 *out++ = '3'; 00765 *out++ = ';'; 00766 } else { 00767 /* 00768 * Works because on UTF-8, all extended sequences cannot 00769 * result in bytes in the ASCII range. 00770 */ 00771 *out++ = *cur; 00772 } 00773 cur++; 00774 } 00775 *out = 0; 00776 return(buffer); 00777 } 00778 00787 xmlEntitiesTablePtr 00788 xmlCreateEntitiesTable(void) { 00789 return((xmlEntitiesTablePtr) xmlHashCreate(0)); 00790 } 00791 00799 static void 00800 xmlFreeEntityWrapper(xmlEntityPtr entity, 00801 const xmlChar *name ATTRIBUTE_UNUSED) { 00802 if (entity != NULL) 00803 xmlFreeEntity(entity); 00804 } 00805 00812 void 00813 xmlFreeEntitiesTable(xmlEntitiesTablePtr table) { 00814 xmlHashFree(table, (xmlHashDeallocator) xmlFreeEntityWrapper); 00815 } 00816 00817 #ifdef LIBXML_TREE_ENABLED 00818 00826 static xmlEntityPtr 00827 xmlCopyEntity(xmlEntityPtr ent) { 00828 xmlEntityPtr cur; 00829 00830 cur = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); 00831 if (cur == NULL) { 00832 xmlEntitiesErrMemory("xmlCopyEntity:: malloc failed"); 00833 return(NULL); 00834 } 00835 memset(cur, 0, sizeof(xmlEntity)); 00836 cur->type = XML_ENTITY_DECL; 00837 00838 cur->etype = ent->etype; 00839 if (ent->name != NULL) 00840 cur->name = xmlStrdup(ent->name); 00841 if (ent->ExternalID != NULL) 00842 cur->ExternalID = xmlStrdup(ent->ExternalID); 00843 if (ent->SystemID != NULL) 00844 cur->SystemID = xmlStrdup(ent->SystemID); 00845 if (ent->content != NULL) 00846 cur->content = xmlStrdup(ent->content); 00847 if (ent->orig != NULL) 00848 cur->orig = xmlStrdup(ent->orig); 00849 if (ent->URI != NULL) 00850 cur->URI = xmlStrdup(ent->URI); 00851 return(cur); 00852 } 00853 00862 xmlEntitiesTablePtr 00863 xmlCopyEntitiesTable(xmlEntitiesTablePtr table) { 00864 return(xmlHashCopy(table, (xmlHashCopier) xmlCopyEntity)); 00865 } 00866 #endif /* LIBXML_TREE_ENABLED */ 00867 00868 #ifdef LIBXML_OUTPUT_ENABLED 00869 00878 static void 00879 xmlDumpEntityContent(xmlBufferPtr buf, const xmlChar *content) { 00880 if (buf->alloc == XML_BUFFER_ALLOC_IMMUTABLE) return; 00881 if (xmlStrchr(content, '%')) { 00882 const xmlChar * base, *cur; 00883 00884 xmlBufferCCat(buf, "\""); 00885 base = cur = content; 00886 while (*cur != 0) { 00887 if (*cur == '"') { 00888 if (base != cur) 00889 xmlBufferAdd(buf, base, cur - base); 00890 xmlBufferAdd(buf, BAD_CAST """, 6); 00891 cur++; 00892 base = cur; 00893 } else if (*cur == '%') { 00894 if (base != cur) 00895 xmlBufferAdd(buf, base, cur - base); 00896 xmlBufferAdd(buf, BAD_CAST "%", 6); 00897 cur++; 00898 base = cur; 00899 } else { 00900 cur++; 00901 } 00902 } 00903 if (base != cur) 00904 xmlBufferAdd(buf, base, cur - base); 00905 xmlBufferCCat(buf, "\""); 00906 } else { 00907 xmlBufferWriteQuotedString(buf, content); 00908 } 00909 } 00910 00918 void 00919 xmlDumpEntityDecl(xmlBufferPtr buf, xmlEntityPtr ent) { 00920 if ((buf == NULL) || (ent == NULL)) return; 00921 switch (ent->etype) { 00922 case XML_INTERNAL_GENERAL_ENTITY: 00923 xmlBufferWriteChar(buf, "<!ENTITY "); 00924 xmlBufferWriteCHAR(buf, ent->name); 00925 xmlBufferWriteChar(buf, " "); 00926 if (ent->orig != NULL) 00927 xmlBufferWriteQuotedString(buf, ent->orig); 00928 else 00929 xmlDumpEntityContent(buf, ent->content); 00930 xmlBufferWriteChar(buf, ">\n"); 00931 break; 00932 case XML_EXTERNAL_GENERAL_PARSED_ENTITY: 00933 xmlBufferWriteChar(buf, "<!ENTITY "); 00934 xmlBufferWriteCHAR(buf, ent->name); 00935 if (ent->ExternalID != NULL) { 00936 xmlBufferWriteChar(buf, " PUBLIC "); 00937 xmlBufferWriteQuotedString(buf, ent->ExternalID); 00938 xmlBufferWriteChar(buf, " "); 00939 xmlBufferWriteQuotedString(buf, ent->SystemID); 00940 } else { 00941 xmlBufferWriteChar(buf, " SYSTEM "); 00942 xmlBufferWriteQuotedString(buf, ent->SystemID); 00943 } 00944 xmlBufferWriteChar(buf, ">\n"); 00945 break; 00946 case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: 00947 xmlBufferWriteChar(buf, "<!ENTITY "); 00948 xmlBufferWriteCHAR(buf, ent->name); 00949 if (ent->ExternalID != NULL) { 00950 xmlBufferWriteChar(buf, " PUBLIC "); 00951 xmlBufferWriteQuotedString(buf, ent->ExternalID); 00952 xmlBufferWriteChar(buf, " "); 00953 xmlBufferWriteQuotedString(buf, ent->SystemID); 00954 } else { 00955 xmlBufferWriteChar(buf, " SYSTEM "); 00956 xmlBufferWriteQuotedString(buf, ent->SystemID); 00957 } 00958 if (ent->content != NULL) { /* Should be true ! */ 00959 xmlBufferWriteChar(buf, " NDATA "); 00960 if (ent->orig != NULL) 00961 xmlBufferWriteCHAR(buf, ent->orig); 00962 else 00963 xmlBufferWriteCHAR(buf, ent->content); 00964 } 00965 xmlBufferWriteChar(buf, ">\n"); 00966 break; 00967 case XML_INTERNAL_PARAMETER_ENTITY: 00968 xmlBufferWriteChar(buf, "<!ENTITY % "); 00969 xmlBufferWriteCHAR(buf, ent->name); 00970 xmlBufferWriteChar(buf, " "); 00971 if (ent->orig == NULL) 00972 xmlDumpEntityContent(buf, ent->content); 00973 else 00974 xmlBufferWriteQuotedString(buf, ent->orig); 00975 xmlBufferWriteChar(buf, ">\n"); 00976 break; 00977 case XML_EXTERNAL_PARAMETER_ENTITY: 00978 xmlBufferWriteChar(buf, "<!ENTITY % "); 00979 xmlBufferWriteCHAR(buf, ent->name); 00980 if (ent->ExternalID != NULL) { 00981 xmlBufferWriteChar(buf, " PUBLIC "); 00982 xmlBufferWriteQuotedString(buf, ent->ExternalID); 00983 xmlBufferWriteChar(buf, " "); 00984 xmlBufferWriteQuotedString(buf, ent->SystemID); 00985 } else { 00986 xmlBufferWriteChar(buf, " SYSTEM "); 00987 xmlBufferWriteQuotedString(buf, ent->SystemID); 00988 } 00989 xmlBufferWriteChar(buf, ">\n"); 00990 break; 00991 default: 00992 xmlEntitiesErr(XML_DTD_UNKNOWN_ENTITY, 00993 "xmlDumpEntitiesDecl: internal: unknown type entity type"); 00994 } 00995 } 00996 01004 static void 01005 xmlDumpEntityDeclScan(xmlEntityPtr ent, xmlBufferPtr buf) { 01006 xmlDumpEntityDecl(buf, ent); 01007 } 01008 01016 void 01017 xmlDumpEntitiesTable(xmlBufferPtr buf, xmlEntitiesTablePtr table) { 01018 xmlHashScan(table, (xmlHashScanner)xmlDumpEntityDeclScan, buf); 01019 } 01020 #endif /* LIBXML_OUTPUT_ENABLED */ 01021 #define bottom_entities 01022 #include "elfgcchack.h" Generated on Sat May 26 2012 04:33:17 for ReactOS by
1.7.6.1
|