xmlparse.c
上传用户:hmc_gdtv
上传日期:2013-08-04
资源大小:798k
文件大小:177k
- &encodingName,
- &newEncoding,
- &standalone))
- return XML_ERROR_SYNTAX;
- if (!isGeneralTextEntity && standalone == 1) {
- _dtd->standalone = XML_TRUE;
- #ifdef XML_DTD
- if (paramEntityParsing == XML_PARAM_ENTITY_PARSING_UNLESS_STANDALONE)
- paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER;
- #endif /* XML_DTD */
- }
- if (xmlDeclHandler) {
- if (encodingName != NULL) {
- storedEncName = poolStoreString(&temp2Pool,
- encoding,
- encodingName,
- encodingName
- + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&temp2Pool);
- }
- if (version) {
- storedversion = poolStoreString(&temp2Pool,
- encoding,
- version,
- versionend - encoding->minBytesPerChar);
- if (!storedversion)
- return XML_ERROR_NO_MEMORY;
- }
- xmlDeclHandler(handlerArg, storedversion, storedEncName, standalone);
- }
- else if (defaultHandler)
- reportDefault(parser, encoding, s, next);
- if (protocolEncodingName == NULL) {
- if (newEncoding) {
- if (newEncoding->minBytesPerChar != encoding->minBytesPerChar) {
- eventPtr = encodingName;
- return XML_ERROR_INCORRECT_ENCODING;
- }
- encoding = newEncoding;
- }
- else if (encodingName) {
- enum XML_Error result;
- if (!storedEncName) {
- storedEncName = poolStoreString(
- &temp2Pool, encoding, encodingName,
- encodingName + XmlNameLength(encoding, encodingName));
- if (!storedEncName)
- return XML_ERROR_NO_MEMORY;
- }
- result = handleUnknownEncoding(parser, storedEncName);
- poolClear(&temp2Pool);
- if (result == XML_ERROR_UNKNOWN_ENCODING)
- eventPtr = encodingName;
- return result;
- }
- }
- if (storedEncName || storedversion)
- poolClear(&temp2Pool);
- 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 = NULL;
- info.data = NULL;
- info.release = NULL;
- 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 != NULL)
- info.release(info.data);
- }
- return XML_ERROR_UNKNOWN_ENCODING;
- }
- static enum XML_Error PTRCALL
- 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);
- }
- #ifdef XML_DTD
- static enum XML_Error PTRCALL
- externalParEntInitProcessor(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;
- /* we know now that XML_Parse(Buffer) has been called,
- so we consider the external parameter entity read */
- _dtd->paramEntityRead = XML_TRUE;
- if (prologState.inEntityValue) {
- processor = entityValueInitProcessor;
- return entityValueInitProcessor(parser, s, end, nextPtr);
- }
- else {
- processor = externalParEntProcessor;
- return externalParEntProcessor(parser, s, end, nextPtr);
- }
- }
- static enum XML_Error PTRCALL
- entityValueInitProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
- {
- const char *start = s;
- const char *next = s;
- int tok;
- for (;;) {
- tok = XmlPrologTok(encoding, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- return storeEntityValue(parser, encoding, s, end);
- }
- else if (tok == XML_TOK_XML_DECL) {
- enum XML_Error result = processXmlDecl(parser, 0, start, next);
- if (result != XML_ERROR_NONE)
- return result;
- if (nextPtr) *nextPtr = next;
- /* stop scanning for text declaration - we found one */
- processor = entityValueProcessor;
- return entityValueProcessor(parser, next, end, nextPtr);
- }
- /* If we are at the end of the buffer, this would cause XmlPrologTok to
- return XML_TOK_NONE on the next call, which would then cause the
- function to exit with *nextPtr set to s - that is what we want for other
- tokens, but not for the BOM - we would rather like to skip it;
- then, when this routine is entered the next time, XmlPrologTok will
- return XML_TOK_INVALID, since the BOM is still in the buffer
- */
- else if (tok == XML_TOK_BOM && next == end && nextPtr) {
- *nextPtr = next;
- return XML_ERROR_NONE;
- }
- start = next;
- }
- }
- static enum XML_Error PTRCALL
- externalParEntProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
- {
- const char *start = s;
- const char *next = s;
- int tok;
- tok = XmlPrologTok(encoding, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- }
- /* This would cause the next stage, i.e. doProlog to be passed XML_TOK_BOM.
- However, when parsing an external subset, doProlog will not accept a BOM
- as valid, and report a syntax error, so we have to skip the BOM
- */
- else if (tok == XML_TOK_BOM) {
- s = next;
- tok = XmlPrologTok(encoding, s, end, &next);
- }
- processor = prologProcessor;
- return doProlog(parser, encoding, s, end, tok, next, nextPtr);
- }
- static enum XML_Error PTRCALL
- entityValueProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
- {
- const char *start = s;
- const char *next = s;
- const ENCODING *enc = encoding;
- int tok;
- for (;;) {
- tok = XmlPrologTok(enc, start, end, &next);
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE: /* start == end */
- default:
- break;
- }
- return storeEntityValue(parser, enc, s, end);
- }
- start = next;
- }
- }
- #endif /* XML_DTD */
- static enum XML_Error PTRCALL
- prologProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
- {
- const char *next = s;
- int tok = XmlPrologTok(encoding, s, end, &next);
- return doProlog(parser, encoding, s, end, tok, next, nextPtr);
- }
- static enum XML_Error
- doProlog(XML_Parser parser,
- const ENCODING *enc,
- const char *s,
- const char *end,
- int tok,
- const char *next,
- const char **nextPtr)
- {
- #ifdef XML_DTD
- static const XML_Char externalSubsetName[] = { '#' , ' ' };
- #endif /* XML_DTD */
- static const XML_Char atypeCDATA[] = { 'C', 'D', 'A', 'T', 'A', ' ' };
- static const XML_Char atypeID[] = { 'I', 'D', ' ' };
- static const XML_Char atypeIDREF[] = { 'I', 'D', 'R', 'E', 'F', ' ' };
- static const XML_Char atypeIDREFS[] = { 'I', 'D', 'R', 'E', 'F', 'S', ' ' };
- static const XML_Char atypeENTITY[] = { 'E', 'N', 'T', 'I', 'T', 'Y', ' ' };
- static const XML_Char atypeENTITIES[] =
- { 'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S', ' ' };
- static const XML_Char atypeNMTOKEN[] = {
- 'N', 'M', 'T', 'O', 'K', 'E', 'N', ' ' };
- static const XML_Char atypeNMTOKENS[] = {
- 'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S', ' ' };
- static const XML_Char notationPrefix[] = {
- 'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N', '(', ' ' };
- static const XML_Char enumValueSep[] = { '|', ' ' };
- static const XML_Char enumValueStart[] = { '(', ' ' };
- DTD * const dtd = _dtd; /* save one level of indirection */
- const char **eventPP;
- const char **eventEndPP;
- enum XML_Content_Quant quant;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- for (;;) {
- int role;
- XML_Bool handleDefault = XML_TRUE;
- *eventPP = s;
- *eventEndPP = next;
- if (tok <= 0) {
- if (nextPtr != 0 && tok != XML_TOK_INVALID) {
- *nextPtr = s;
- return XML_ERROR_NONE;
- }
- switch (tok) {
- case XML_TOK_INVALID:
- *eventPP = next;
- return XML_ERROR_INVALID_TOKEN;
- case XML_TOK_PARTIAL:
- return XML_ERROR_UNCLOSED_TOKEN;
- case XML_TOK_PARTIAL_CHAR:
- return XML_ERROR_PARTIAL_CHAR;
- case XML_TOK_NONE:
- #ifdef XML_DTD
- if (enc != encoding)
- return XML_ERROR_NONE;
- if (isParamEntity) {
- if (XmlTokenRole(&prologState, XML_TOK_NONE, end, end, enc)
- == XML_ROLE_ERROR)
- return XML_ERROR_SYNTAX;
- return XML_ERROR_NONE;
- }
- #endif /* XML_DTD */
- return XML_ERROR_NO_ELEMENTS;
- default:
- tok = -tok;
- next = end;
- break;
- }
- }
- role = XmlTokenRole(&prologState, tok, s, next, enc);
- switch (role) {
- case XML_ROLE_XML_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 0, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_NAME:
- if (startDoctypeDeclHandler) {
- doctypeName = poolStoreString(&tempPool, enc, s, next);
- if (!doctypeName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- doctypePubid = NULL;
- handleDefault = XML_FALSE;
- }
- doctypeSysid = NULL; /* always initialize to NULL */
- break;
- case XML_ROLE_DOCTYPE_INTERNAL_SUBSET:
- if (startDoctypeDeclHandler) {
- startDoctypeDeclHandler(handlerArg, doctypeName, doctypeSysid,
- doctypePubid, 1);
- doctypeName = NULL;
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- #ifdef XML_DTD
- case XML_ROLE_TEXT_DECL:
- {
- enum XML_Error result = processXmlDecl(parser, 1, s, next);
- if (result != XML_ERROR_NONE)
- return result;
- enc = encoding;
- handleDefault = XML_FALSE;
- }
- break;
- #endif /* XML_DTD */
- case XML_ROLE_DOCTYPE_PUBLIC_ID:
- #ifdef XML_DTD
- useForeignDTD = XML_FALSE;
- #endif /* XML_DTD */
- dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypePubid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!doctypePubid)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- #ifdef XML_DTD
- declEntity = (ENTITY *)lookup(&dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- #endif /* XML_DTD */
- /* fall through */
- case XML_ROLE_ENTITY_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_SYNTAX;
- if (dtd->keepProcessing && declEntity) {
- XML_Char *tem = poolStoreString(&dtd->pool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declEntity->publicId = tem;
- poolFinish(&dtd->pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_DOCTYPE_CLOSE:
- if (doctypeName) {
- startDoctypeDeclHandler(handlerArg, doctypeName,
- doctypeSysid, doctypePubid, 0);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- /* doctypeSysid will be non-NULL in the case of a previous
- XML_ROLE_DOCTYPE_SYSTEM_ID, even if startDoctypeDeclHandler
- was not set, indicating an external subset
- */
- #ifdef XML_DTD
- if (doctypeSysid || useForeignDTD) {
- dtd->hasParamEntityRefs = XML_TRUE; /* when docTypeSysid == NULL */
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- if (useForeignDTD)
- entity->base = curBase;
- dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd->paramEntityRead &&
- !dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- /* end of DTD - no need to update dtd->keepProcessing */
- }
- useForeignDTD = XML_FALSE;
- }
- #endif /* XML_DTD */
- if (endDoctypeDeclHandler) {
- endDoctypeDeclHandler(handlerArg);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_INSTANCE_START:
- #ifdef XML_DTD
- /* if there is no DOCTYPE declaration then now is the
- last chance to read the foreign DTD
- */
- if (useForeignDTD) {
- dtd->hasParamEntityRefs = XML_TRUE;
- if (paramEntityParsing && externalEntityRefHandler) {
- ENTITY *entity = (ENTITY *)lookup(&dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!entity)
- return XML_ERROR_NO_MEMORY;
- entity->base = curBase;
- dtd->paramEntityRead = XML_FALSE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId))
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- if (dtd->paramEntityRead &&
- !dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- /* end of DTD - no need to update dtd->keepProcessing */
- }
- }
- #endif /* XML_DTD */
- processor = contentProcessor;
- return contentProcessor(parser, s, end, nextPtr);
- case XML_ROLE_ATTLIST_ELEMENT_NAME:
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_NAME:
- declAttributeId = getAttributeId(parser, enc, s, next);
- if (!declAttributeId)
- return XML_ERROR_NO_MEMORY;
- declAttributeIsCdata = XML_FALSE;
- declAttributeType = NULL;
- declAttributeIsId = XML_FALSE;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_CDATA:
- declAttributeIsCdata = XML_TRUE;
- declAttributeType = atypeCDATA;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ID:
- declAttributeIsId = XML_TRUE;
- declAttributeType = atypeID;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREF:
- declAttributeType = atypeIDREF;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_IDREFS:
- declAttributeType = atypeIDREFS;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITY:
- declAttributeType = atypeENTITY;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_ENTITIES:
- declAttributeType = atypeENTITIES;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKEN:
- declAttributeType = atypeNMTOKEN;
- goto checkAttListDeclHandler;
- case XML_ROLE_ATTRIBUTE_TYPE_NMTOKENS:
- declAttributeType = atypeNMTOKENS;
- checkAttListDeclHandler:
- if (dtd->keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTRIBUTE_ENUM_VALUE:
- case XML_ROLE_ATTRIBUTE_NOTATION_VALUE:
- if (dtd->keepProcessing && attlistDeclHandler) {
- const XML_Char *prefix;
- if (declAttributeType) {
- prefix = enumValueSep;
- }
- else {
- prefix = (role == XML_ROLE_ATTRIBUTE_NOTATION_VALUE
- ? notationPrefix
- : enumValueStart);
- }
- if (!poolAppendString(&tempPool, prefix))
- return XML_ERROR_NO_MEMORY;
- if (!poolAppend(&tempPool, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_IMPLIED_ATTRIBUTE_VALUE:
- case XML_ROLE_REQUIRED_ATTRIBUTE_VALUE:
- if (dtd->keepProcessing) {
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, declAttributeIsId, 0,
- parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T('(')
- || (*declAttributeType == XML_T('N')
- && declAttributeType[1] == XML_T('O'))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(')'))
- || !poolAppendChar(&tempPool, XML_T(' ')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- 0, role == XML_ROLE_REQUIRED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_DEFAULT_ATTRIBUTE_VALUE:
- case XML_ROLE_FIXED_ATTRIBUTE_VALUE:
- if (dtd->keepProcessing) {
- const XML_Char *attVal;
- enum XML_Error result
- = storeAttributeValue(parser, enc, declAttributeIsCdata,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar,
- &dtd->pool);
- if (result)
- return result;
- attVal = poolStart(&dtd->pool);
- poolFinish(&dtd->pool);
- /* ID attributes aren't allowed to have a default */
- if (!defineAttribute(declElementType, declAttributeId,
- declAttributeIsCdata, XML_FALSE, attVal, parser))
- return XML_ERROR_NO_MEMORY;
- if (attlistDeclHandler && declAttributeType) {
- if (*declAttributeType == XML_T('(')
- || (*declAttributeType == XML_T('N')
- && declAttributeType[1] == XML_T('O'))) {
- /* Enumerated or Notation type */
- if (!poolAppendChar(&tempPool, XML_T(')'))
- || !poolAppendChar(&tempPool, XML_T(' ')))
- return XML_ERROR_NO_MEMORY;
- declAttributeType = tempPool.start;
- poolFinish(&tempPool);
- }
- *eventEndPP = s;
- attlistDeclHandler(handlerArg, declElementType->name,
- declAttributeId->name, declAttributeType,
- attVal,
- role == XML_ROLE_FIXED_ATTRIBUTE_VALUE);
- poolClear(&tempPool);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_ENTITY_VALUE:
- if (dtd->keepProcessing) {
- enum XML_Error result = storeEntityValue(parser, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (declEntity) {
- declEntity->textPtr = poolStart(&dtd->entityValuePool);
- declEntity->textLen = poolLength(&dtd->entityValuePool);
- poolFinish(&dtd->entityValuePool);
- if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- declEntity->textPtr,
- declEntity->textLen,
- curBase, 0, 0, 0);
- handleDefault = XML_FALSE;
- }
- }
- else
- poolDiscard(&dtd->entityValuePool);
- if (result != XML_ERROR_NONE)
- return result;
- }
- break;
- case XML_ROLE_DOCTYPE_SYSTEM_ID:
- #ifdef XML_DTD
- useForeignDTD = XML_FALSE;
- #endif /* XML_DTD */
- dtd->hasParamEntityRefs = XML_TRUE;
- if (startDoctypeDeclHandler) {
- doctypeSysid = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (doctypeSysid == NULL)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- #ifdef XML_DTD
- else
- /* use externalSubsetName to make doctypeSysid non-NULL
- for the case where no startDoctypeDeclHandler is set */
- doctypeSysid = externalSubsetName;
- #endif /* XML_DTD */
- if (!dtd->standalone
- #ifdef XML_DTD
- && !paramEntityParsing
- #endif /* XML_DTD */
- && notStandaloneHandler
- && !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- #ifndef XML_DTD
- break;
- #else /* XML_DTD */
- if (!declEntity) {
- declEntity = (ENTITY *)lookup(&dtd->paramEntities,
- externalSubsetName,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- declEntity->publicId = NULL;
- }
- /* fall through */
- #endif /* XML_DTD */
- case XML_ROLE_ENTITY_SYSTEM_ID:
- if (dtd->keepProcessing && declEntity) {
- declEntity->systemId = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!declEntity->systemId)
- return XML_ERROR_NO_MEMORY;
- declEntity->base = curBase;
- poolFinish(&dtd->pool);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_COMPLETE:
- if (dtd->keepProcessing && declEntity && entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->is_param,
- 0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- 0);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_ENTITY_NOTATION_NAME:
- if (dtd->keepProcessing && declEntity) {
- declEntity->notation = poolStoreString(&dtd->pool, enc, s, next);
- if (!declEntity->notation)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&dtd->pool);
- if (unparsedEntityDeclHandler) {
- *eventEndPP = s;
- unparsedEntityDeclHandler(handlerArg,
- declEntity->name,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- else if (entityDeclHandler) {
- *eventEndPP = s;
- entityDeclHandler(handlerArg,
- declEntity->name,
- 0,0,0,
- declEntity->base,
- declEntity->systemId,
- declEntity->publicId,
- declEntity->notation);
- handleDefault = XML_FALSE;
- }
- }
- break;
- case XML_ROLE_GENERAL_ENTITY_NAME:
- {
- if (XmlPredefinedEntityName(enc, s, next)) {
- declEntity = NULL;
- break;
- }
- if (dtd->keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(&dtd->generalEntities, name,
- sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_FALSE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- }
- break;
- case XML_ROLE_PARAM_ENTITY_NAME:
- #ifdef XML_DTD
- if (dtd->keepProcessing) {
- const XML_Char *name = poolStoreString(&dtd->pool, enc, s, next);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- declEntity = (ENTITY *)lookup(&dtd->paramEntities,
- name, sizeof(ENTITY));
- if (!declEntity)
- return XML_ERROR_NO_MEMORY;
- if (declEntity->name != name) {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- else {
- poolFinish(&dtd->pool);
- declEntity->publicId = NULL;
- declEntity->is_param = XML_TRUE;
- /* if we have a parent parser or are reading an internal parameter
- entity, then the entity declaration is not considered "internal"
- */
- declEntity->is_internal = !(parentParser || openInternalEntities);
- if (entityDeclHandler)
- handleDefault = XML_FALSE;
- }
- }
- else {
- poolDiscard(&dtd->pool);
- declEntity = NULL;
- }
- #else /* not XML_DTD */
- declEntity = NULL;
- #endif /* XML_DTD */
- break;
- case XML_ROLE_NOTATION_NAME:
- declNotationPublicId = NULL;
- declNotationName = NULL;
- if (notationDeclHandler) {
- declNotationName = poolStoreString(&tempPool, enc, s, next);
- if (!declNotationName)
- return XML_ERROR_NO_MEMORY;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_PUBLIC_ID:
- if (!XmlIsPublicId(enc, s, next, eventPP))
- return XML_ERROR_SYNTAX;
- if (declNotationName) { /* means notationDeclHandler != NULL */
- XML_Char *tem = poolStoreString(&tempPool,
- enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!tem)
- return XML_ERROR_NO_MEMORY;
- normalizePublicId(tem);
- declNotationPublicId = tem;
- poolFinish(&tempPool);
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_NOTATION_SYSTEM_ID:
- if (declNotationName && notationDeclHandler) {
- const XML_Char *systemId
- = poolStoreString(&tempPool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!systemId)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- systemId,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_NOTATION_NO_SYSTEM_ID:
- if (declNotationPublicId && notationDeclHandler) {
- *eventEndPP = s;
- notationDeclHandler(handlerArg,
- declNotationName,
- curBase,
- 0,
- declNotationPublicId);
- handleDefault = XML_FALSE;
- }
- poolClear(&tempPool);
- break;
- case XML_ROLE_ERROR:
- 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;
- }
- #ifdef XML_DTD
- case XML_ROLE_IGNORE_SECT:
- {
- enum XML_Error result;
- if (defaultHandler)
- reportDefault(parser, enc, s, next);
- handleDefault = XML_FALSE;
- result = doIgnoreSection(parser, enc, &next, end, nextPtr);
- if (!next) {
- processor = ignoreSectionProcessor;
- return result;
- }
- }
- break;
- #endif /* XML_DTD */
- case XML_ROLE_GROUP_OPEN:
- if (prologState.level >= groupSize) {
- if (groupSize) {
- char *temp = (char *)REALLOC(groupConnector, groupSize *= 2);
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- groupConnector = temp;
- if (dtd->scaffIndex) {
- int *temp = (int *)REALLOC(dtd->scaffIndex,
- groupSize * sizeof(int));
- if (temp == NULL)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffIndex = temp;
- }
- }
- else {
- groupConnector = (char *)MALLOC(groupSize = 32);
- if (!groupConnector)
- return XML_ERROR_NO_MEMORY;
- }
- }
- groupConnector[prologState.level] = 0;
- if (dtd->in_eldecl) {
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffIndex[dtd->scaffLevel] = myindex;
- dtd->scaffLevel++;
- dtd->scaffold[myindex].type = XML_CTYPE_SEQ;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_GROUP_SEQUENCE:
- if (groupConnector[prologState.level] == '|')
- return XML_ERROR_SYNTAX;
- groupConnector[prologState.level] = ',';
- if (dtd->in_eldecl && elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_GROUP_CHOICE:
- if (groupConnector[prologState.level] == ',')
- return XML_ERROR_SYNTAX;
- if (dtd->in_eldecl
- && !groupConnector[prologState.level]
- && (dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- != XML_CTYPE_MIXED)
- ) {
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- = XML_CTYPE_CHOICE;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- groupConnector[prologState.level] = '|';
- break;
- case XML_ROLE_PARAM_ENTITY_REF:
- #ifdef XML_DTD
- case XML_ROLE_INNER_PARAM_ENTITY_REF:
- /* PE references in internal subset are
- not allowed within declarations */
- if (prologState.documentEntity &&
- role == XML_ROLE_INNER_PARAM_ENTITY_REF)
- return XML_ERROR_PARAM_ENTITY_REF;
- dtd->hasParamEntityRefs = XML_TRUE;
- if (!paramEntityParsing)
- dtd->keepProcessing = dtd->standalone;
- else {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&dtd->pool, enc,
- s + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name)
- return XML_ERROR_NO_MEMORY;
- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
- poolDiscard(&dtd->pool);
- /* first, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the skipped entity handler
- */
- if (prologState.documentEntity &&
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs)) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- dtd->keepProcessing = dtd->standalone;
- /* cannot report skipped entities in declarations */
- if ((role == XML_ROLE_PARAM_ENTITY_REF) && skippedEntityHandler) {
- skippedEntityHandler(handlerArg, name, 1);
- handleDefault = XML_FALSE;
- }
- break;
- }
- if (entity->open)
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- if (entity->textPtr) {
- enum XML_Error result;
- result = processInternalParamEntity(parser, entity);
- if (result != XML_ERROR_NONE)
- return result;
- handleDefault = XML_FALSE;
- break;
- }
- if (externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- return XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- }
- entity->open = XML_FALSE;
- handleDefault = XML_FALSE;
- if (!dtd->paramEntityRead) {
- dtd->keepProcessing = dtd->standalone;
- break;
- }
- }
- else {
- dtd->keepProcessing = dtd->standalone;
- break;
- }
- }
- #endif /* XML_DTD */
- if (!dtd->standalone &&
- notStandaloneHandler &&
- !notStandaloneHandler(handlerArg))
- return XML_ERROR_NOT_STANDALONE;
- break;
- /* Element declaration stuff */
- case XML_ROLE_ELEMENT_NAME:
- if (elementDeclHandler) {
- declElementType = getElementType(parser, enc, s, next);
- if (!declElementType)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffLevel = 0;
- dtd->scaffCount = 0;
- dtd->in_eldecl = XML_TRUE;
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_CONTENT_ANY:
- case XML_ROLE_CONTENT_EMPTY:
- if (dtd->in_eldecl) {
- if (elementDeclHandler) {
- XML_Content * content = (XML_Content *) MALLOC(sizeof(XML_Content));
- if (!content)
- return XML_ERROR_NO_MEMORY;
- content->quant = XML_CQUANT_NONE;
- content->name = NULL;
- content->numchildren = 0;
- content->children = NULL;
- content->type = ((role == XML_ROLE_CONTENT_ANY) ?
- XML_CTYPE_ANY :
- XML_CTYPE_EMPTY);
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, content);
- handleDefault = XML_FALSE;
- }
- dtd->in_eldecl = XML_FALSE;
- }
- break;
- case XML_ROLE_CONTENT_PCDATA:
- if (dtd->in_eldecl) {
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel - 1]].type
- = XML_CTYPE_MIXED;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_CONTENT_ELEMENT:
- quant = XML_CQUANT_NONE;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_OPT:
- quant = XML_CQUANT_OPT;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_REP:
- quant = XML_CQUANT_REP;
- goto elementContent;
- case XML_ROLE_CONTENT_ELEMENT_PLUS:
- quant = XML_CQUANT_PLUS;
- elementContent:
- if (dtd->in_eldecl) {
- ELEMENT_TYPE *el;
- const XML_Char *name;
- int nameLen;
- const char *nxt = (quant == XML_CQUANT_NONE
- ? next
- : next - enc->minBytesPerChar);
- int myindex = nextScaffoldPart(parser);
- if (myindex < 0)
- return XML_ERROR_NO_MEMORY;
- dtd->scaffold[myindex].type = XML_CTYPE_NAME;
- dtd->scaffold[myindex].quant = quant;
- el = getElementType(parser, enc, s, nxt);
- if (!el)
- return XML_ERROR_NO_MEMORY;
- name = el->name;
- dtd->scaffold[myindex].name = name;
- nameLen = 0;
- for (; name[nameLen++]; );
- dtd->contentStringLen += nameLen;
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- }
- break;
- case XML_ROLE_GROUP_CLOSE:
- quant = XML_CQUANT_NONE;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_OPT:
- quant = XML_CQUANT_OPT;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_REP:
- quant = XML_CQUANT_REP;
- goto closeGroup;
- case XML_ROLE_GROUP_CLOSE_PLUS:
- quant = XML_CQUANT_PLUS;
- closeGroup:
- if (dtd->in_eldecl) {
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- dtd->scaffLevel--;
- dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel]].quant = quant;
- if (dtd->scaffLevel == 0) {
- if (!handleDefault) {
- XML_Content *model = build_model(parser);
- if (!model)
- return XML_ERROR_NO_MEMORY;
- *eventEndPP = s;
- elementDeclHandler(handlerArg, declElementType->name, model);
- }
- dtd->in_eldecl = XML_FALSE;
- dtd->contentStringLen = 0;
- }
- }
- break;
- /* End element declaration stuff */
- case XML_ROLE_PI:
- if (!reportProcessingInstruction(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_COMMENT:
- if (!reportComment(parser, enc, s, next))
- return XML_ERROR_NO_MEMORY;
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NONE:
- switch (tok) {
- case XML_TOK_BOM:
- handleDefault = XML_FALSE;
- break;
- }
- break;
- case XML_ROLE_DOCTYPE_NONE:
- if (startDoctypeDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ENTITY_NONE:
- if (dtd->keepProcessing && entityDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_NOTATION_NONE:
- if (notationDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ATTLIST_NONE:
- if (dtd->keepProcessing && attlistDeclHandler)
- handleDefault = XML_FALSE;
- break;
- case XML_ROLE_ELEMENT_NONE:
- if (elementDeclHandler)
- handleDefault = XML_FALSE;
- break;
- } /* end of big switch */
- if (handleDefault && defaultHandler)
- reportDefault(parser, enc, s, next);
- s = next;
- tok = XmlPrologTok(enc, s, end, &next);
- }
- /* not reached */
- }
- static enum XML_Error PTRCALL
- epilogProcessor(XML_Parser parser,
- const char *s,
- const char *end,
- const char **nextPtr)
- {
- processor = epilogProcessor;
- eventPtr = s;
- for (;;) {
- const char *next = NULL;
- int tok = XmlPrologTok(encoding, s, end, &next);
- eventEndPtr = next;
- switch (tok) {
- /* report partial linebreak - it might be the last token */
- case -XML_TOK_PROLOG_S:
- if (defaultHandler) {
- eventEndPtr = next;
- reportDefault(parser, encoding, s, next);
- }
- if (nextPtr)
- *nextPtr = next;
- return XML_ERROR_NONE;
- case XML_TOK_NONE:
- if (nextPtr)
- *nextPtr = s;
- 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;
- }
- }
- #ifdef XML_DTD
- static enum XML_Error
- processInternalParamEntity(XML_Parser parser, ENTITY *entity)
- {
- const char *s, *end, *next;
- int tok;
- enum XML_Error result;
- OPEN_INTERNAL_ENTITY openEntity;
- entity->open = XML_TRUE;
- openEntity.next = openInternalEntities;
- openInternalEntities = &openEntity;
- openEntity.entity = entity;
- openEntity.internalEventPtr = NULL;
- openEntity.internalEventEndPtr = NULL;
- s = (char *)entity->textPtr;
- end = (char *)(entity->textPtr + entity->textLen);
- tok = XmlPrologTok(internalEncoding, s, end, &next);
- result = doProlog(parser, internalEncoding, s, end, tok, next, 0);
- entity->open = XML_FALSE;
- openInternalEntities = openEntity.next;
- return result;
- }
- #endif /* XML_DTD */
- static enum XML_Error PTRCALL
- 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, XML_Bool 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) == 0x20)
- poolChop(pool);
- if (!poolAppendChar(pool, XML_T(' ')))
- return XML_ERROR_NO_MEMORY;
- return XML_ERROR_NONE;
- }
- static enum XML_Error
- appendAttributeValue(XML_Parser parser, const ENCODING *enc, XML_Bool isCdata,
- const char *ptr, const char *end,
- STRING_POOL *pool)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- 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) == 0x20))
- 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;
- 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) == 0x20))
- break;
- if (!poolAppendChar(pool, 0x20))
- return XML_ERROR_NO_MEMORY;
- break;
- case XML_TOK_ENTITY_REF:
- {
- const XML_Char *name;
- ENTITY *entity;
- char checkEntityDecl;
- XML_Char ch = (XML_Char) 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);
- /* first, determine if a check for an existing declaration is needed;
- if yes, check that the entity exists, and that it is internal,
- otherwise call the default handler (if called from content)
- */
- if (pool == &dtd->pool) /* are we called from prolog? */
- checkEntityDecl =
- #ifdef XML_DTD
- prologState.documentEntity &&
- #endif /* XML_DTD */
- (dtd->standalone
- ? !openInternalEntities
- : !dtd->hasParamEntityRefs);
- else /* if (pool == &tempPool): we are called from content */
- checkEntityDecl = !dtd->hasParamEntityRefs || dtd->standalone;
- if (checkEntityDecl) {
- if (!entity)
- return XML_ERROR_UNDEFINED_ENTITY;
- else if (!entity->is_internal)
- return XML_ERROR_ENTITY_DECLARED_IN_PE;
- }
- else if (!entity) {
- /* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- if ((pool == &tempPool) && defaultHandler)
- reportDefault(parser, enc, ptr, next);
- break;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_RECURSIVE_ENTITY_REF;
- }
- if (entity->notation) {
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_BINARY_ENTITY_REF;
- }
- 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 = XML_TRUE;
- result = appendAttributeValue(parser, internalEncoding, isCdata,
- (char *)entity->textPtr,
- (char *)textEnd, pool);
- entity->open = XML_FALSE;
- if (result)
- return result;
- }
- }
- break;
- default:
- if (enc == encoding)
- eventPtr = ptr;
- return XML_ERROR_UNEXPECTED_STATE;
- }
- ptr = next;
- }
- /* not reached */
- }
- static enum XML_Error
- storeEntityValue(XML_Parser parser,
- const ENCODING *enc,
- const char *entityTextPtr,
- const char *entityTextEnd)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- STRING_POOL *pool = &(dtd->entityValuePool);
- enum XML_Error result = XML_ERROR_NONE;
- #ifdef XML_DTD
- int oldInEntityValue = prologState.inEntityValue;
- prologState.inEntityValue = 1;
- #endif /* XML_DTD */
- /* never return Null for the value argument in EntityDeclHandler,
- since this would indicate an external entity; therefore we
- have to make sure that entityValuePool.start is not null */
- if (!pool->blocks) {
- if (!poolGrow(pool))
- return XML_ERROR_NO_MEMORY;
- }
- for (;;) {
- const char *next;
- int tok = XmlEntityValueTok(enc, entityTextPtr, entityTextEnd, &next);
- switch (tok) {
- case XML_TOK_PARAM_ENTITY_REF:
- #ifdef XML_DTD
- if (isParamEntity || enc != encoding) {
- const XML_Char *name;
- ENTITY *entity;
- name = poolStoreString(&tempPool, enc,
- entityTextPtr + enc->minBytesPerChar,
- next - enc->minBytesPerChar);
- if (!name) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- entity = (ENTITY *)lookup(&dtd->paramEntities, name, 0);
- poolDiscard(&tempPool);
- if (!entity) {
- /* not a well-formedness error - see XML 1.0: WFC Entity Declared */
- /* cannot report skipped entity here - see comments on
- skippedEntityHandler
- if (skippedEntityHandler)
- skippedEntityHandler(handlerArg, name, 0);
- */
- dtd->keepProcessing = dtd->standalone;
- goto endEntityValue;
- }
- if (entity->open) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_RECURSIVE_ENTITY_REF;
- goto endEntityValue;
- }
- if (entity->systemId) {
- if (externalEntityRefHandler) {
- dtd->paramEntityRead = XML_FALSE;
- entity->open = XML_TRUE;
- if (!externalEntityRefHandler(externalEntityRefHandlerArg,
- 0,
- entity->base,
- entity->systemId,
- entity->publicId)) {
- entity->open = XML_FALSE;
- result = XML_ERROR_EXTERNAL_ENTITY_HANDLING;
- goto endEntityValue;
- }
- entity->open = XML_FALSE;
- if (!dtd->paramEntityRead)
- dtd->keepProcessing = dtd->standalone;
- }
- else
- dtd->keepProcessing = dtd->standalone;
- }
- else {
- entity->open = XML_TRUE;
- result = storeEntityValue(parser,
- internalEncoding,
- (char *)entity->textPtr,
- (char *)(entity->textPtr
- + entity->textLen));
- entity->open = XML_FALSE;
- if (result)
- goto endEntityValue;
- }
- break;
- }
- #endif /* XML_DTD */
- /* in the internal subset, PE references are not legal
- within markup declarations, e.g entity values in this case */
- eventPtr = entityTextPtr;
- result = XML_ERROR_PARAM_ENTITY_REF;
- goto endEntityValue;
- case XML_TOK_NONE:
- result = XML_ERROR_NONE;
- goto endEntityValue;
- case XML_TOK_ENTITY_REF:
- case XML_TOK_DATA_CHARS:
- if (!poolAppend(pool, enc, entityTextPtr, next)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- break;
- case XML_TOK_TRAILING_CR:
- next = entityTextPtr + enc->minBytesPerChar;
- /* fall through */
- case XML_TOK_DATA_NEWLINE:
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = 0xA;
- break;
- case XML_TOK_CHAR_REF:
- {
- XML_Char buf[XML_ENCODE_MAX];
- int i;
- int n = XmlCharRefNumber(enc, entityTextPtr);
- if (n < 0) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- n = XmlEncode(n, (ICHAR *)buf);
- if (!n) {
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_BAD_CHAR_REF;
- goto endEntityValue;
- }
- for (i = 0; i < n; i++) {
- if (pool->end == pool->ptr && !poolGrow(pool)) {
- result = XML_ERROR_NO_MEMORY;
- goto endEntityValue;
- }
- *(pool->ptr)++ = buf[i];
- }
- }
- break;
- case XML_TOK_PARTIAL:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- case XML_TOK_INVALID:
- if (enc == encoding)
- eventPtr = next;
- result = XML_ERROR_INVALID_TOKEN;
- goto endEntityValue;
- default:
- if (enc == encoding)
- eventPtr = entityTextPtr;
- result = XML_ERROR_UNEXPECTED_STATE;
- goto endEntityValue;
- }
- entityTextPtr = next;
- }
- endEntityValue:
- #ifdef XML_DTD
- prologState.inEntityValue = oldInEntityValue;
- #endif /* XML_DTD */
- return result;
- }
- static void FASTCALL
- normalizeLines(XML_Char *s)
- {
- XML_Char *p;
- for (;; s++) {
- if (*s == XML_T(' '))
- return;
- if (*s == 0xD)
- break;
- }
- p = s;
- do {
- if (*s == 0xD) {
- *p++ = 0xA;
- if (*++s == 0xA)
- s++;
- }
- else
- *p++ = *s++;
- } while (*s);
- *p = XML_T(' ');
- }
- static int
- reportProcessingInstruction(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 int
- reportComment(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
- {
- XML_Char *data;
- if (!commentHandler) {
- if (defaultHandler)
- reportDefault(parser, enc, start, end);
- return 1;
- }
- data = poolStoreString(&tempPool,
- enc,
- start + enc->minBytesPerChar * 4,
- end - enc->minBytesPerChar * 3);
- if (!data)
- return 0;
- normalizeLines(data);
- commentHandler(handlerArg, data);
- poolClear(&tempPool);
- return 1;
- }
- static void
- reportDefault(XML_Parser parser, const ENCODING *enc,
- const char *s, const char *end)
- {
- if (MUST_CONVERT(enc, s)) {
- const char **eventPP;
- const char **eventEndPP;
- if (enc == encoding) {
- eventPP = &eventPtr;
- eventEndPP = &eventEndPtr;
- }
- else {
- eventPP = &(openInternalEntities->internalEventPtr);
- eventEndPP = &(openInternalEntities->internalEventEndPtr);
- }
- do {
- ICHAR *dataPtr = (ICHAR *)dataBuf;
- XmlConvert(enc, &s, end, &dataPtr, (ICHAR *)dataBufEnd);
- *eventEndPP = s;
- defaultHandler(handlerArg, dataBuf, dataPtr - (ICHAR *)dataBuf);
- *eventPP = s;
- } while (s != end);
- }
- else
- defaultHandler(handlerArg, (XML_Char *)s, (XML_Char *)end - (XML_Char *)s);
- }
- static int
- defineAttribute(ELEMENT_TYPE *type, ATTRIBUTE_ID *attId, XML_Bool isCdata,
- XML_Bool isId, const XML_Char *value, XML_Parser parser)
- {
- DEFAULT_ATTRIBUTE *att;
- if (value || isId) {
- /* The handling of default attributes gets messed up if we have
- a default which duplicates a non-default. */
- int i;
- for (i = 0; i < type->nDefaultAtts; i++)
- if (attId == type->defaultAtts[i].id)
- return 1;
- if (isId && !type->idAtt && !attId->xmlns)
- type->idAtt = attId;
- }
- if (type->nDefaultAtts == type->allocDefaultAtts) {
- if (type->allocDefaultAtts == 0) {
- type->allocDefaultAtts = 8;
- type->defaultAtts = (DEFAULT_ATTRIBUTE *)MALLOC(type->allocDefaultAtts
- * sizeof(DEFAULT_ATTRIBUTE));
- if (!type->defaultAtts)
- return 0;
- }
- else {
- DEFAULT_ATTRIBUTE *temp;
- int count = type->allocDefaultAtts * 2;
- temp = (DEFAULT_ATTRIBUTE *)
- REALLOC(type->defaultAtts, (count * sizeof(DEFAULT_ATTRIBUTE)));
- if (temp == NULL)
- return 0;
- type->allocDefaultAtts = count;
- type->defaultAtts = temp;
- }
- }
- att = type->defaultAtts + type->nDefaultAtts;
- att->id = attId;
- att->value = value;
- att->isCdata = isCdata;
- if (!isCdata)
- attId->maybeTokenized = XML_TRUE;
- type->nDefaultAtts += 1;
- return 1;
- }
- static int
- setElementTypePrefix(XML_Parser parser, ELEMENT_TYPE *elementType)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *name;
- for (name = elementType->name; *name; name++) {
- if (*name == XML_T(':')) {
- PREFIX *prefix;
- const XML_Char *s;
- for (s = elementType->name; s != name; s++) {
- if (!poolAppendChar(&dtd->pool, *s))
- return 0;
- }
- if (!poolAppendChar(&dtd->pool, XML_T(' ')))
- return 0;
- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
- sizeof(PREFIX));
- if (!prefix)
- return 0;
- if (prefix->name == poolStart(&dtd->pool))
- poolFinish(&dtd->pool);
- else
- poolDiscard(&dtd->pool);
- elementType->prefix = prefix;
- }
- }
- return 1;
- }
- static ATTRIBUTE_ID *
- getAttributeId(XML_Parser parser, const ENCODING *enc,
- const char *start, const char *end)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- ATTRIBUTE_ID *id;
- const XML_Char *name;
- if (!poolAppendChar(&dtd->pool, XML_T(' ')))
- return NULL;
- name = poolStoreString(&dtd->pool, enc, start, end);
- if (!name)
- return NULL;
- ++name;
- id = (ATTRIBUTE_ID *)lookup(&dtd->attributeIds, name, sizeof(ATTRIBUTE_ID));
- if (!id)
- return NULL;
- if (id->name != name)
- poolDiscard(&dtd->pool);
- else {
- poolFinish(&dtd->pool);
- if (!ns)
- ;
- else if (name[0] == XML_T('x')
- && name[1] == XML_T('m')
- && name[2] == XML_T('l')
- && name[3] == XML_T('n')
- && name[4] == XML_T('s')
- && (name[5] == XML_T(' ') || name[5] == XML_T(':'))) {
- if (name[5] == XML_T(' '))
- id->prefix = &dtd->defaultPrefix;
- else
- id->prefix = (PREFIX *)lookup(&dtd->prefixes, name + 6, sizeof(PREFIX));
- id->xmlns = XML_TRUE;
- }
- else {
- int i;
- for (i = 0; name[i]; i++) {
- if (name[i] == XML_T(':')) {
- int j;
- for (j = 0; j < i; j++) {
- if (!poolAppendChar(&dtd->pool, name[j]))
- return NULL;
- }
- if (!poolAppendChar(&dtd->pool, XML_T(' ')))
- return NULL;
- id->prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&dtd->pool),
- sizeof(PREFIX));
- if (id->prefix->name == poolStart(&dtd->pool))
- poolFinish(&dtd->pool);
- else
- poolDiscard(&dtd->pool);
- break;
- }
- }
- }
- }
- return id;
- }
- #define CONTEXT_SEP XML_T('f')
- static const XML_Char *
- getContext(XML_Parser parser)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- HASH_TABLE_ITER iter;
- XML_Bool needSep = XML_FALSE;
- if (dtd->defaultPrefix.binding) {
- int i;
- int len;
- if (!poolAppendChar(&tempPool, XML_T('=')))
- return NULL;
- len = dtd->defaultPrefix.binding->uriLen;
- if (namespaceSeparator != XML_T(' '))
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, dtd->defaultPrefix.binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
- hashTableIterInit(&iter, &(dtd->prefixes));
- for (;;) {
- int i;
- int len;
- const XML_Char *s;
- PREFIX *prefix = (PREFIX *)hashTableIterNext(&iter);
- if (!prefix)
- break;
- if (!prefix->binding)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = prefix->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return NULL;
- if (!poolAppendChar(&tempPool, XML_T('=')))
- return NULL;
- len = prefix->binding->uriLen;
- if (namespaceSeparator != XML_T(' '))
- len--;
- for (i = 0; i < len; i++)
- if (!poolAppendChar(&tempPool, prefix->binding->uri[i]))
- return NULL;
- needSep = XML_TRUE;
- }
- hashTableIterInit(&iter, &(dtd->generalEntities));
- for (;;) {
- const XML_Char *s;
- ENTITY *e = (ENTITY *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (!e->open)
- continue;
- if (needSep && !poolAppendChar(&tempPool, CONTEXT_SEP))
- return NULL;
- for (s = e->name; *s; s++)
- if (!poolAppendChar(&tempPool, *s))
- return 0;
- needSep = XML_TRUE;
- }
- if (!poolAppendChar(&tempPool, XML_T(' ')))
- return NULL;
- return tempPool.start;
- }
- static XML_Bool
- setContext(XML_Parser parser, const XML_Char *context)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *s = context;
- while (*context != XML_T(' ')) {
- if (*s == CONTEXT_SEP || *s == XML_T(' ')) {
- ENTITY *e;
- if (!poolAppendChar(&tempPool, XML_T(' ')))
- return XML_FALSE;
- e = (ENTITY *)lookup(&dtd->generalEntities, poolStart(&tempPool), 0);
- if (e)
- e->open = XML_TRUE;
- if (*s != XML_T(' '))
- s++;
- context = s;
- poolDiscard(&tempPool);
- }
- else if (*s == XML_T('=')) {
- PREFIX *prefix;
- if (poolLength(&tempPool) == 0)
- prefix = &dtd->defaultPrefix;
- else {
- if (!poolAppendChar(&tempPool, XML_T(' ')))
- return XML_FALSE;
- prefix = (PREFIX *)lookup(&dtd->prefixes, poolStart(&tempPool),
- sizeof(PREFIX));
- if (!prefix)
- return XML_FALSE;
- if (prefix->name == poolStart(&tempPool)) {
- prefix->name = poolCopyString(&dtd->pool, prefix->name);
- if (!prefix->name)
- return XML_FALSE;
- }
- poolDiscard(&tempPool);
- }
- for (context = s + 1;
- *context != CONTEXT_SEP && *context != XML_T(' ');
- context++)
- if (!poolAppendChar(&tempPool, *context))
- return XML_FALSE;
- if (!poolAppendChar(&tempPool, XML_T(' ')))
- return XML_FALSE;
- if (!addBinding(parser, prefix, 0, poolStart(&tempPool),
- &inheritedBindings))
- return XML_FALSE;
- poolDiscard(&tempPool);
- if (*context != XML_T(' '))
- ++context;
- s = context;
- }
- else {
- if (!poolAppendChar(&tempPool, *s))
- return XML_FALSE;
- s++;
- }
- }
- return XML_TRUE;
- }
- static void FASTCALL
- normalizePublicId(XML_Char *publicId)
- {
- XML_Char *p = publicId;
- XML_Char *s;
- for (s = publicId; *s; s++) {
- switch (*s) {
- case 0x20:
- case 0xD:
- case 0xA:
- if (p != publicId && p[-1] != 0x20)
- *p++ = 0x20;
- break;
- default:
- *p++ = *s;
- }
- }
- if (p != publicId && p[-1] == 0x20)
- --p;
- *p = XML_T(' ');
- }
- static DTD *
- dtdCreate(const XML_Memory_Handling_Suite *ms)
- {
- DTD *p = (DTD *)ms->malloc_fcn(ms->priv,sizeof(DTD));
- if (p == NULL)
- return p;
- poolInit(&(p->pool), ms);
- #ifdef XML_DTD
- poolInit(&(p->entityValuePool), ms);
- #endif /* XML_DTD */
- hashTableInit(&(p->generalEntities), ms);
- hashTableInit(&(p->elementTypes), ms);
- hashTableInit(&(p->attributeIds), ms);
- hashTableInit(&(p->prefixes), ms);
- #ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableInit(&(p->paramEntities), ms);
- #endif /* XML_DTD */
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
- p->in_eldecl = XML_FALSE;
- p->scaffIndex = NULL;
- p->scaffold = NULL;
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
- return p;
- }
- static void
- dtdReset(DTD *p, const XML_Memory_Handling_Suite *ms)
- {
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- ms->free_fcn(ms->priv,e->defaultAtts);
- }
- hashTableClear(&(p->generalEntities));
- #ifdef XML_DTD
- p->paramEntityRead = XML_FALSE;
- hashTableClear(&(p->paramEntities));
- #endif /* XML_DTD */
- hashTableClear(&(p->elementTypes));
- hashTableClear(&(p->attributeIds));
- hashTableClear(&(p->prefixes));
- poolClear(&(p->pool));
- #ifdef XML_DTD
- poolClear(&(p->entityValuePool));
- #endif /* XML_DTD */
- p->defaultPrefix.name = NULL;
- p->defaultPrefix.binding = NULL;
- p->in_eldecl = XML_FALSE;
- if (p->scaffIndex) {
- ms->free_fcn(ms->priv,p->scaffIndex);
- p->scaffIndex = NULL;
- }
- if (p->scaffold) {
- ms->free_fcn(ms->priv,p->scaffold);
- p->scaffold = NULL;
- }
- p->scaffLevel = 0;
- p->scaffSize = 0;
- p->scaffCount = 0;
- p->contentStringLen = 0;
- p->keepProcessing = XML_TRUE;
- p->hasParamEntityRefs = XML_FALSE;
- p->standalone = XML_FALSE;
- }
- static void
- dtdDestroy(DTD *p, XML_Bool isDocEntity, const XML_Memory_Handling_Suite *ms)
- {
- HASH_TABLE_ITER iter;
- hashTableIterInit(&iter, &(p->elementTypes));
- for (;;) {
- ELEMENT_TYPE *e = (ELEMENT_TYPE *)hashTableIterNext(&iter);
- if (!e)
- break;
- if (e->allocDefaultAtts != 0)
- ms->free_fcn(ms->priv,e->defaultAtts);
- }
- hashTableDestroy(&(p->generalEntities));
- #ifdef XML_DTD
- hashTableDestroy(&(p->paramEntities));
- #endif /* XML_DTD */
- hashTableDestroy(&(p->elementTypes));
- hashTableDestroy(&(p->attributeIds));
- hashTableDestroy(&(p->prefixes));
- poolDestroy(&(p->pool));
- #ifdef XML_DTD
- poolDestroy(&(p->entityValuePool));
- #endif /* XML_DTD */
- if (isDocEntity) {
- if (p->scaffIndex)
- ms->free_fcn(ms->priv,p->scaffIndex);
- if (p->scaffold)
- ms->free_fcn(ms->priv,p->scaffold);
- }
- ms->free_fcn(ms->priv,p);
- }
- /* 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, const XML_Memory_Handling_Suite *ms)
- {
- HASH_TABLE_ITER iter;
- /* Copy the prefix table. */
- hashTableIterInit(&iter, &(oldDtd->prefixes));
- for (;;) {
- const XML_Char *name;
- const PREFIX *oldP = (PREFIX *)hashTableIterNext(&iter);
- if (!oldP)
- break;
- name = poolCopyString(&(newDtd->pool), oldP->name);
- if (!name)
- return 0;
- if (!lookup(&(newDtd->prefixes), name, sizeof(PREFIX)))
- return 0;
- }
- 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(' ')))
- 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;
- if (oldA->prefix) {
- newA->xmlns = oldA->xmlns;
- if (oldA->prefix == &oldDtd->defaultPrefix)
- newA->prefix = &newDtd->defaultPrefix;
- else
- newA->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
- oldA->prefix->name, 0);
- }
- }
- /* 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;
- if (oldE->nDefaultAtts) {
- newE->defaultAtts = (DEFAULT_ATTRIBUTE *)
- ms->malloc_fcn(ms->priv,oldE->nDefaultAtts * sizeof(DEFAULT_ATTRIBUTE));
- if (!newE->defaultAtts) {
- ms->free_fcn(ms->priv,newE);
- return 0;
- }
- }
- if (oldE->idAtt)
- newE->idAtt = (ATTRIBUTE_ID *)
- lookup(&(newDtd->attributeIds), oldE->idAtt->name, 0);
- newE->allocDefaultAtts = newE->nDefaultAtts = oldE->nDefaultAtts;
- if (oldE->prefix)
- newE->prefix = (PREFIX *)lookup(&(newDtd->prefixes),
- oldE->prefix->name, 0);
- 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 = NULL;
- }
- }
- /* Copy the entity tables. */
- if (!copyEntityTable(&(newDtd->generalEntities),
- &(newDtd->pool),
- &(oldDtd->generalEntities)))
- return 0;
- #ifdef XML_DTD
- if (!copyEntityTable(&(newDtd->paramEntities),
- &(newDtd->pool),
- &(oldDtd->paramEntities)))
- return 0;
- newDtd->paramEntityRead = oldDtd->paramEntityRead;
- #endif /* XML_DTD */
- newDtd->keepProcessing = oldDtd->keepProcessing;
- newDtd->hasParamEntityRefs = oldDtd->hasParamEntityRefs;
- newDtd->standalone = oldDtd->standalone;
- /* Don't want deep copying for scaffolding */
- newDtd->in_eldecl = oldDtd->in_eldecl;
- newDtd->scaffold = oldDtd->scaffold;
- newDtd->contentStringLen = oldDtd->contentStringLen;
- newDtd->scaffSize = oldDtd->scaffSize;
- newDtd->scaffLevel = oldDtd->scaffLevel;
- newDtd->scaffIndex = oldDtd->scaffIndex;
- return 1;
- } /* End dtdCopy */
- static int
- copyEntityTable(HASH_TABLE *newTable,
- STRING_POOL *newPool,
- const HASH_TABLE *oldTable)
- {
- HASH_TABLE_ITER iter;
- const XML_Char *cachedOldBase = NULL;
- const XML_Char *cachedNewBase = NULL;
- hashTableIterInit(&iter, oldTable);
- for (;;) {
- ENTITY *newE;
- const XML_Char *name;
- const ENTITY *oldE = (ENTITY *)hashTableIterNext(&iter);
- if (!oldE)
- break;
- name = poolCopyString(newPool, oldE->name);
- if (!name)
- return 0;
- newE = (ENTITY *)lookup(newTable, name, sizeof(ENTITY));
- if (!newE)
- return 0;
- if (oldE->systemId) {
- const XML_Char *tem = poolCopyString(newPool, oldE->systemId);
- if (!tem)
- return 0;
- newE->systemId = tem;
- if (oldE->base) {
- if (oldE->base == cachedOldBase)
- newE->base = cachedNewBase;
- else {
- cachedOldBase = oldE->base;
- tem = poolCopyString(newPool, cachedOldBase);
- if (!tem)
- return 0;
- cachedNewBase = newE->base = tem;
- }
- }
- if (oldE->publicId) {
- tem = poolCopyString(newPool, oldE->publicId);
- if (!tem)
- return 0;
- newE->publicId = tem;
- }
- }
- else {
- const XML_Char *tem = poolCopyStringN(newPool, oldE->textPtr,
- oldE->textLen);
- if (!tem)
- return 0;
- newE->textPtr = tem;
- newE->textLen = oldE->textLen;
- }
- if (oldE->notation) {
- const XML_Char *tem = poolCopyString(newPool, oldE->notation);
- if (!tem)
- return 0;
- newE->notation = tem;
- }
- newE->is_param = oldE->is_param;
- newE->is_internal = oldE->is_internal;
- }
- return 1;
- }
- #define INIT_SIZE 64
- static int FASTCALL
- keyeq(KEY s1, KEY s2)
- {
- for (; *s1 == *s2; s1++, s2++)
- if (*s1 == 0)
- return 1;
- return 0;
- }
- static unsigned long FASTCALL
- hash(KEY s)
- {
- unsigned long h = 0;
- while (*s)
- h = (h << 5) + h + (unsigned char)*s++;
- return h;
- }
- static NAMED *
- lookup(HASH_TABLE *table, KEY name, size_t createSize)
- {
- size_t i;
- if (table->size == 0) {
- size_t tsize;
- if (!createSize)
- return NULL;
- tsize = INIT_SIZE * sizeof(NAMED *);
- table->v = (NAMED **)table->mem->malloc_fcn(table->mem->priv,tsize);
- if (!table->v)
- return NULL;
- memset(table->v, 0, tsize);
- table->size = INIT_SIZE;
- table->usedLim = INIT_SIZE / 2;
- i = hash(name) & (table->size - 1);
- }
- else {
- unsigned long h = hash(name);
- for (i = h & (table->size - 1);
- table->v[i];
- i == 0 ? i = table->size - 1 : --i) {
- if (keyeq(name, table->v[i]->name))
- return table->v[i];
- }
- if (!createSize)
- return NULL;
- if (table->used == table->usedLim) {
- /* check for overflow */
- size_t newSize = table->size * 2;
- size_t tsize = newSize * sizeof(NAMED *);
- NAMED **newV = (NAMED **)table->mem->malloc_fcn(table->mem->priv,tsize);
- if (!newV)
- return NULL;
- memset(newV, 0, tsize);
- for (i = 0; i < table->size; i++)
- if (table->v[i]) {
- size_t j;
- for (j = hash(table->v[i]->name) & (newSize - 1);
- newV[j];
- j == 0 ? j = newSize - 1 : --j)
- ;
- newV[j] = table->v[i];
- }
- table->mem->free_fcn(table->mem->priv,table->v);
- table->v = newV;
- table->size = newSize;
- table->usedLim = newSize/2;
- for (i = h & (table->size - 1);
- table->v[i];
- i == 0 ? i = table->size - 1 : --i)
- ;
- }
- }
- table->v[i] = (NAMED *)table->mem->malloc_fcn(table->mem->priv,createSize);
- if (!table->v[i])
- return NULL;
- memset(table->v[i], 0, createSize);
- table->v[i]->name = name;
- (table->used)++;
- return table->v[i];
- }
- static void FASTCALL
- hashTableClear(HASH_TABLE *table)
- {
- size_t i;
- for (i = 0; i < table->size; i++) {
- NAMED *p = table->v[i];
- if (p) {
- table->mem->free_fcn(table->mem->priv,p);
- table->v[i] = NULL;
- }
- }
- table->usedLim = table->size / 2;
- table->used = 0;
- }
- static void FASTCALL
- hashTableDestroy(HASH_TABLE *table)
- {
- size_t i;
- for (i = 0; i < table->size; i++) {
- NAMED *p = table->v[i];
- if (p)
- table->mem->free_fcn(table->mem->priv,p);
- }
- if (table->v)
- table->mem->free_fcn(table->mem->priv,table->v);
- }
- static void FASTCALL
- hashTableInit(HASH_TABLE *p, const XML_Memory_Handling_Suite *ms)
- {
- p->size = 0;
- p->usedLim = 0;
- p->used = 0;
- p->v = NULL;
- p->mem = ms;
- }
- static void FASTCALL
- hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
- {
- iter->p = table->v;
- iter->end = iter->p + table->size;
- }
- static NAMED * FASTCALL
- hashTableIterNext(HASH_TABLE_ITER *iter)
- {
- while (iter->p != iter->end) {
- NAMED *tem = *(iter->p)++;
- if (tem)
- return tem;
- }
- return NULL;
- }
- static void FASTCALL
- poolInit(STRING_POOL *pool, const XML_Memory_Handling_Suite *ms)
- {
- pool->blocks = NULL;
- pool->freeBlocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
- pool->mem = ms;
- }
- static void FASTCALL
- poolClear(STRING_POOL *pool)
- {
- if (!pool->freeBlocks)
- pool->freeBlocks = pool->blocks;
- else {
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- p->next = pool->freeBlocks;
- pool->freeBlocks = p;
- p = tem;
- }
- }
- pool->blocks = NULL;
- pool->start = NULL;
- pool->ptr = NULL;
- pool->end = NULL;
- }
- static void FASTCALL
- poolDestroy(STRING_POOL *pool)
- {
- BLOCK *p = pool->blocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(pool->mem->priv,p);
- p = tem;
- }
- p = pool->freeBlocks;
- while (p) {
- BLOCK *tem = p->next;
- pool->mem->free_fcn(pool->mem->priv,p);
- p = tem;
- }
- }
- static XML_Char *
- poolAppend(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
- {
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (;;) {
- XmlConvert(enc, &ptr, end, (ICHAR **)&(pool->ptr), (ICHAR *)pool->end);
- if (ptr == end)
- break;
- if (!poolGrow(pool))
- return NULL;
- }
- return pool->start;
- }
- static const XML_Char * FASTCALL
- poolCopyString(STRING_POOL *pool, const XML_Char *s)
- {
- do {
- if (!poolAppendChar(pool, *s))
- return NULL;
- } while (*s++);
- s = pool->start;
- poolFinish(pool);
- return s;
- }
- static const XML_Char *
- poolCopyStringN(STRING_POOL *pool, const XML_Char *s, int n)
- {
- if (!pool->ptr && !poolGrow(pool))
- return NULL;
- for (; n > 0; --n, s++) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- }
- s = pool->start;
- poolFinish(pool);
- return s;
- }
- static const XML_Char * FASTCALL
- poolAppendString(STRING_POOL *pool, const XML_Char *s)
- {
- while (*s) {
- if (!poolAppendChar(pool, *s))
- return NULL;
- s++;
- }
- return pool->start;
- }
- static XML_Char *
- poolStoreString(STRING_POOL *pool, const ENCODING *enc,
- const char *ptr, const char *end)
- {
- if (!poolAppend(pool, enc, ptr, end))
- return NULL;
- if (pool->ptr == pool->end && !poolGrow(pool))
- return NULL;
- *(pool->ptr)++ = 0;
- return pool->start;
- }
- static XML_Bool FASTCALL
- poolGrow(STRING_POOL *pool)
- {
- if (pool->freeBlocks) {
- if (pool->start == 0) {
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = pool->freeBlocks->next;
- pool->blocks->next = NULL;
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- pool->ptr = pool->start;
- return XML_TRUE;
- }
- if (pool->end - pool->start < pool->freeBlocks->size) {
- BLOCK *tem = pool->freeBlocks->next;
- pool->freeBlocks->next = pool->blocks;
- pool->blocks = pool->freeBlocks;
- pool->freeBlocks = tem;
- memcpy(pool->blocks->s, pool->start,
- (pool->end - pool->start) * sizeof(XML_Char));
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + pool->blocks->size;
- return XML_TRUE;
- }
- }
- if (pool->blocks && pool->start == pool->blocks->s) {
- int blockSize = (pool->end - pool->start)*2;
- pool->blocks = (BLOCK *)
- pool->mem->realloc_fcn(pool->mem->priv,pool->blocks,
- (offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char)));
- if (pool->blocks == NULL)
- return XML_FALSE;
- pool->blocks->size = blockSize;
- pool->ptr = pool->blocks->s + (pool->ptr - pool->start);
- pool->start = pool->blocks->s;
- pool->end = pool->start + blockSize;
- }
- else {
- BLOCK *tem;
- int blockSize = pool->end - pool->start;
- if (blockSize < INIT_BLOCK_SIZE)
- blockSize = INIT_BLOCK_SIZE;
- else
- blockSize *= 2;
- tem = (BLOCK *)pool->mem->malloc_fcn(pool->mem->priv,offsetof(BLOCK, s)
- + blockSize * sizeof(XML_Char));
- if (!tem)
- return XML_FALSE;
- tem->size = blockSize;
- tem->next = pool->blocks;
- pool->blocks = tem;
- if (pool->ptr != pool->start)
- memcpy(tem->s, pool->start,
- (pool->ptr - pool->start) * sizeof(XML_Char));
- pool->ptr = tem->s + (pool->ptr - pool->start);
- pool->start = tem->s;
- pool->end = tem->s + blockSize;
- }
- return XML_TRUE;
- }
- static int FASTCALL
- nextScaffoldPart(XML_Parser parser)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- CONTENT_SCAFFOLD * me;
- int next;
- if (!dtd->scaffIndex) {
- dtd->scaffIndex = (int *)MALLOC(groupSize * sizeof(int));
- if (!dtd->scaffIndex)
- return -1;
- dtd->scaffIndex[0] = 0;
- }
- if (dtd->scaffCount >= dtd->scaffSize) {
- CONTENT_SCAFFOLD *temp;
- if (dtd->scaffold) {
- temp = (CONTENT_SCAFFOLD *)
- REALLOC(dtd->scaffold, dtd->scaffSize * 2 * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd->scaffSize *= 2;
- }
- else {
- temp = (CONTENT_SCAFFOLD *)MALLOC(INIT_SCAFFOLD_ELEMENTS
- * sizeof(CONTENT_SCAFFOLD));
- if (temp == NULL)
- return -1;
- dtd->scaffSize = INIT_SCAFFOLD_ELEMENTS;
- }
- dtd->scaffold = temp;
- }
- next = dtd->scaffCount++;
- me = &dtd->scaffold[next];
- if (dtd->scaffLevel) {
- CONTENT_SCAFFOLD *parent = &dtd->scaffold[dtd->scaffIndex[dtd->scaffLevel-1]];
- if (parent->lastchild) {
- dtd->scaffold[parent->lastchild].nextsib = next;
- }
- if (!parent->childcnt)
- parent->firstchild = next;
- parent->lastchild = next;
- parent->childcnt++;
- }
- me->firstchild = me->lastchild = me->childcnt = me->nextsib = 0;
- return next;
- }
- static void
- build_node(XML_Parser parser,
- int src_node,
- XML_Content *dest,
- XML_Content **contpos,
- XML_Char **strpos)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- dest->type = dtd->scaffold[src_node].type;
- dest->quant = dtd->scaffold[src_node].quant;
- if (dest->type == XML_CTYPE_NAME) {
- const XML_Char *src;
- dest->name = *strpos;
- src = dtd->scaffold[src_node].name;
- for (;;) {
- *(*strpos)++ = *src;
- if (!*src)
- break;
- src++;
- }
- dest->numchildren = 0;
- dest->children = NULL;
- }
- else {
- unsigned int i;
- int cn;
- dest->numchildren = dtd->scaffold[src_node].childcnt;
- dest->children = *contpos;
- *contpos += dest->numchildren;
- for (i = 0, cn = dtd->scaffold[src_node].firstchild;
- i < dest->numchildren;
- i++, cn = dtd->scaffold[cn].nextsib) {
- build_node(parser, cn, &(dest->children[i]), contpos, strpos);
- }
- dest->name = NULL;
- }
- }
- static XML_Content *
- build_model (XML_Parser parser)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- XML_Content *ret;
- XML_Content *cpos;
- XML_Char * str;
- int allocsize = (dtd->scaffCount * sizeof(XML_Content)
- + (dtd->contentStringLen * sizeof(XML_Char)));
- ret = (XML_Content *)MALLOC(allocsize);
- if (!ret)
- return NULL;
- str = (XML_Char *) (&ret[dtd->scaffCount]);
- cpos = &ret[1];
- build_node(parser, 0, ret, &cpos, &str);
- return ret;
- }
- static ELEMENT_TYPE *
- getElementType(XML_Parser parser,
- const ENCODING *enc,
- const char *ptr,
- const char *end)
- {
- DTD * const dtd = _dtd; /* save one level of indirection */
- const XML_Char *name = poolStoreString(&dtd->pool, enc, ptr, end);
- ELEMENT_TYPE *ret;
- if (!name)
- return NULL;
- ret = (ELEMENT_TYPE *) lookup(&dtd->elementTypes, name, sizeof(ELEMENT_TYPE));
- if (!ret)
- return NULL;
- if (ret->name != name)
- poolDiscard(&dtd->pool);
- else {
- poolFinish(&dtd->pool);
- if (!setElementTypePrefix(parser, ret))
- return NULL;
- }
- return ret;
- }
- /* local additions */
- int XML_IsExpanding(XML_Parser parser) {
- return !!openInternalEntities;
- }
- int XML_ParseCharacterData(XML_Parser parser,char **source,int len,
- wchar_t *dest,int destlen)
- {
- char *start=*source;
- char *end=start+len;
- char *next;
- int nChars=0;
- int tok;
- while (start<end && nChars<destlen) {
- next=start;
- tok=XmlContentTok(encoding,start,end,&next);
- switch (tok) {
- case XML_TOK_CHAR_REF:
- {
- int n = XmlCharRefNumber(encoding, start);
- if (n < 0)
- return -1;
- /* XXX cheating ! */
- *dest++=n;
- ++nChars;
- }
- break;
- case XML_TOK_ENTITY_REF:
- {
- XML_Char ch = XmlPredefinedEntityName(encoding,
- start + encoding->minBytesPerChar,
- next - encoding->minBytesPerChar);
- if (ch) {
- *dest++=ch;
- ++nChars;
- break;
- }
- /* TODO: I really should have expanded internal entities here */
- }
- break;
- case XML_TOK_DATA_NEWLINE:
- *dest++=0xA;
- ++nChars;
- break;
- case XML_TOK_DATA_CHARS:
- {
- do {
- unsigned short *ds=dest,*de=dest+destlen-nChars;
- XmlUtf16Convert(encoding, &start, next, &ds,de);
- if (ds==dest) /* didn't convert anything */
- break;
- nChars+=ds-dest;
- dest=ds;
- } while (start!=next && nChars<destlen);
- next=start;
- }
- break;
- case XML_TOK_TRAILING_RSQB: {
- /* ] or ]] */
- wchar_t *ds=dest,*de=dest+destlen-nChars;
- XmlUtf16Convert(encoding, &start, end, &ds, de);
- nChars+=ds-dest;
- *source=start;
- return nChars;
- }
- default: /* we only deal with characters here */
- return -1;
- }
- start=next;
- *source=start;
- }
- return nChars;
- }
- int XML_ConvertCharacterData(XML_Parser parser,char **source,int len,
- wchar_t *dest,int destlen)
- {
- int nChars=0;
- char *top=*source+len;
- while (*source<top && nChars<destlen) {
- wchar_t *ds=dest,*de=dest+destlen-nChars;
- XmlUtf16Convert(encoding, source, top, &ds,de);
- if (ds==dest) /* didn't convert anything */
- break;
- nChars+=ds-dest;
- dest=ds;
- }
- return nChars;
- }