📄 xmlparse.c
字号:
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 = ptr; return XML_ERROR_BINARY_ENTITY_REF; } else if (!entity->textPtr) { if (enc == encoding) eventPtr = ptr; return XML_ERROR_ATTRIBUTE_EXTERNAL_ENTITY_REF; } else { enum XML_Error result; const XML_Char *textEnd = entity->textPtr + entity->textLen; entity->open = 1; result = appendAttributeValue(parser, internalEnc, isCdata, (char *)entity->textPtr, (char *)textEnd, pool); entity->open = 0; if (result) return result; } } break; default: abort(); } ptr = next; } /* not reached */}staticenum XML_Error storeEntityValue(XML_Parser parser, const char *entityTextPtr, const char *entityTextEnd){ const ENCODING *internalEnc = XmlGetInternalEncoding(); STRING_POOL *pool = &(dtd.pool); entityTextPtr += encoding->minBytesPerChar; entityTextEnd -= encoding->minBytesPerChar; for (;;) { const char *next; int tok = XmlEntityValueTok(encoding, entityTextPtr, entityTextEnd, &next); switch (tok) { case XML_TOK_PARAM_ENTITY_REF: eventPtr = entityTextPtr; return XML_ERROR_SYNTAX; case XML_TOK_NONE: if (declEntity) { declEntity->textPtr = pool->start; declEntity->textLen = pool->ptr - pool->start; poolFinish(pool); } else poolDiscard(pool); return XML_ERROR_NONE; case XML_TOK_ENTITY_REF: case XML_TOK_DATA_CHARS: if (!poolAppend(pool, encoding, entityTextPtr, next)) return XML_ERROR_NO_MEMORY; break; case XML_TOK_TRAILING_CR: next = entityTextPtr + encoding->minBytesPerChar; /* fall through */ case XML_TOK_DATA_NEWLINE: if (pool->end == pool->ptr && !poolGrow(pool)) return XML_ERROR_NO_MEMORY; *(pool->ptr)++ = XML_T('\n'); break; case XML_TOK_CHAR_REF: { XML_Char buf[XML_ENCODE_MAX]; int i; int n = XmlCharRefNumber(encoding, entityTextPtr); if (n < 0) { eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } n = XmlEncode(n, (ICHAR *)buf); if (!n) { eventPtr = entityTextPtr; return XML_ERROR_BAD_CHAR_REF; } for (i = 0; i < n; i++) { if (pool->end == pool->ptr && !poolGrow(pool)) return XML_ERROR_NO_MEMORY; *(pool->ptr)++ = buf[i]; } } break; case XML_TOK_PARTIAL: eventPtr = entityTextPtr; return XML_ERROR_INVALID_TOKEN; case XML_TOK_INVALID: eventPtr = next; return XML_ERROR_INVALID_TOKEN; default: abort(); } entityTextPtr = next; } /* not reached */}static voidnormalizeLines(XML_Char *s){ XML_Char *p; for (;; s++) { if (*s == XML_T('\0')) return; if (*s == XML_T('\r')) break; } p = s; do { if (*s == XML_T('\r')) { *p++ = XML_T('\n'); if (*++s == XML_T('\n')) s++; } else *p++ = *s++; } while (*s); *p = XML_T('\0');}static intreportProcessingInstruction(XML_Parser parser, const ENCODING *enc, const char *start, const char *end){ const XML_Char *target; XML_Char *data; const char *tem; if (!processingInstructionHandler) { if (defaultHandler) reportDefault(parser, enc, start, end); return 1; } start += enc->minBytesPerChar * 2; tem = start + XmlNameLength(enc, start); target = poolStoreString(&tempPool, enc, start, tem); if (!target) return 0; poolFinish(&tempPool); data = poolStoreString(&tempPool, enc, XmlSkipS(enc, tem), end - enc->minBytesPerChar*2); if (!data) return 0; normalizeLines(data); processingInstructionHandler(handlerArg, target, data); poolClear(&tempPool); return 1;}static voidreportDefault(XML_Parser parser, const ENCODING *enc, const char *s, const char *end){ if (MUST_CONVERT(enc, s)) { for (;;) { ICHAR *dataPtr = (ICHAR *)dataBuf; XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd); if (s == end) { defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); break; } if (enc == encoding) { eventEndPtr = s; defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); eventPtr = s; } else defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf); } } else defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);}static intdefineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, int isCdata, const XML_Char *value){ DEFAULT_ATTRIBUTE *att; if (type->nDefaultAtts == type->allocDefaultAtts) { if (type->allocDefaultAtts == 0) { type->allocDefaultAtts = 8; type->defaultAtts = malloc(type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); } else { type->allocDefaultAtts *= 2; type->defaultAtts = realloc(type->defaultAtts, type->allocDefaultAtts*sizeof(DEFAULT_ATTRIBUTE)); } if (!type->defaultAtts) return 0; } att = type->defaultAtts + type->nDefaultAtts; att->id = attId; att->value = value; att->isCdata = isCdata; if (!isCdata) attId->maybeTokenized = 1; type->nDefaultAtts += 1; return 1;}static ATTRIBUTE_ID *getAttributeId(XML_Parser parser, const ENCODING *enc, const char *start, const char *end){ ATTRIBUTE_ID *id; const XML_Char *name; if (!poolAppendChar(&dtd.pool, XML_T('\0'))) return 0; name = poolStoreString(&dtd.pool, enc, start, end); if (!name) return 0; ++name; id = (ATTRIBUTE_ID *)lookup(&dtd.attributeIds, name, sizeof(ATTRIBUTE_ID)); if (!id) return 0; if (id->name != name) poolDiscard(&dtd.pool); else poolFinish(&dtd.pool); return id;}staticconst XML_Char *getOpenEntityNames(XML_Parser parser){ HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(dtd.generalEntities)); for (;;) { const XML_Char *s; ENTITY *e = (ENTITY *)hashTableIterNext(&iter); if (!e) break; if (!e->open) continue; if (poolLength(&tempPool) > 0 && !poolAppendChar(&tempPool, XML_T(' '))) return 0; for (s = e->name; *s; s++) if (!poolAppendChar(&tempPool, *s)) return 0; } if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; return tempPool.start;}staticint setOpenEntityNames(XML_Parser parser, const XML_Char *openEntityNames){ const XML_Char *s = openEntityNames; while (*openEntityNames != XML_T('\0')) { if (*s == XML_T(' ') || *s == XML_T('\0')) { ENTITY *e; if (!poolAppendChar(&tempPool, XML_T('\0'))) return 0; e = (ENTITY *)lookup(&dtd.generalEntities, poolStart(&tempPool), 0); if (e) e->open = 1; if (*s == XML_T(' ')) s++; openEntityNames = s; poolDiscard(&tempPool); } else { if (!poolAppendChar(&tempPool, *s)) return 0; s++; } } return 1;}staticvoid normalizePublicId(XML_Char *publicId){ XML_Char *p = publicId; XML_Char *s; for (s = publicId; *s; s++) { switch (*s) { case XML_T(' '): case XML_T('\r'): case XML_T('\n'): if (p != publicId && p[-1] != XML_T(' ')) *p++ = XML_T(' '); break; default: *p++ = *s; } } if (p != publicId && p[-1] == XML_T(' ')) --p; *p = XML_T('\0');}static int dtdInit(DTD *p){ poolInit(&(p->pool)); hashTableInit(&(p->generalEntities)); hashTableInit(&(p->elementTypes)); hashTableInit(&(p->attributeIds)); p->complete = 1; p->standalone = 0; p->base = 0; return 1;}static void dtdDestroy(DTD *p){ HASH_TABLE_ITER iter; hashTableIterInit(&iter, &(p->elementTypes)); for (;;) { ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (!e) break; if (e->allocDefaultAtts != 0) free(e->defaultAtts); } hashTableDestroy(&(p->generalEntities)); hashTableDestroy(&(p->elementTypes)); hashTableDestroy(&(p->attributeIds)); poolDestroy(&(p->pool));}/* Do a deep copy of the DTD. Return 0 for out of memory; non-zero otherwise.The new DTD has already been initialized. */static int dtdCopy(DTD *newDtd, const DTD *oldDtd){ HASH_TABLE_ITER iter; if (oldDtd->base) { const XML_Char *tem = poolCopyString(&(newDtd->pool), oldDtd->base); if (!tem) return 0; newDtd->base = tem; } hashTableIterInit(&iter, &(oldDtd->attributeIds)); /* Copy the attribute id table. */ for (;;) { ATTRIBUTE_ID *newA; const XML_Char *name; const ATTRIBUTE_ID *oldA = (ATTRIBUTE_ID *)hashTableIterNext(&iter); if (!oldA) break; /* Remember to allocate the scratch byte before the name. */ if (!poolAppendChar(&(newDtd->pool), XML_T('\0'))) return 0; name = poolCopyString(&(newDtd->pool), oldA->name); if (!name) return 0; ++name; newA = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), name, sizeof(ATTRIBUTE_ID)); if (!newA) return 0; newA->maybeTokenized = oldA->maybeTokenized; } /* Copy the element type table. */ hashTableIterInit(&iter, &(oldDtd->elementTypes)); for (;;) { int i; ELEMENT_TYPE *newE; const XML_Char *name; const ELEMENT_TYPE *oldE = (ELEMENT_TYPE *)hashTableIterNext(&iter); if (!oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (!name) return 0; newE = (ELEMENT_TYPE *)lookup(&(newDtd->elementTypes), name, sizeof(ELEMENT_TYPE)); if (!newE) return 0; newE->defaultAtts = (DEFAULT_ATTRIBUTE *)malloc(oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE)); if (!newE->defaultAtts) return 0; newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts; for (i = 0; i < newE->nDefaultAtts; i++) { newE->defaultAtts[i].id = (ATTRIBUTE_ID *)lookup(&(newDtd->attributeIds), oldE->defaultAtts[i].id->name, 0); newE->defaultAtts[i].isCdata = oldE->defaultAtts[i].isCdata; if (oldE->defaultAtts[i].value) { newE->defaultAtts[i].value = poolCopyString(&(newDtd->pool), oldE->defaultAtts[i].value); if (!newE->defaultAtts[i].value) return 0; } else newE->defaultAtts[i].value = 0; } } /* Copy the entity table. */ hashTableIterInit(&iter, &(oldDtd->generalEntities)); for (;;) { ENTITY *newE; const XML_Char *name; const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter); if (!oldE) break; name = poolCopyString(&(newDtd->pool), oldE->name); if (!name) return 0; newE = (ENTITY *)lookup(&(newDtd->generalEntities), name, sizeof(ENTITY)); if (!newE) return 0; if (oldE->systemId) { const XML_Char *tem = poolCopyString(&(newDtd->pool), oldE->systemId); if (!tem) return 0; newE->systemId = tem; if (oldE->base) { if (oldE->base == oldDtd->base) newE->base = newDtd->base; tem = poolCopyString(&(newDtd->pool), oldE->base); if (!tem) return 0; newE->base = tem; } } else { const XML_Char *tem = poolCopyStringN(&(newDtd->pool),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -