📄 xmlparse.c
字号:
{
enum XML_Status result = XML_STATUS_OK;
if (ps_parsing != XML_SUSPENDED) {
errorCode = XML_ERROR_NOT_SUSPENDED;
return XML_STATUS_ERROR;
}
ps_parsing = XML_PARSING;
errorCode = processor(parser, bufferPtr, parseEndPtr, &bufferPtr);
if (errorCode != XML_ERROR_NONE) {
eventEndPtr = eventPtr;
processor = errorProcessor;
return XML_STATUS_ERROR;
}
else {
switch (ps_parsing) {
case XML_SUSPENDED:
result = XML_STATUS_SUSPENDED;
break;
case XML_INITIALIZED:
case XML_PARSING:
if (ps_finalBuffer) {
ps_parsing = XML_FINISHED;
return result;
}
default: ;
}
}
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
positionPtr = bufferPtr;
return result;
}
void XMLCALL
XML_GetParsingStatus(XML_Parser parser, XML_ParsingStatus *status)
{
assert(status != NULL);
*status = parser->m_parsingStatus;
}
enum XML_Error XMLCALL
XML_GetErrorCode(XML_Parser parser)
{
return errorCode;
}
XML_Index XMLCALL
XML_GetCurrentByteIndex(XML_Parser parser)
{
if (eventPtr)
return parseEndByteIndex - (parseEndPtr - eventPtr);
return -1;
}
int XMLCALL
XML_GetCurrentByteCount(XML_Parser parser)
{
if (eventEndPtr && eventPtr)
return (int)(eventEndPtr - eventPtr);
return 0;
}
const char * XMLCALL
XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
if (eventPtr && buffer) {
*offset = (int)(eventPtr - buffer);
*size = (int)(bufferEnd - buffer);
return buffer;
}
#endif /* defined XML_CONTEXT_BYTES */
return (char *) 0;
}
XML_Size XMLCALL
XML_GetCurrentLineNumber(XML_Parser parser)
{
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.lineNumber + 1;
}
XML_Size XMLCALL
XML_GetCurrentColumnNumber(XML_Parser parser)
{
if (eventPtr && eventPtr >= positionPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.columnNumber;
}
void XMLCALL
XML_FreeContentModel(XML_Parser parser, XML_Content *model)
{
FREE(model);
}
void * XMLCALL
XML_MemMalloc(XML_Parser parser, size_t size)
{
return MALLOC(size);
}
void * XMLCALL
XML_MemRealloc(XML_Parser parser, void *ptr, size_t size)
{
return REALLOC(ptr, size);
}
void XMLCALL
XML_MemFree(XML_Parser parser, void *ptr)
{
FREE(ptr);
}
void XMLCALL
XML_DefaultCurrent(XML_Parser parser)
{
if (defaultHandler) {
if (openInternalEntities)
reportDefault(parser,
internalEncoding,
openInternalEntities->internalEventPtr,
openInternalEntities->internalEventEndPtr);
else
reportDefault(parser, encoding, eventPtr, eventEndPtr);
}
}
const XML_LChar * XMLCALL
XML_ErrorString(enum XML_Error code)
{
static const XML_LChar* const message[] = {
0,
XML_L("out of memory"),
XML_L("syntax error"),
XML_L("no element found"),
XML_L("not well-formed (invalid token)"),
XML_L("unclosed token"),
XML_L("partial character"),
XML_L("mismatched tag"),
XML_L("duplicate attribute"),
XML_L("junk after document element"),
XML_L("illegal parameter entity reference"),
XML_L("undefined entity"),
XML_L("recursive entity reference"),
XML_L("asynchronous entity"),
XML_L("reference to invalid character number"),
XML_L("reference to binary entity"),
XML_L("reference to external entity in attribute"),
XML_L("XML or text declaration not at start of entity"),
XML_L("unknown encoding"),
XML_L("encoding specified in XML declaration is incorrect"),
XML_L("unclosed CDATA section"),
XML_L("error in processing external entity reference"),
XML_L("document is not standalone"),
XML_L("unexpected parser state - please send a bug report"),
XML_L("entity declared in parameter entity"),
XML_L("requested feature requires XML_DTD support in Expat"),
XML_L("cannot change setting once parsing has begun"),
XML_L("unbound prefix"),
XML_L("must not undeclare prefix"),
XML_L("incomplete markup in parameter entity"),
XML_L("XML declaration not well-formed"),
XML_L("text declaration not well-formed"),
XML_L("illegal character(s) in public id"),
XML_L("parser suspended"),
XML_L("parser not suspended"),
XML_L("parsing aborted"),
XML_L("parsing finished"),
XML_L("cannot suspend in external parameter entity"),
XML_L("reserved prefix (xml) must not be undeclared or bound to another namespace name"),
XML_L("reserved prefix (xmlns) must not be declared or undeclared"),
XML_L("prefix must not be bound to one of the reserved namespace names")
};
if (code > 0 && code < sizeof(message)/sizeof(message[0]))
return message[code];
return NULL;
}
const XML_LChar * XMLCALL
XML_ExpatVersion(void) {
/* V1 is used to string-ize the version number. However, it would
string-ize the actual version macro *names* unless we get them
substituted before being passed to V1. CPP is defined to expand
a macro, then rescan for more expansions. Thus, we use V2 to expand
the version macros, then CPP will expand the resulting V1() macro
with the correct numerals. */
/* ### I'm assuming cpp is portable in this respect... */
#define V1(a,b,c) XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
#define V2(a,b,c) XML_L("expat_")V1(a,b,c)
return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
#undef V1
#undef V2
}
XML_Expat_Version XMLCALL
XML_ExpatVersionInfo(void)
{
XML_Expat_Version version;
version.major = XML_MAJOR_VERSION;
version.minor = XML_MINOR_VERSION;
version.micro = XML_MICRO_VERSION;
return version;
}
const XML_Feature * XMLCALL
XML_GetFeatureList(void)
{
static const XML_Feature features[] = {
{XML_FEATURE_SIZEOF_XML_CHAR, XML_L("sizeof(XML_Char)"),
sizeof(XML_Char)},
{XML_FEATURE_SIZEOF_XML_LCHAR, XML_L("sizeof(XML_LChar)"),
sizeof(XML_LChar)},
#ifdef XML_UNICODE
{XML_FEATURE_UNICODE, XML_L("XML_UNICODE"), 0},
#endif
#ifdef XML_UNICODE_WCHAR_T
{XML_FEATURE_UNICODE_WCHAR_T, XML_L("XML_UNICODE_WCHAR_T"), 0},
#endif
#ifdef XML_DTD
{XML_FEATURE_DTD, XML_L("XML_DTD"), 0},
#endif
#ifdef XML_CONTEXT_BYTES
{XML_FEATURE_CONTEXT_BYTES, XML_L("XML_CONTEXT_BYTES"),
XML_CONTEXT_BYTES},
#endif
#ifdef XML_MIN_SIZE
{XML_FEATURE_MIN_SIZE, XML_L("XML_MIN_SIZE"), 0},
#endif
#ifdef XML_NS
{XML_FEATURE_NS, XML_L("XML_NS"), 0},
#endif
{XML_FEATURE_END, NULL, 0}
};
return features;
}
/* Initially tag->rawName always points into the parse buffer;
for those TAG instances opened while the current parse buffer was
processed, and not yet closed, we need to store tag->rawName in a more
permanent location, since the parse buffer is about to be discarded.
*/
static XML_Bool
storeRawNames(XML_Parser parser)
{
TAG *tag = tagStack;
while (tag) {
int bufSize;
int nameLen = sizeof(XML_Char) * (tag->name.strLen + 1);
char *rawNameBuf = tag->buf + nameLen;
/* Stop if already stored. Since tagStack is a stack, we can stop
at the first entry that has already been copied; everything
below it in the stack is already been accounted for in a
previous call to this function.
*/
if (tag->rawName == rawNameBuf)
break;
/* For re-use purposes we need to ensure that the
size of tag->buf is a multiple of sizeof(XML_Char).
*/
bufSize = nameLen + ROUND_UP(tag->rawNameLength, sizeof(XML_Char));
if (bufSize > tag->bufEnd - tag->buf) {
char *temp = (char *)REALLOC(tag->buf, bufSize);
if (temp == NULL)
return XML_FALSE;
/* if tag->name.str points to tag->buf (only when namespace
processing is off) then we have to update it
*/
if (tag->name.str == (XML_Char *)tag->buf)
tag->name.str = (XML_Char *)temp;
/* if tag->name.localPart is set (when namespace processing is on)
then update it as well, since it will always point into tag->buf
*/
if (tag->name.localPart)
tag->name.localPart = (XML_Char *)temp + (tag->name.localPart -
(XML_Char *)tag->buf);
tag->buf = temp;
tag->bufEnd = temp + bufSize;
rawNameBuf = temp + nameLen;
}
memcpy(rawNameBuf, tag->rawName, tag->rawNameLength);
tag->rawName = rawNameBuf;
tag = tag->parent;
}
return XML_TRUE;
}
static enum XML_Error PTRCALL
contentProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
enum XML_Error result = doContent(parser, 0, encoding, start, end,
endPtr, (XML_Bool)!ps_finalBuffer);
if (result == XML_ERROR_NONE) {
if (!storeRawNames(parser))
return XML_ERROR_NO_MEMORY;
}
return result;
}
static enum XML_Error PTRCALL
externalEntityInitProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
enum XML_Error result = initializeEncoding(parser);
if (result != XML_ERROR_NONE)
return result;
processor = externalEntityInitProcessor2;
return externalEntityInitProcessor2(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
externalEntityInitProcessor2(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
const char *next = start; /* XmlContentTok doesn't always set the last arg */
int tok = XmlContentTok(encoding, start, end, &next);
switch (tok) {
case XML_TOK_BOM:
/* If we are at the end of the buffer, this would cause the next stage,
i.e. externalEntityInitProcessor3, to pass control directly to
doContent (by detecting XML_TOK_NONE) without processing any xml text
declaration - causing the error XML_ERROR_MISPLACED_XML_PI in doContent.
*/
if (next == end && !ps_finalBuffer) {
*endPtr = next;
return XML_ERROR_NONE;
}
start = next;
break;
case XML_TOK_PARTIAL:
if (!ps_finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
eventPtr = start;
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (!ps_finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
eventPtr = start;
return XML_ERROR_PARTIAL_CHAR;
}
processor = externalEntityInitProcessor3;
return externalEntityInitProcessor3(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
externalEntityInitProcessor3(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
int tok;
const char *next = start; /* XmlContentTok doesn't always set the last arg */
eventPtr = start;
tok = XmlContentTok(encoding, start, end, &next);
eventEndPtr = next;
switch (tok) {
case XML_TOK_XML_DECL:
{
enum XML_Error result;
result = processXmlDecl(parser, 1, start, next);
if (result != XML_ERROR_NONE)
return result;
switch (ps_parsing) {
case XML_SUSPENDED:
*endPtr = next;
return XML_ERROR_NONE;
case XML_FINISHED:
return XML_ERROR_ABORTED;
default:
start = next;
}
}
break;
case XML_TOK_PARTIAL:
if (!ps_finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (!ps_finalBuffer) {
*endPtr = start;
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
}
processor = externalEntityContentProcessor;
tagLevel = 1;
return externalEntityContentProcessor(parser, start, end, endPtr);
}
static enum XML_Error PTRCALL
externalEntityContentProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -