xmlparse.c
来自「ARM上的如果你对底层感兴趣」· C语言 代码 · 共 2,269 行 · 第 1/5 页
C
2,269 行
return XML_ERROR_NO_MEMORY;
if ((attId->name)[-1]) {
if (enc == encoding)
eventPtr = atts[i].name;
return XML_ERROR_DUPLICATE_ATTRIBUTE;
}
(attId->name)[-1] = 1;
appAtts[attIndex++] = attId->name;
if (!atts[i].normalized) {
enum XML_Error result;
int isCdata = 1;
if (attId->maybeTokenized) {
int j;
for (j = 0; j < nDefaultAtts; j++) {
if (attId == elementType->defaultAtts[j].id) {
isCdata = elementType->defaultAtts[j].isCdata;
break;
}
}
}
result = storeAttributeValue(parser, enc, isCdata,
atts[i].valuePtr, atts[i].valueEnd,
&tempPool);
if (result)
return result;
if (tagNamePtr) {
appAtts[attIndex] = poolStart(&tempPool);
poolFinish(&tempPool);
}
else
poolDiscard(&tempPool);
}
else if (tagNamePtr) {
appAtts[attIndex] = poolStoreString(&tempPool, enc, atts[i].valuePtr, atts[i].valueEnd);
if (appAtts[attIndex] == 0)
return XML_ERROR_NO_MEMORY;
poolFinish(&tempPool);
}
if (attId->prefix && tagNamePtr) {
if (attId->xmlns) {
if (!addBinding(parser, attId->prefix, attId, appAtts[attIndex], bindingsPtr))
return XML_ERROR_NO_MEMORY;
--attIndex;
}
else {
attIndex++;
nPrefixes++;
(attId->name)[-1] = 2;
}
}
else
attIndex++;
}
if (tagNamePtr) {
int j;
for (j = 0; j < nDefaultAtts; j++) {
const DEFAULT_ATTRIBUTE *da = elementType->defaultAtts + j;
if (!(da->id->name)[-1] && da->value) {
if (da->id->prefix) {
if (da->id->xmlns) {
if (!addBinding(parser, da->id->prefix, da->id, da->value, bindingsPtr))
return XML_ERROR_NO_MEMORY;
}
else {
(da->id->name)[-1] = 2;
nPrefixes++;
appAtts[attIndex++] = da->id->name;
appAtts[attIndex++] = da->value;
}
}
else {
(da->id->name)[-1] = 1;
appAtts[attIndex++] = da->id->name;
appAtts[attIndex++] = da->value;
}
}
}
appAtts[attIndex] = 0;
}
i = 0;
if (nPrefixes) {
for (; i < attIndex; i += 2) {
if (appAtts[i][-1] == 2) {
ATTRIBUTE_ID *id;
((XML_Char *)(appAtts[i]))[-1] = 0;
id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, appAtts[i], 0);
if (id->prefix->binding) {
int j;
const BINDING *b = id->prefix->binding;
const XML_Char *s = appAtts[i];
for (j = 0; j < b->uriLen; j++) {
if (!poolAppendChar(&tempPool, b->uri[j]))
return XML_ERROR_NO_MEMORY;
}
while (*s++ != ':')
;
do {
if (!poolAppendChar(&tempPool, *s))
return XML_ERROR_NO_MEMORY;
} while (*s++);
appAtts[i] = poolStart(&tempPool);
poolFinish(&tempPool);
}
if (!--nPrefixes)
break;
}
else
((XML_Char *)(appAtts[i]))[-1] = 0;
}
}
for (; i < attIndex; i += 2)
((XML_Char *)(appAtts[i]))[-1] = 0;
if (!tagNamePtr)
return XML_ERROR_NONE;
for (binding = *bindingsPtr; binding; binding = binding->nextTagBinding)
binding->attId->name[-1] = 0;
if (elementType->prefix) {
binding = elementType->prefix->binding;
if (!binding)
return XML_ERROR_NONE;
localPart = *tagNamePtr;
while (*localPart++ != XML_T(':'))
;
}
else if (dtd.defaultPrefix.binding) {
binding = dtd.defaultPrefix.binding;
localPart = *tagNamePtr;
}
else
return XML_ERROR_NONE;
i = binding->uriLen;
do {
if (i == binding->uriAlloc) {
binding->uri = realloc(binding->uri, binding->uriAlloc *= 2);
if (!binding->uri)
return XML_ERROR_NO_MEMORY;
}
binding->uri[i++] = *localPart;
} while (*localPart++);
*tagNamePtr = binding->uri;
return XML_ERROR_NONE;
}
static
int addBinding(XML_Parser parser, PREFIX *prefix, const ATTRIBUTE_ID *attId, const XML_Char *uri, BINDING **bindingsPtr)
{
BINDING *b;
int len;
for (len = 0; uri[len]; len++)
;
if (namespaceSeparator)
len++;
if (freeBindingList) {
b = freeBindingList;
if (len > b->uriAlloc) {
b->uri = realloc(b->uri, len + EXPAND_SPARE);
if (!b->uri)
return 0;
b->uriAlloc = len + EXPAND_SPARE;
}
freeBindingList = b->nextTagBinding;
}
else {
b = malloc(sizeof(BINDING));
if (!b)
return 0;
b->uri = malloc(sizeof(XML_Char) * len + EXPAND_SPARE);
if (!b->uri) {
free(b);
return 0;
}
b->uriAlloc = len;
}
b->uriLen = len;
memcpy(b->uri, uri, len * sizeof(XML_Char));
if (namespaceSeparator)
b->uri[len - 1] = namespaceSeparator;
b->prefix = prefix;
b->attId = attId;
b->prevPrefixBinding = b->prefix->binding;
b->prefix->binding = *uri == XML_T('\0') ? 0 : b;
b->nextTagBinding = *bindingsPtr;
*bindingsPtr = b;
return 1;
}
/* The idea here is to avoid using stack for each CDATA section when
the whole file is parsed with one call. */
static
enum XML_Error cdataSectionProcessor(XML_Parser parser,
const char *start,
const char *end,
const char **endPtr)
{
enum XML_Error result = doCdataSection(parser, encoding, &start, end, endPtr);
if (start) {
processor = contentProcessor;
return contentProcessor(parser, start, end, endPtr);
}
return result;
}
/* startPtr gets set to non-null is the section is closed, and to null if
the section is not yet closed. */
static
enum XML_Error doCdataSection(XML_Parser parser,
const ENCODING *enc,
const char **startPtr,
const char *end,
const char **nextPtr)
{
const char *s = *startPtr;
const char **eventPP;
const char **eventEndPP;
if (enc == encoding) {
eventPP = &eventPtr;
*eventPP = s;
eventEndPP = &eventEndPtr;
}
else {
eventPP = &(openInternalEntities->internalEventPtr);
eventEndPP = &(openInternalEntities->internalEventEndPtr);
}
*eventPP = s;
*startPtr = 0;
for (;;) {
const char *next;
int tok = XmlCdataSectionTok(enc, s, end, &next);
*eventEndPP = next;
switch (tok) {
case XML_TOK_CDATA_SECT_CLOSE:
if (characterDataHandler)
characterDataHandler(handlerArg, dataBuf, 0);
else if (defaultHandler)
reportDefault(parser, enc, s, next);
*startPtr = next;
return XML_ERROR_NONE;
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_DATA_CHARS:
if (characterDataHandler) {
if (MUST_CONVERT(enc, s)) {
for (;;) {
ICHAR *dataPtr = (ICHAR *)dataBuf;
XmlConvert(enc, &s, next, &dataPtr, (ICHAR *)dataBufEnd);
*eventEndPP = next;
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_INVALID:
*eventPP = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_PARTIAL_CHAR:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_PARTIAL_CHAR;
case XML_TOK_PARTIAL:
case XML_TOK_NONE:
if (nextPtr) {
*nextPtr = s;
return XML_ERROR_NONE;
}
return XML_ERROR_UNCLOSED_CDATA_SECTION;
default:
abort();
}
*eventPP = s = next;
}
/* not reached */
}
static enum XML_Error
initializeEncoding(XML_Parser parser)
{
const char *s;
#ifdef XML_UNICODE
char encodingBuf[128];
if (!protocolEncodingName)
s = 0;
else {
int i;
for (i = 0; protocolEncodingName[i]; i++) {
if (i == sizeof(encodingBuf) - 1
|| protocolEncodingName[i] >= 0x80
|| protocolEncodingName[i] < 0) {
encodingBuf[0] = '\0';
break;
}
encodingBuf[i] = (char)protocolEncodingName[i];
}
encodingBuf[i] = '\0';
s = encodingBuf;
}
#else
s = protocolEncodingName;
#endif
if ((ns ? XmlInitEncodingNS : XmlInitEncoding)(&initEncoding, &encoding, s))
return XML_ERROR_NONE;
return handleUnknownEncoding(parser, protocolEncodingName);
}
static enum XML_Error
processXmlDecl(XML_Parser parser, int isGeneralTextEntity,
const char *s, const char *next)
{
const char *encodingName = 0;
const ENCODING *newEncoding = 0;
const char *version;
int standalone = -1;
if (!(ns
? XmlParseXmlDeclNS
: XmlParseXmlDecl)(isGeneralTextEntity,
encoding,
s,
next,
&eventPtr,
&version,
&encodingName,
&newEncoding,
&standalone))
return XML_ERROR_SYNTAX;
if (defaultHandler)
reportDefault(parser, encoding, s, next);
if (!protocolEncodingName) {
if (newEncoding) {
if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
eventPtr = encodingName;
return XML_ERROR_INCORRECT_ENCODING;
}
encoding = newEncoding;
}
else if (encodingName) {
enum XML_Error result;
const XML_Char *s = poolStoreString(&tempPool,
encoding,
encodingName,
encodingName
+ XmlNameLength(encoding, encodingName));
if (!s)
return XML_ERROR_NO_MEMORY;
result = handleUnknownEncoding(parser, s);
poolDiscard(&tempPool);
if (result == XML_ERROR_UNKNOWN_ENCODING)
eventPtr = encodingName;
return result;
}
}
if (!isGeneralTextEntity && standalone == 1)
dtd.standalone = 1;
return XML_ERROR_NONE;
}
static enum XML_Error
handleUnknownEncoding(XML_Parser parser, const XML_Char *encodingName)
{
if (unknownEncodingHandler) {
XML_Encoding info;
int i;
for (i = 0; i < 256; i++)
info.map[i] = -1;
info.convert = 0;
info.data = 0;
info.release = 0;
if (unknownEncodingHandler(unknownEncodingHandlerData, encodingName, &info)) {
ENCODING *enc;
unknownEncodingMem = malloc(XmlSizeOfUnknownEncoding());
if (!unknownEncodingMem) {
if (info.release)
info.release(info.data);
return XML_ERROR_NO_MEMORY;
}
enc = (ns
? XmlInitUnknownEncodingNS
: XmlInitUnknownEncoding)(unknownEncodingMem,
info.map,
info.convert,
info.data);
if (enc) {
unknownEncodingData = info.data;
unknownEncodingRelease = info.release;
encoding = enc;
return XML_ERROR_NONE;
}
}
if (info.release)
info.release(info.data);
}
return XML_ERROR_UNKNOWN_ENCODING;
}
static enum XML_Error
prologInitProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
enum XML_Error result = initializeEncoding(parser);
if (result != XML_ERROR_NONE)
return result;
processor = prologProcessor;
return prologProcessor(parser, s, end, nextPtr);
}
static enum XML_Error
prologProcessor(XML_Parser parser,
const char *s,
const char *end,
const char **nextPtr)
{
for (;;) {
const char *next;
int tok = XmlPrologTok(encoding, s, end, &next);
if (tok <= 0) {
if (nextPtr != 0 && tok != XML_TOK_INVALID) {
*nextPtr = s;
return XML_ERROR_NONE;
}
switch (tok) {
case XML_TOK_INVALID:
eventPtr = next;
return XML_ERROR_INVALID_TOKEN;
case XML_TOK_NONE:
return XML_ERROR_NO_ELEMENTS;
case XML_TOK_PARTIAL:
return XML_ERROR_UNCLOSED_TOKEN;
case XML_TOK_PARTIAL_CHAR:
return XML_ERROR_PARTIAL_CHAR;
case XML_TOK_TRAILING_CR:
eventPtr = s + encoding->minBytesPerChar;
return XML_ERROR_NO_ELEMENTS;
default:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?