xmlparse.c
来自「ARM上的如果你对底层感兴趣」· C语言 代码 · 共 2,269 行 · 第 1/5 页
C
2,269 行
abort();
}
}
switch (XmlTokenRole(&prologState, tok, s, next, encoding)) {
case XML_ROLE_XML_DECL:
{
enum XML_Error result = processXmlDecl(parser, 0, s, next);
if (result != XML_ERROR_NONE)
return result;
}
break;
case XML_ROLE_DOCTYPE_SYSTEM_ID:
hadExternalDoctype = 1;
break;
case XML_ROLE_DOCTYPE_PUBLIC_ID:
case XML_ROLE_ENTITY_PUBLIC_ID:
if (!XmlIsPublicId(encoding, s, next, &eventPtr))
return XML_ERROR_SYNTAX;
if (declEntity) {
XML_Char *tem = poolStoreString(&dtd.pool,
encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!tem)
return XML_ERROR_NO_MEMORY;
normalizePublicId(tem);
declEntity->publicId = tem;
poolFinish(&dtd.pool);
}
break;
case XML_ROLE_INSTANCE_START:
processor = contentProcessor;
if (hadExternalDoctype)
dtd.complete = 0;
return contentProcessor(parser, s, end, nextPtr);
case XML_ROLE_ATTLIST_ELEMENT_NAME:
{
const XML_Char *name = poolStoreString(&dtd.pool, encoding, s, next);
if (!name)
return XML_ERROR_NO_MEMORY;
declElementType = (ELEMENT_TYPE *)lookup(&dtd.elementTypes, name, sizeof(ELEMENT_TYPE));
if (!declElementType)
return XML_ERROR_NO_MEMORY;
if (declElementType->name != name)
poolDiscard(&dtd.pool);
else {
poolFinish(&dtd.pool);
if (!setElementTypePrefix(parser, declElementType))
return XML_ERROR_NO_MEMORY;
}
break;
}
case XML_ROLE_ATTRIBUTE_NAME:
declAttributeId = getAttributeId(parser, encoding, s, next);
if (!declAttributeId)
return XML_ERROR_NO_MEMORY;
declAttributeIsCdata = 0;
break;
case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
declAttributeIsCdata = 1;
break;
case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
if (dtd.complete
&& !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, 0))
return XML_ERROR_NO_MEMORY;
break;
case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
{
const XML_Char *attVal;
enum XML_Error result
= storeAttributeValue(parser, encoding, declAttributeIsCdata,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar,
&dtd.pool);
if (result)
return result;
attVal = poolStart(&dtd.pool);
poolFinish(&dtd.pool);
if (dtd.complete
&& !defineAttribute(declElementType, declAttributeId, declAttributeIsCdata, attVal))
return XML_ERROR_NO_MEMORY;
break;
}
case XML_ROLE_ENTITY_VALUE:
{
enum XML_Error result = storeEntityValue(parser, s, next);
if (result != XML_ERROR_NONE)
return result;
}
break;
case XML_ROLE_ENTITY_SYSTEM_ID:
if (declEntity) {
declEntity->systemId = poolStoreString(&dtd.pool, encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!declEntity->systemId)
return XML_ERROR_NO_MEMORY;
declEntity->base = dtd.base;
poolFinish(&dtd.pool);
}
break;
case XML_ROLE_ENTITY_NOTATION_NAME:
if (declEntity) {
declEntity->notation = poolStoreString(&dtd.pool, encoding, s, next);
if (!declEntity->notation)
return XML_ERROR_NO_MEMORY;
poolFinish(&dtd.pool);
if (unparsedEntityDeclHandler) {
eventPtr = eventEndPtr = s;
unparsedEntityDeclHandler(handlerArg,
declEntity->name,
declEntity->base,
declEntity->systemId,
declEntity->publicId,
declEntity->notation);
}
}
break;
case XML_ROLE_GENERAL_ENTITY_NAME:
{
const XML_Char *name;
if (XmlPredefinedEntityName(encoding, s, next)) {
declEntity = 0;
break;
}
name = poolStoreString(&dtd.pool, encoding, s, next);
if (!name)
return XML_ERROR_NO_MEMORY;
if (dtd.complete) {
declEntity = (ENTITY *)lookup(&dtd.generalEntities, name, sizeof(ENTITY));
if (!declEntity)
return XML_ERROR_NO_MEMORY;
if (declEntity->name != name) {
poolDiscard(&dtd.pool);
declEntity = 0;
}
else
poolFinish(&dtd.pool);
}
else {
poolDiscard(&dtd.pool);
declEntity = 0;
}
}
break;
case XML_ROLE_PARAM_ENTITY_NAME:
declEntity = 0;
break;
case XML_ROLE_NOTATION_NAME:
declNotationPublicId = 0;
declNotationName = 0;
if (notationDeclHandler) {
declNotationName = poolStoreString(&tempPool, encoding, s, next);
if (!declNotationName)
return XML_ERROR_NO_MEMORY;
poolFinish(&tempPool);
}
break;
case XML_ROLE_NOTATION_PUBLIC_ID:
if (!XmlIsPublicId(encoding, s, next, &eventPtr))
return XML_ERROR_SYNTAX;
if (declNotationName) {
XML_Char *tem = poolStoreString(&tempPool,
encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!tem)
return XML_ERROR_NO_MEMORY;
normalizePublicId(tem);
declNotationPublicId = tem;
poolFinish(&tempPool);
}
break;
case XML_ROLE_NOTATION_SYSTEM_ID:
if (declNotationName && notationDeclHandler) {
const XML_Char *systemId
= poolStoreString(&tempPool, encoding,
s + encoding->minBytesPerChar,
next - encoding->minBytesPerChar);
if (!systemId)
return XML_ERROR_NO_MEMORY;
eventPtr = eventEndPtr = s;
notationDeclHandler(handlerArg,
declNotationName,
dtd.base,
systemId,
declNotationPublicId);
}
poolClear(&tempPool);
break;
case XML_ROLE_NOTATION_NO_SYSTEM_ID:
if (declNotationPublicId && notationDeclHandler) {
eventPtr = eventEndPtr = s;
notationDeclHandler(handlerArg,
declNotationName,
dtd.base,
0,
declNotationPublicId);
}
poolClear(&tempPool);
break;
case XML_ROLE_ERROR:
eventPtr = s;
switch (tok) {
case XML_TOK_PARAM_ENTITY_REF:
return XML_ERROR_PARAM_ENTITY_REF;
case XML_TOK_XML_DECL:
return XML_ERROR_MISPLACED_XML_PI;
default:
return XML_ERROR_SYNTAX;
}
case XML_ROLE_GROUP_OPEN:
if (prologState.level >= groupSize) {
if (groupSize)
groupConnector = realloc(groupConnector, groupSize *= 2);
else
groupConnector = malloc(groupSize = 32);
if (!groupConnector)
return XML_ERROR_NO_MEMORY;
}
groupConnector[prologState.level] = 0;
break;
case XML_ROLE_GROUP_SEQUENCE:
if (groupConnector[prologState.level] == '|') {
eventPtr = s;
return XML_ERROR_SYNTAX;
}
groupConnector[prologState.level] = ',';
break;
case XML_ROLE_GROUP_CHOICE:
if (groupConnector[prologState.level] == ',') {
eventPtr = s;
return XML_ERROR_SYNTAX;
}
groupConnector[prologState.level] = '|';
break;
case XML_ROLE_PARAM_ENTITY_REF:
dtd.complete = 0;
break;
case XML_ROLE_NONE:
switch (tok) {
case XML_TOK_PI:
eventPtr = s;
eventEndPtr = next;
if (!reportProcessingInstruction(parser, encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
eventPtr = s;
eventEndPtr = next;
if (!reportComment(parser, encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
}
break;
}
if (defaultHandler) {
switch (tok) {
case XML_TOK_PI:
case XML_TOK_COMMENT:
case XML_TOK_BOM:
case XML_TOK_XML_DECL:
break;
default:
eventPtr = s;
eventEndPtr = next;
reportDefault(parser, encoding, s, next);
}
}
s = next;
}
/* not reached */
}
static
enum XML_Error epilogProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
processor = epilogProcessor;
eventPtr = s;
for (;;) {
const char *next;
int tok = XmlPrologTok(encoding, s, end, &next);
eventEndPtr = next;
switch (tok) {
case XML_TOK_TRAILING_CR:
if (defaultHandler) {
eventEndPtr = end;
reportDefault(parser, encoding, s, end);
}
/* fall through */
case XML_TOK_NONE:
if (nextPtr)
*nextPtr = end;
return XML_ERROR_NONE;
case XML_TOK_PROLOG_S:
if (defaultHandler)
reportDefault(parser, encoding, s, next);
break;
case XML_TOK_PI:
if (!reportProcessingInstruction(parser, encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_COMMENT:
if (!reportComment(parser, encoding, s, next))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_INVALID:
eventPtr = 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;
default:
return XML_ERROR_JUNK_AFTER_DOC_ELEMENT;
}
eventPtr = s = next;
}
}
static
enum XML_Error errorProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
return errorCode;
}
static enum XML_Error
storeAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
const char *ptr, const char *end,
STRING_POOL *pool)
{
enum XML_Error result = appendAttributeValue(parser, enc, isCdata, ptr, end, pool);
if (result)
return result;
if (!isCdata && poolLength(pool) && poolLastChar(pool) == XML_T(' '))
poolChop(pool);
if (!poolAppendChar(pool, XML_T('\0')))
return XML_ERROR_NO_MEMORY;
return XML_ERROR_NONE;
}
static enum XML_Error
appendAttributeValue(XML_Parser parser, const ENCODING *enc, int isCdata,
const char *ptr, const char *end,
STRING_POOL *pool)
{
const ENCODING *internalEnc = ns ? XmlGetInternalEncodingNS() : XmlGetInternalEncoding();
for (;;) {
const char *next;
int tok = XmlAttributeValueTok(enc, ptr, end, &next);
switch (tok) {
case XML_TOK_NONE:
return XML_ERROR_NONE;
case XML_TOK_INVALID:
if (enc == encoding)
eventPtr = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL:
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_CHAR_REF:
{
XML_Char buf[XML_ENCODE_MAX];
int i;
int n = XmlCharRefNumber(enc, ptr);
if (n < 0) {
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_BAD_CHAR_REF;
}
if (!isCdata
&& n == 0x20 /* space */
&& (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
break;
n = XmlEncode(n, (ICHAR *)buf);
if (!n) {
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_BAD_CHAR_REF;
}
for (i = 0; i < n; i++) {
if (!poolAppendChar(pool, buf[i]))
return XML_ERROR_NO_MEMORY;
}
}
break;
case XML_TOK_DATA_CHARS:
if (!poolAppend(pool, enc, ptr, next))
return XML_ERROR_NO_MEMORY;
break;
break;
case XML_TOK_TRAILING_CR:
next = ptr + enc->minBytesPerChar;
/* fall through */
case XML_TOK_ATTRIBUTE_VALUE_S:
case XML_TOK_DATA_NEWLINE:
if (!isCdata && (poolLength(pool) == 0 || poolLastChar(pool) == XML_T(' ')))
break;
if (!poolAppendChar(pool, XML_T(' ')))
return XML_ERROR_NO_MEMORY;
break;
case XML_TOK_ENTITY_REF:
{
const XML_Char *name;
ENTITY *entity;
XML_Char ch = XmlPredefinedEntityName(enc,
ptr + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (ch) {
if (!poolAppendChar(pool, ch))
return XML_ERROR_NO_MEMORY;
break;
}
name = poolStoreString(&temp2Pool, enc,
ptr + enc->minBytesPerChar,
next - enc->minBytesPerChar);
if (!name)
return XML_ERROR_NO_MEMORY;
entity = (ENTITY *)lookup(&dtd.generalEntities, name, 0);
poolDiscard(&temp2Pool);
if (!entity) {
if (dtd.complete) {
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_UNDEFINED_ENTITY;
}
}
else if (entity->open) {
if (enc == encoding)
eventPtr = ptr;
return XML_ERROR_RECURSIVE_ENTITY_REF;
}
else if (entity->notation) {
if (enc == encoding)
eventPtr = pt
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?