📄 entities.c.svn-base
字号:
/* * entities.c : implementation for the XML entities handling * * See Copyright for the status of this software. * * daniel@veillard.com */#define IN_LIBXML#include "libxml.h"#include <string.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#include <libxml/xmlmemory.h>#include <libxml/hash.h>#include <libxml/entities.h>#include <libxml/parser.h>#include <libxml/parserInternals.h>#include <libxml/xmlerror.h>#include <libxml/globals.h>/* * The XML predefined entities. */static xmlEntity xmlEntityLt = { NULL, XML_ENTITY_DECL, BAD_CAST "lt", NULL, NULL, NULL, NULL, NULL, NULL, BAD_CAST "<", BAD_CAST "<", 1, XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, NULL, NULL, 0};static xmlEntity xmlEntityGt = { NULL, XML_ENTITY_DECL, BAD_CAST "gt", NULL, NULL, NULL, NULL, NULL, NULL, BAD_CAST ">", BAD_CAST ">", 1, XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, NULL, NULL, 0};static xmlEntity xmlEntityAmp = { NULL, XML_ENTITY_DECL, BAD_CAST "amp", NULL, NULL, NULL, NULL, NULL, NULL, BAD_CAST "&", BAD_CAST "&", 1, XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, NULL, NULL, 0};static xmlEntity xmlEntityQuot = { NULL, XML_ENTITY_DECL, BAD_CAST "quot", NULL, NULL, NULL, NULL, NULL, NULL, BAD_CAST "\"", BAD_CAST "\"", 1, XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, NULL, NULL, 0};static xmlEntity xmlEntityApos = { NULL, XML_ENTITY_DECL, BAD_CAST "apos", NULL, NULL, NULL, NULL, NULL, NULL, BAD_CAST "'", BAD_CAST "'", 1, XML_INTERNAL_PREDEFINED_ENTITY, NULL, NULL, NULL, NULL, 0};/* * xmlFreeEntity : clean-up an entity record. */static void xmlFreeEntity(xmlEntityPtr entity) { if (entity == NULL) return; if ((entity->children) && (entity->owner == 1) && (entity == (xmlEntityPtr) entity->children->parent)) xmlFreeNodeList(entity->children); if (entity->name != NULL) xmlFree((char *) entity->name); if (entity->ExternalID != NULL) xmlFree((char *) entity->ExternalID); if (entity->SystemID != NULL) xmlFree((char *) entity->SystemID); if (entity->URI != NULL) xmlFree((char *) entity->URI); if (entity->content != NULL) xmlFree((char *) entity->content); if (entity->orig != NULL) xmlFree((char *) entity->orig); xmlFree(entity);}/* * xmlAddEntity : register a new entity for an entities table. */static xmlEntityPtrxmlAddEntity(xmlDtdPtr dtd, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntitiesTablePtr table = NULL; xmlEntityPtr ret; if (name == NULL) return(NULL); switch (type) { case XML_INTERNAL_GENERAL_ENTITY: case XML_EXTERNAL_GENERAL_PARSED_ENTITY: case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: if (dtd->entities == NULL) dtd->entities = xmlHashCreate(0); table = dtd->entities; break; case XML_INTERNAL_PARAMETER_ENTITY: case XML_EXTERNAL_PARAMETER_ENTITY: if (dtd->pentities == NULL) dtd->pentities = xmlHashCreate(0); table = dtd->pentities; break; case XML_INTERNAL_PREDEFINED_ENTITY: return(NULL); } if (table == NULL) return(NULL); ret = (xmlEntityPtr) xmlMalloc(sizeof(xmlEntity)); if (ret == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlAddEntity: out of memory\n"); return(NULL); } memset(ret, 0, sizeof(xmlEntity)); ret->type = XML_ENTITY_DECL; /* * fill the structure. */ ret->name = xmlStrdup(name); ret->etype = (xmlEntityType) type; if (ExternalID != NULL) ret->ExternalID = xmlStrdup(ExternalID); if (SystemID != NULL) ret->SystemID = xmlStrdup(SystemID); if (content != NULL) { ret->length = xmlStrlen(content); ret->content = xmlStrndup(content, ret->length); } else { ret->length = 0; ret->content = NULL; } ret->URI = NULL; /* to be computed by the layer knowing the defining entity */ ret->orig = NULL; ret->owner = 0; if (xmlHashAddEntry(table, name, ret)) { /* * entity was already defined at another level. */ xmlFreeEntity(ret); return(NULL); } return(ret);}/** * xmlGetPredefinedEntity: * @name: the entity name * * Check whether this name is an predefined entity. * * Returns NULL if not, otherwise the entity */xmlEntityPtrxmlGetPredefinedEntity(const xmlChar *name) { if (name == NULL) return(NULL); switch (name[0]) { case 'l': if (xmlStrEqual(name, BAD_CAST "lt")) return(&xmlEntityLt); break; case 'g': if (xmlStrEqual(name, BAD_CAST "gt")) return(&xmlEntityGt); break; case 'a': if (xmlStrEqual(name, BAD_CAST "amp")) return(&xmlEntityAmp); if (xmlStrEqual(name, BAD_CAST "apos")) return(&xmlEntityApos); break; case 'q': if (xmlStrEqual(name, BAD_CAST "quot")) return(&xmlEntityQuot); break; default: break; } return(NULL);}/** * xmlAddDtdEntity: * @doc: the document * @name: the entity name * @type: the entity type XML_xxx_yyy_ENTITY * @ExternalID: the entity external ID if available * @SystemID: the entity system ID if available * @content: the entity content * * Register a new entity for this document DTD external subset. * * Returns a pointer to the entity or NULL in case of error */xmlEntityPtrxmlAddDtdEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntityPtr ret; xmlDtdPtr dtd; if (doc == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlAddDtdEntity: doc == NULL !\n"); return(NULL); } if (doc->extSubset == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlAddDtdEntity: document without external subset !\n"); return(NULL); } dtd = doc->extSubset; ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); if (ret == NULL) return(NULL); /* * Link it to the DTD */ ret->parent = dtd; ret->doc = dtd->doc; if (dtd->last == NULL) { dtd->children = dtd->last = (xmlNodePtr) ret; } else { dtd->last->next = (xmlNodePtr) ret; ret->prev = dtd->last; dtd->last = (xmlNodePtr) ret; } return(ret);}/** * xmlAddDocEntity: * @doc: the document * @name: the entity name * @type: the entity type XML_xxx_yyy_ENTITY * @ExternalID: the entity external ID if available * @SystemID: the entity system ID if available * @content: the entity content * * Register a new entity for this document. * * Returns a pointer to the entity or NULL in case of error */xmlEntityPtrxmlAddDocEntity(xmlDocPtr doc, const xmlChar *name, int type, const xmlChar *ExternalID, const xmlChar *SystemID, const xmlChar *content) { xmlEntityPtr ret; xmlDtdPtr dtd; if (doc == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlAddDocEntity: document is NULL !\n"); return(NULL); } if (doc->intSubset == NULL) { xmlGenericError(xmlGenericErrorContext, "xmlAddDocEntity: document without internal subset !\n"); return(NULL); } dtd = doc->intSubset; ret = xmlAddEntity(dtd, name, type, ExternalID, SystemID, content); if (ret == NULL) return(NULL); /* * Link it to the DTD */ ret->parent = dtd; ret->doc = dtd->doc; if (dtd->last == NULL) { dtd->children = dtd->last = (xmlNodePtr) ret; } else { dtd->last->next = (xmlNodePtr) ret; ret->prev = dtd->last; dtd->last = (xmlNodePtr) ret; } return(ret);}/** * xmlGetEntityFromTable: * @table: an entity table * @name: the entity name * @parameter: look for parameter entities * * Do an entity lookup in the table. * returns the corresponding parameter entity, if found. * * Returns A pointer to the entity structure or NULL if not found. */static xmlEntityPtrxmlGetEntityFromTable(xmlEntitiesTablePtr table, const xmlChar *name) { return((xmlEntityPtr) xmlHashLookup(table, name));}/** * xmlGetParameterEntity: * @doc: the document referencing the entity * @name: the entity name * * Do an entity lookup in the internal and external subsets and * returns the corresponding parameter entity, if found. * * Returns A pointer to the entity structure or NULL if not found. */xmlEntityPtrxmlGetParameterEntity(xmlDocPtr doc, const xmlChar *name) { xmlEntitiesTablePtr table; xmlEntityPtr ret; if (doc == NULL) return(NULL); if ((doc->intSubset != NULL) && (doc->intSubset->pentities != NULL)) { table = (xmlEntitiesTablePtr) doc->intSubset->pentities; ret = xmlGetEntityFromTable(table, name); if (ret != NULL) return(ret); } if ((doc->extSubset != NULL) && (doc->extSubset->pentities != NULL)) { table = (xmlEntitiesTablePtr) doc->extSubset->pentities; return(xmlGetEntityFromTable(table, name)); } return(NULL);}/** * xmlGetDtdEntity: * @doc: the document referencing the entity * @name: the entity name * * Do an entity lookup in the DTD entity hash table and * returns the corresponding entity, if found. * Note: the first argument is the document node, not the DTD node. * * Returns A pointer to the entity structure or NULL if not found. */xmlEntityPtrxmlGetDtdEntity(xmlDocPtr doc, const xmlChar *name) { xmlEntitiesTablePtr table; if (doc == NULL) return(NULL); if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->extSubset->entities; return(xmlGetEntityFromTable(table, name)); } return(NULL);}/** * xmlGetDocEntity: * @doc: the document referencing the entity * @name: the entity name * * Do an entity lookup in the document entity hash table and * returns the corresponding entity, otherwise a lookup is done * in the predefined entities too. * * Returns A pointer to the entity structure or NULL if not found. */xmlEntityPtrxmlGetDocEntity(xmlDocPtr doc, const xmlChar *name) { xmlEntityPtr cur; xmlEntitiesTablePtr table; if (doc != NULL) { if ((doc->intSubset != NULL) && (doc->intSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->intSubset->entities; cur = xmlGetEntityFromTable(table, name); if (cur != NULL) return(cur); } if (doc->standalone != 1) { if ((doc->extSubset != NULL) && (doc->extSubset->entities != NULL)) { table = (xmlEntitiesTablePtr) doc->extSubset->entities; cur = xmlGetEntityFromTable(table, name); if (cur != NULL) return(cur); } } } return(xmlGetPredefinedEntity(name));}/* * Macro used to grow the current buffer. */#define growBufferReentrant() { \ buffer_size *= 2; \ buffer = (xmlChar *) \ xmlRealloc(buffer, buffer_size * sizeof(xmlChar)); \ if (buffer == NULL) { \ xmlGenericError(xmlGenericErrorContext, "realloc failed\n"); \ return(NULL); \ } \}/** * xmlEncodeEntitiesReentrant: * @doc: the document containing the string * @input: A string to convert to XML. * * Do a global encoding of a string, replacing the predefined entities * and non ASCII values with their entities and CharRef counterparts. * Contrary to xmlEncodeEntities, this routine is reentrant, and result * must be deallocated. * * Returns A newly allocated string with the substitution done. */xmlChar *xmlEncodeEntitiesReentrant(xmlDocPtr doc, const xmlChar *input) { const xmlChar *cur = input; xmlChar *buffer = NULL; xmlChar *out = NULL; int buffer_size = 0; int html = 0; if (input == NULL) return(NULL); if (doc != NULL) html = (doc->type == XML_HTML_DOCUMENT_NODE); /* * allocate an translation buffer. */ buffer_size = 1000; buffer = (xmlChar *) xmlMalloc(buffer_size * sizeof(xmlChar)); if (buffer == NULL) { xmlGenericError(xmlGenericErrorContext, "malloc failed\n"); return(NULL); } out = buffer; while (*cur != '\0') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -