📄 xmlparse.c
字号:
return 0;
}
buffer = temp;
if (!buffer) {
errorCode = XML_ERROR_NO_MEMORY;
eventPtr = eventEndPtr = NULL;
processor = errorProcessor;
return 0;
}
bufferLim = buffer + len * 2;
}
memcpy(buffer, end, nLeftOver);
bufferPtr = buffer;
bufferEnd = buffer + nLeftOver;
}
return 1;
}
#endif /* not defined XML_CONTEXT_BYTES */
else {
void *buff = XML_GetBuffer(parser, len);
if (buff == NULL)
return 0;
else {
memcpy(buff, s, len);
return XML_ParseBuffer(parser, len, isFinal);
}
}
}
int XML_ParseBuffer(XML_Parser parser, int len, int isFinal)
{
const char *start = bufferPtr;
positionPtr = start;
bufferEnd += len;
parseEndByteIndex += len;
errorCode = processor(parser, start, parseEndPtr = bufferEnd,
isFinal ? (const char **)0 : &bufferPtr);
if (errorCode == XML_ERROR_NONE) {
if (!isFinal)
XmlUpdatePosition(encoding, positionPtr, bufferPtr, &position);
return 1;
}
else {
eventEndPtr = eventPtr;
processor = errorProcessor;
return 0;
}
}
void *XML_GetBuffer(XML_Parser parser, int len)
{
if (len > bufferLim - bufferEnd) {
/* FIXME avoid integer overflow */
int neededSize = len + (bufferEnd - bufferPtr);
#ifdef XML_CONTEXT_BYTES
int keep = bufferPtr - buffer;
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
neededSize += keep;
#endif /* defined XML_CONTEXT_BYTES */
if (neededSize <= bufferLim - buffer) {
#ifdef XML_CONTEXT_BYTES
if (keep < bufferPtr - buffer) {
int offset = (bufferPtr - buffer) - keep;
memmove(buffer, &buffer[offset], bufferEnd - bufferPtr + keep);
bufferEnd -= offset;
bufferPtr -= offset;
}
#else
memmove(buffer, bufferPtr, bufferEnd - bufferPtr);
bufferEnd = buffer + (bufferEnd - bufferPtr);
bufferPtr = buffer;
#endif /* not defined XML_CONTEXT_BYTES */
}
else {
char *newBuf;
int bufferSize = bufferLim - bufferPtr;
if (bufferSize == 0)
bufferSize = INIT_BUFFER_SIZE;
do {
bufferSize *= 2;
} while (bufferSize < neededSize);
newBuf = MALLOC(bufferSize);
if (newBuf == 0) {
errorCode = XML_ERROR_NO_MEMORY;
return 0;
}
bufferLim = newBuf + bufferSize;
#ifdef XML_CONTEXT_BYTES
if (bufferPtr) {
int keep = bufferPtr - buffer;
if (keep > XML_CONTEXT_BYTES)
keep = XML_CONTEXT_BYTES;
memcpy(newBuf, &bufferPtr[-keep], bufferEnd - bufferPtr + keep);
FREE(buffer);
buffer = newBuf;
bufferEnd = buffer + (bufferEnd - bufferPtr) + keep;
bufferPtr = buffer + keep;
}
else {
bufferEnd = newBuf + (bufferEnd - bufferPtr);
bufferPtr = buffer = newBuf;
}
#else
if (bufferPtr) {
memcpy(newBuf, bufferPtr, bufferEnd - bufferPtr);
FREE(buffer);
}
bufferEnd = newBuf + (bufferEnd - bufferPtr);
bufferPtr = buffer = newBuf;
#endif /* not defined XML_CONTEXT_BYTES */
}
}
return bufferEnd;
}
enum XML_Error XML_GetErrorCode(XML_Parser parser)
{
return errorCode;
}
long XML_GetCurrentByteIndex(XML_Parser parser)
{
if (eventPtr)
return parseEndByteIndex - (parseEndPtr - eventPtr);
return -1;
}
int XML_GetCurrentByteCount(XML_Parser parser)
{
if (eventEndPtr && eventPtr)
return eventEndPtr - eventPtr;
return 0;
}
const char * XML_GetInputContext(XML_Parser parser, int *offset, int *size)
{
#ifdef XML_CONTEXT_BYTES
if (eventPtr && buffer) {
*offset = eventPtr - buffer;
*size = bufferEnd - buffer;
return buffer;
}
#endif /* defined XML_CONTEXT_BYTES */
return (char *) 0;
}
int XML_GetCurrentLineNumber(XML_Parser parser)
{
if (eventPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.lineNumber + 1;
}
int XML_GetCurrentColumnNumber(XML_Parser parser)
{
if (eventPtr) {
XmlUpdatePosition(encoding, positionPtr, eventPtr, &position);
positionPtr = eventPtr;
}
return position.columnNumber;
}
void 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 *XML_ErrorString(int code)
{
static const XML_LChar *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 processing instruction not at start of external 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")
};
if (code > 0 && code < sizeof(message)/sizeof(message[0]))
return message[code];
return 0;
}
const XML_LChar *
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("expat_")XML_L(#a)XML_L(".")XML_L(#b)XML_L(".")XML_L(#c)
#define V2(a,b,c) V1(a,b,c)
return V2(XML_MAJOR_VERSION, XML_MINOR_VERSION, XML_MICRO_VERSION);
#undef V1
#undef V2
}
XML_Expat_Version
XML_ExpatVersionInfo(void) {
XML_Expat_Version version;
version.major = XML_MAJOR_VERSION;
version.minor = XML_MINOR_VERSION;
version.micro = XML_MICRO_VERSION;
return version;
}
static
enum XML_Error contentProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
return doContent(parser, 0, encoding, start, end, endPtr);
}
static
enum XML_Error 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 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 && endPtr) {
*endPtr = next;
return XML_ERROR_NONE;
}
start = next;
break;
case XML_TOK_PARTIAL:
if (endPtr) {
*endPtr = start;
return XML_ERROR_NONE;
}
eventPtr = start;
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (endPtr) {
*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 externalEntityInitProcessor3(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_XML_DECL:
{
enum XML_Error result = processXmlDecl(parser, 1, start, next);
if (result != XML_ERROR_NONE)
return result;
start = next;
}
break;
case XML_TOK_PARTIAL:
if (endPtr) {
*endPtr = start;
return XML_ERROR_NONE;
}
eventPtr = start;
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (endPtr) {
*endPtr = start;
return XML_ERROR_NONE;
}
eventPtr = start;
return XML_ERROR_PARTIAL_CHAR;
}
processor = externalEntityContentProcessor;
tagLevel = 1;
return doContent(parser, 1, encoding, start, end, endPtr);
}
static
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 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 = s; /* XmlContentTok doesn't always set the last arg */
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 = 0xA;
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -