xmlparse.c.orig
来自「ARM上的如果你对底层感兴趣」· ORIG 代码 · 共 2,269 行 · 第 1/5 页
ORIG
2,269 行
enum XML_Error externalEntityContentProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
return doContent(parser, 1, encoding, start, end, endPtr);
}
static enum XML_Error
doContent(XML_Parser parser,
int startTagLevel,
const ENCODING *enc,
const char *s,
const char *end,
const char **nextPtr)
{
const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
const char **eventPP;
const char **eventEndPP;
if (enc == encoding) {
eventPP = &eventPtr;
eventEndPP = &eventEndPtr;
}
else {
eventPP = &(openInternalEntities->internalEventPtr);
eventEndPP = &(openInternalEntities->internalEventEndPtr);
}
*eventPP = s;
for (;;) {
const char *next;
int tok = XmlContentTok(enc, s, end, &next);
*eventEndPP = next;
switch (tok) {
case XML_TOK_TRAILING_CR:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
*eventEndPP = end;
if (characterDataHandler) {
XML_Char c = XML_T('\n');
characterDataHandler(handlerArg, &c, 1);
}
else if (defaultHandler)
reportDefault(parser, enc, s, end);
if (startTagLevel == 0)
return XML_ERROR_NO_ELEMENTS;
if (tagLevel != startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
return XML_ERROR_NONE;
case XML_TOK_NONE:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
if (startTagLevel > 0) {
if (tagLevel != startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
return XML_ERROR_NONE;
}
return XML_ERROR_NO_ELEMENTS;
case XML_TOK_INVALID:
*eventPP = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
case XML_TOK_ENTITY_REF:
{
const XML_Char *name;
ENTITY *entity;
XML_Char ch = XmlPredefinedEntityName(enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (ch) {
if (characterDataHandler)
characterDataHandler(handlerArg, &ch, 1);
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
}
name = poolStoreString(&dtd.pool, enc,
s + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (!name)
return XML_ERROR_NO_MEMORY;
entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
poolDiscard(&dtd.pool);
if (!entity) {
if (dtd.complete || dtd.standalone)
return XML_ERROR_UNDEFINED_ENTITY;
if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
}
if (entity->open)
return XML_ERROR_RECURSIVE_ENTITY_REF;
if (entity->notation)
return XML_ERROR_BINARY_ENTITY_REF;
if (entity) {
if (entity->textPtr) {
enum XML_Error result;
OPEN_INTERNAL_ENTITY openEntity;
if (defaultHandler && !defaultExpandInternalEntities) {
reportDefault(parser, enc, s, next);
break;
}
entity->open = 1;
openEntity.next = openInternalEntities;
openInternalEntities = &openEntity;
openEntity.entity = entity;
openEntity.internalEventPtr = 0;
openEntity.internalEventEndPtr = 0;
result = doContent(parser,
tagLevel,
internalEnc,
(char *)entity->textPtr,
(char *)(entity->textPtr + entity->textLen),
0);
entity->open = 0;
openInternalEntities = openEntity.next;
if (result)
return result;
}
else if (externalEntityRefHandler) {
const XML_Char *context;
entity->open = 1;
context = getContext(parser);
entity->open = 0;
if (!context)
return XML_ERROR_NO_MEMORY;
if (!externalEntityRefHandler(parser, context, dtd.base, entity->systemId, entity->publicId))
return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
break;
}
case XML_TOK_START_TAG_WITH_ATTS:
if (!startElementHandler) {
enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
if (result)
return result;
}
/* fall through */
case XML_TOK_START_TAG_NO_ATTS:
{
TAG *tag;
if (freeTagList) {
tag = freeTagList;
freeTagList = freeTagList->parent;
}
else {
tag = malloc(sizeof(TAG));
if (!tag)
return XML_ERROR_NO_MEMORY;
tag->buf = malloc(INIT_TAG_BUF_SIZE);
if (!tag->buf)
return XML_ERROR_NO_MEMORY;
tag->bufEnd = tag->buf + INIT_TAG_BUF_SIZE;
}
tag->bindings = 0;
tag->parent = tagStack;
tagStack = tag;
tag->rawName = s + enc->minBytesPerChar;
tag->rawNameLength = XmlNameLength(enc, tag->rawName);
if (nextPtr) {
if (tag->rawNameLength > tag->bufEnd - tag->buf) {
int bufSize = tag->rawNameLength * 4;
bufSize = ROUND_UP(bufSize, sizeof(XML_Char));
tag->buf = realloc(tag->buf, bufSize);
if (!tag->buf)
return XML_ERROR_NO_MEMORY;
tag->bufEnd = tag->buf + bufSize;
}
memcpy(tag->buf, tag->rawName, tag->rawNameLength);
tag->rawName = tag->buf;
}
++tagLevel;
if (startElementHandler) {
enum XML_Error result;
XML_Char *toPtr;
for (;;) {
const char *rawNameEnd = tag->rawName + tag->rawNameLength;
const char *fromPtr = tag->rawName;
int bufSize;
if (nextPtr)
toPtr = (XML_Char *)(tag->buf + ROUND_UP(tag->rawNameLength, sizeof(XML_Char)));
else
toPtr = (XML_Char *)tag->buf;
tag->name = toPtr;
XmlConvert(enc,
&fromPtr, rawNameEnd,
(ICHAR **)&toPtr, (ICHAR *)tag->bufEnd - 1);
if (fromPtr == rawNameEnd)
break;
bufSize = (tag->bufEnd - tag->buf) << 1;
tag->buf = realloc(tag->buf, bufSize);
if (!tag->buf)
return XML_ERROR_NO_MEMORY;
tag->bufEnd = tag->buf + bufSize;
if (nextPtr)
tag->rawName = tag->buf;
}
*toPtr = XML_T('\0');
result = storeAtts(parser, enc, s, &(tag->name), &(tag->bindings));
if (result)
return result;
startElementHandler(handlerArg, tag->name, (const XML_Char **)atts);
poolClear(&tempPool);
}
else {
tag->name = 0;
if (defaultHandler)
reportDefault(parser, enc, s, next);
}
break;
}
case XML_TOK_EMPTY_ELEMENT_WITH_ATTS:
if (!startElementHandler) {
enum XML_Error result = storeAtts(parser, enc, s, 0, 0);
if (result)
return result;
}
/* fall through */
case XML_TOK_EMPTY_ELEMENT_NO_ATTS:
if (startElementHandler || endElementHandler) {
const char *rawName = s + enc->minBytesPerChar;
enum XML_Error result;
BINDING *bindings = 0;
const XML_Char *name = poolStoreString(&tempPool, enc, rawName,
rawName
+ XmlNameLength(enc, rawName));
if (!name)
return XML_ERROR_NO_MEMORY;
poolFinish(&tempPool);
result = storeAtts(parser, enc, s, &name, &bindings);
if (result)
return result;
poolFinish(&tempPool);
if (startElementHandler)
startElementHandler(handlerArg, name, (const XML_Char **)atts);
if (endElementHandler) {
if (startElementHandler)
*eventEndPP = *eventPP;
endElementHandler(handlerArg, name);
}
poolClear(&tempPool);
while (bindings) {
BINDING *b = bindings;
bindings = bindings->nextTagBinding;
b->nextTagBinding = freeBindingList;
freeBindingList = b;
b->prefix->binding = b->prevPrefixBinding;
}
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
if (tagLevel == 0)
return epilogProcessor(parser, next, end, nextPtr);
break;
case XML_TOK_END_TAG:
if (tagLevel == startTagLevel)
return XML_ERROR_ASYNC_ENTITY;
else {
int len;
const char *rawName;
TAG *tag = tagStack;
tagStack = tag->parent;
tag->parent = freeTagList;
freeTagList = tag;
rawName = s + enc->minBytesPerChar*2;
len = XmlNameLength(enc, rawName);
if (len != tag->rawNameLength
|| memcmp(tag->rawName, rawName, len) != 0) {
*eventPP = rawName;
return XML_ERROR_TAG_MISMATCH;
}
--tagLevel;
if (endElementHandler && tag->name)
endElementHandler(handlerArg, tag->name);
else if (defaultHandler)
reportDefault(parser, enc, s, next);
while (tag->bindings) {
BINDING *b = tag->bindings;
tag->bindings = tag->bindings->nextTagBinding;
b->nextTagBinding = freeBindingList;
freeBindingList = b;
b->prefix->binding = b->prevPrefixBinding;
}
if (tagLevel == 0)
return epilogProcessor(parser, next, end, nextPtr);
}
break;
case XML_TOK_CHAR_REF:
{
int n = XmlCharRefNumber(enc, s);
if (n < 0)
return XML_ERROR_BAD_CHAR_REF;
if (characterDataHandler) {
XML_Char buf[XML_ENCODE_MAX];
characterDataHandler(handlerArg, buf, XmlEncode(n, (ICHAR *)buf));
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
}
break;
case XML_TOK_XML_DECL:
return XML_ERROR_MISPLACED_XML_PI;
case XML_TOK_DATA_NEWLINE:
if (characterDataHandler) {
XML_Char c = XML_T('\n');
characterDataHandler(handlerArg, &c, 1);
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
case XML_TOK_CDATA_SECT_OPEN:
{
enum XML_Error result;
if (characterDataHandler)
characterDataHandler(handlerArg, dataBuf, 0);
else if (defaultHandler)
reportDefault(parser, enc, s, next);
result = doCdataSection(parser, enc, &next, end, nextPtr);
if (!next) {
processor = cdataSectionProcessor;
return result;
}
}
break;
case XML_TOK_TRAILING_RSQB:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
if (characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
}
else
characterDataHandler(handlerArg,
(XML_Char *)s,
(XML_Char *)end - (XML_Char *)s);
}
else if (defaultHandler)
reportDefault(parser, enc, s, end);
if (startTagLevel == 0) {
*eventPP = end;
return XML_ERROR_NO_ELEMENTS;
}
if (tagLevel != startTagLevel) {
*eventPP = end;
return XML_ERROR_ASYNC_ENTITY;
}
return XML_ERROR_NONE;
case XML_TOK_DATA_CHARS:
if (characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = s;
characterDataHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
if (s == next)
break;
*eventPP = s;
}
}
else
characterDataHandler(handlerArg,
(XML_Char *)s,
(XML_Char *)next - (XML_Char *)s);
}
else if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
case XML_TOK_PI:
if (!reportProcessingInstruction(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
if (!reportComment(parser, enc, s, next))
return XML_ERROR_NO_MEMORY;
break;
default:
if (defaultHandler)
reportDefault(parser, enc, s, next);
break;
}
*eventPP = s = next;
}
/* not reached */
}
/* If tagNamePtr is non-null, build a real list of attributes,
otherwise just check the attributes for well-formedness. */
static enum XML_Error storeAtts(XML_Parser parser, const ENCODING *enc,
const char *s, const XML_Char **tagNamePtr,
BINDING **bindingsPtr)
{
ELEMENT_TYPE *elementType = 0;
int nDefaultAtts = 0;
const XML_Char **appAtts;
int attIndex = 0;
int i;
int n;
int nPrefixes = 0;
BINDING *binding;
const XML_Char *localPart;
if (tagNamePtr) {
elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, *tagNamePtr, 0);
if (!elementType) {
*tagNamePtr = poolCopyString(&dtd.pool, *tagNamePtr);
if (!*tagNamePtr)
return XML_ERROR_NO_MEMORY;
elementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, *tagNamePtr, sizeof(ELEMENT_TYPE));
if (!elementType)
return XML_ERROR_NO_MEMORY;
if (ns && !setElementTypePrefix(parser, elementType))
return XML_ERROR_NO_MEMORY;
}
nDefaultAtts = elementType->nDefaultAtts;
}
n = XmlGetAttributes(enc, s, attsSize, atts);
if (n + nDefaultAtts > attsSize) {
int oldAttsSize = attsSize;
attsSize = n + nDefaultAtts + INIT_ATTS_SIZE;
atts = realloc((void *)atts, attsSize * sizeof(ATTRIBUTE));
if (!atts)
return XML_ERROR_NO_MEMORY;
if (n > oldAttsSize)
XmlGetAttributes(enc, s, n, atts);
}
appAtts = (const XML_Char **)atts;
for (i = 0; i < n; i++) {
ATTRIBUTE_ID *attId = getAttributeId(parser, enc, atts[i].name,
atts[i].name
+ XmlNameLength(enc, atts[i].name));
if (!attId)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?