Lines Matching refs:parser

60     const struct __CFXMLParser *parser = (const struct __CFXMLParser *)cf;
61 return CFStringCreateWithFormat(CFGetAllocator(cf), NULL, CFSTR("<CFXMLParser %p>"), parser);
65 struct __CFXMLParser *parser = (struct __CFXMLParser *)cf;
66 CFAllocatorRef alloc = CFGetAllocator(parser);
67 _freeInputStream(&(parser->input));
68 if (parser->argDict) CFRelease(parser->argDict);
69 if (parser->argArray) CFRelease(parser->argArray);
70 if (parser->errorString) CFRelease(parser->errorString);
71 if (parser->node) CFRelease(parser->node);
72 CFAllocatorDeallocate(alloc, parser->stack);
73 if (parser->context.info && parser->context.release) {
74 parser->context.release(parser->context.info);
101 void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context) {
102 CFAssert1(parser != NULL, __kCFLogAssertion, "%s(): NULL parser not permitted", __PRETTY_FUNCTION__);
103 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
105 context->version = parser->context.version;
106 context->info = parser->context.info;
107 context->retain = parser->context.retain;
108 context->release = parser->context.release;
109 context->copyDescription = parser->context.copyDescription;
116 void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) {
117 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
119 callBacks->version = parser->callBacks.version;
120 callBacks->createXMLStructure = parser->callBacks.createXMLStructure;
121 callBacks->addChild = parser->callBacks.addChild;
122 callBacks->endXMLStructure = parser->callBacks.endXMLStructure;
123 callBacks->resolveExternalEntity = parser->callBacks.resolveExternalEntity;
124 callBacks->handleError = parser->callBacks.handleError;
133 CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser) {
134 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
135 return parser->input.url;
139 CFIndex CFXMLParserGetLocation(CFXMLParserRef parser) {
140 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
141 return _inputStreamCurrentLocation(&parser->input);
144 CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser) {
145 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
146 return _inputStreamCurrentLine(&parser->input);
150 void *CFXMLParserGetDocument(CFXMLParserRef parser) {
151 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
152 if (parser->capacity > 0)
153 return parser->stack[0];
158 CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser) {
159 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
160 return parser->status;
163 CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser) {
164 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
165 return (CFStringRef)CFRetain(parser->errorString);
168 void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription) {
169 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
174 parser->status = errorCode;
175 if (parser->errorString) CFRelease(parser->errorString);
176 parser->errorString = (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, errorDescription);
180 static Boolean parseXML(CFXMLParserRef parser);
181 static Boolean parseComment(CFXMLParserRef parser, Boolean report);
182 static Boolean parseProcessingInstruction(CFXMLParserRef parser, Boolean report);
183 static Boolean parseInlineDTD(CFXMLParserRef parser);
184 static Boolean parseDTD(CFXMLParserRef parser);
185 static Boolean parsePhysicalEntityReference(CFXMLParserRef parser);
186 static Boolean parseCDSect(CFXMLParserRef parser);
187 static Boolean parseEntityReference(CFXMLParserRef parser, Boolean report);
188 static Boolean parsePCData(CFXMLParserRef parser);
189 static Boolean parseWhitespace(CFXMLParserRef parser);
190 static Boolean parseAttributeListDeclaration(CFXMLParserRef parser);
191 static Boolean parseNotationDeclaration(CFXMLParserRef parser);
192 static Boolean parseElementDeclaration(CFXMLParserRef parser);
193 static Boolean parseEntityDeclaration(CFXMLParserRef parser);
194 static Boolean parseExternalID(CFXMLParserRef parser, Boolean alsoAcceptPublicID, CFXMLExternalID *extID);
195 static Boolean parseCloseTag(CFXMLParserRef parser, CFStringRef tag);
196 static Boolean parseTagContent(CFXMLParserRef parser);
197 static Boolean parseTag(CFXMLParserRef parser);
198 static Boolean parseAttributes(CFXMLParserRef parser);
199 static Boolean parseAttributeValue(CFXMLParserRef parser, CFMutableStringRef str);
201 // Utilities; may need to make these accessible to the property list parser to avoid code duplication
202 static void _CFReportError(CFXMLParserRef parser, CFXMLParserStatusCode errNum, const char *str);
203 static Boolean reportNewLeaf(CFXMLParserRef parser); // Assumes parser->node has been set and is ready to go
204 static void pushXMLNode(CFXMLParserRef parser, void *node);
207 struct __CFXMLParser *parser = (struct __CFXMLParser *)_CFRuntimeCreateInstance(alloc, CFXMLParserGetTypeID(), sizeof(struct __CFXMLParser) - sizeof(CFRuntimeBase), NULL);
210 if (parser && node) {
211 alloc = CFGetAllocator(parser);
212 _initializeInputStream(&(parser->input), alloc, dataSource, xmlData);
213 parser->top = parser->stack;
214 parser->stack = NULL;
215 parser->capacity = 0;
218 parser->node = node;
219 parser->node->dataString = CFStringCreateMutableWithExternalCharactersNoCopy(alloc, buf, 0, 128, alloc);
220 parser->node->additionalData = NULL;
221 parser->node->version = version;
222 parser->argDict = NULL; // don't create these until necessary
223 parser->argArray = NULL;
225 parser->options = options;
226 parser->callBacks = *callBacks;
228 FAULT_CALLBACK((void **)&(parser->callBacks.createXMLStructure));
229 FAULT_CALLBACK((void **)&(parser->callBacks.addChild));
230 FAULT_CALLBACK((void **)&(parser->callBacks.endXMLStructure));
231 FAULT_CALLBACK((void **)&(parser->callBacks.resolveExternalEntity));
232 FAULT_CALLBACK((void **)&(parser->callBacks.handleError));
235 parser->context = *context;
236 if (parser->context.info && parser->context.retain) {
237 parser->context.retain(parser->context.info);
240 parser->context.version = 0;
241 parser->context.info = NULL;
242 parser->context.retain = NULL;
243 parser->context.release = NULL;
244 parser->context.copyDescription = NULL;
246 parser->status = kCFXMLStatusParseNotBegun;
247 parser->errorString = NULL;
249 if (parser) CFRelease(parser);
251 parser = NULL;
253 return parser;
275 Boolean CFXMLParserParse(CFXMLParserRef parser) {
277 __CFGenericValidateType(parser, CFXMLParserGetTypeID());
278 if (parser->status != kCFXMLStatusParseNotBegun) return false;
279 parser->status = kCFXMLStatusParseInProgress;
281 if (!_openInputStream(&parser->input)) {
282 if (!parser->input.data) {
284 parser->status = kCFXMLErrorNoData;
285 parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("No data found at %@"), CFURLGetString(parser->input.url));
288 CFAssert(parser->input.encoding == kCFStringEncodingInvalidId, __kCFLogAssertion, "CFXMLParser internal error: input stream could not be opened");
289 parser->status = kCFXMLErrorUnknownEncoding;
290 parser->errorString = CFStringCreateWithCString(CFGetAllocator(parser), "Encountered unknown encoding", kCFStringEncodingASCII);
292 if (parser->callBacks.handleError) {
293 INVOKE_CALLBACK3(parser->callBacks.handleError, parser, parser->status, parser->context.info);
299 parser->stack = (void **)CFAllocatorAllocate(CFGetAllocator(parser), 16 * sizeof(void *), 0);
300 parser->capacity = 16;
301 parser->node->dataTypeID = kCFXMLNodeTypeDocument;
302 docData.encoding = _inputStreamGetEncoding(&parser->input);
303 docData.sourceURL = parser->input.url;
304 parser->node->additionalData = &docData;
305 parser->stack[0] = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
306 parser->top = parser->stack;
307 parser->node->additionalData = NULL;
310 if (parser->status != kCFXMLStatusParseInProgress) {
311 _CFReportError(parser, parser->status, NULL);
314 return parseXML(parser);
317 /* The next several functions are all intended to parse past a particular XML structure. They expect parser->curr to be set to the first content character of their structure (e.g. parseXMLComment expects parser->curr to be set just past "<!--"). They parse to the end of their structure, calling any necessary callbacks along the way, and advancing parser->curr as they go. They either return void (not possible for the parse to fail) or they return a Boolean (success/failure). The calling routines are expected to catch returned Booleans and fail immediately if false is returned. */
320 static Boolean parseWhitespace(CFXMLParserRef parser) {
322 Boolean report = !(parser->options & kCFXMLParserSkipWhitespace);
323 len = _inputStreamSkipWhitespace(&parser->input, report ? (CFMutableStringRef)(parser->node->dataString) : NULL);
325 parser->node->dataTypeID = kCFXMLNodeTypeWhitespace;
326 parser->node->additionalData = NULL;
327 return reportNewLeaf(parser);
333 // parser should be just past "<!--"
334 static Boolean parseComment(CFXMLParserRef parser, Boolean report) {
337 report = report && (!(parser->options & kCFXMLParserSkipMetaData));
338 if (!_inputStreamScanToCharacters(&parser->input, dashes, 2, report ? (CFMutableStringRef)(parser->node->dataString) : NULL) || !_inputStreamGetCharacter(&parser->input, &ch)) {
339 _CFReportError(parser, kCFXMLErrorUnexpectedEOF,"Found unexpected EOF while parsing comment");
342 _CFReportError(parser, kCFXMLErrorMalformedComment, "Found \"--\" within a comment");
345 parser->node->dataTypeID = kCFXMLNodeTypeComment;
346 parser->node->additionalData = NULL;
347 return reportNewLeaf(parser);
357 // parser should be set to the first character after "<?"
358 static Boolean parseProcessingInstruction(CFXMLParserRef parser, Boolean report) {
363 if (!_inputStreamScanXMLName(&parser->input, false, &name)) {
364 _CFReportError(parser, kCFXMLErrorMalformedProcessingInstruction, "Found malformed processing instruction");
367 _inputStreamSkipWhitespace(&parser->input, NULL);
368 str = (report && *parser->top) ? CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser)) : NULL;
369 if (!_inputStreamScanToCharacters(&parser->input, piTermination, 2, str)) {
370 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing processing instruction");
378 CFStringRef tmp = parser->node->dataString;
379 parser->node->dataTypeID = kCFXMLNodeTypeProcessingInstruction;
380 parser->node->dataString = name;
382 parser->node->additionalData = &data;
383 result = reportNewLeaf(parser);
384 parser->node->additionalData = NULL;
385 parser->node->dataString = tmp;
398 static Boolean parseDTD(CFXMLParserRef parser) {
406 success = _inputStreamMatchString(&parser->input, _DoctypeOpening, 7);
407 success = success && _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
408 success = success && _inputStreamScanXMLName(&parser->input, false, &name);
410 _inputStreamSkipWhitespace(&parser->input, NULL);
411 success = _inputStreamPeekCharacter(&parser->input, &ch);
414 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found malformed DTD");
420 success = parseExternalID(parser, false, &(docData.externalID));
422 _inputStreamSkipWhitespace(&parser->input, NULL);
423 success = _inputStreamPeekCharacter(&parser->input, &ch);
427 if (!(parser->options & kCFXMLParserSkipMetaData) && *(parser->top)) {
428 CFStringRef tmp = parser->node->dataString;
429 parser->node->dataTypeID = kCFXMLNodeTypeDocumentType;
430 parser->node->dataString = name;
431 parser->node->additionalData = &docData;
432 dtdStructure = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
433 if (dtdStructure && parser->status == kCFXMLStatusParseInProgress) {
434 INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *parser->top, dtdStructure, parser->context.info);
436 parser->node->additionalData = NULL;
437 parser->node->dataString = tmp;
438 if (parser->status != kCFXMLStatusParseInProgress) {
440 _CFReportError(parser, parser->status, NULL);
448 pushXMLNode(parser, dtdStructure);
452 _inputStreamGetCharacter(&parser->input, &ch);
453 if (!parseInlineDTD(parser)) return false;
454 _inputStreamSkipWhitespace(&parser->input, NULL);
455 success = _inputStreamGetCharacter(&parser->input, &ch) && ch == '>';
458 _inputStreamGetCharacter(&parser->input, &ch);
461 if (_inputStreamAtEOF(&parser->input)) {
462 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing DTD");
464 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found malformed DTD");
469 parser->top --; // Remove dtdStructure from the stack
472 INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, dtdStructure, parser->context.info);
473 if (parser->status != kCFXMLStatusParseInProgress) {
474 _CFReportError(parser, parser->status, NULL);
484 static Boolean parsePhysicalEntityReference(CFXMLParserRef parser) {
487 if (!_inputStreamScanXMLName(&parser->input, false, &name)) {
488 _CFReportError(parser, kCFXMLErrorMalformedName, "Found malformed name while parsing physical entity reference");
490 } else if (!_inputStreamGetCharacter(&parser->input, &ch)) {
491 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing physical entity reference");
494 _CFReportError(parser, kCFXMLErrorMalformedName, "Found malformed name while parsing physical entity reference");
496 } else if (!(parser->options & kCFXMLParserSkipMetaData) && *(parser->top)) {
499 CFStringRef tmp = parser->node->dataString;
500 parser->node->dataTypeID = kCFXMLNodeTypeEntityReference;
501 parser->node->dataString = name;
503 parser->node->additionalData = &myData;
504 result = reportNewLeaf(parser);
505 parser->node->additionalData = NULL;
506 parser->node->dataString = tmp;
521 static Boolean parseEnumeration(CFXMLParserRef parser, Boolean useNMTokens) {
524 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
525 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
528 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
531 _inputStreamSkipWhitespace(&parser->input, NULL);
532 if (!_inputStreamScanXMLName(&parser->input, useNMTokens, NULL)) {
533 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
537 _inputStreamSkipWhitespace(&parser->input, NULL);
538 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
539 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
544 _inputStreamSkipWhitespace(&parser->input, NULL);
545 if (!_inputStreamScanXMLName(&parser->input, useNMTokens, NULL)) {
546 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
550 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
557 static Boolean parseAttributeType(CFXMLParserRef parser, CFMutableStringRef str) {
566 if (str) _inputStreamSetMark(&parser->input);
567 if (_inputStreamMatchString(&parser->input, attTypeStrings[0], 5) ||
568 _inputStreamMatchString(&parser->input, attTypeStrings[1], 6) ||
569 _inputStreamMatchString(&parser->input, attTypeStrings[1], 5) ||
570 _inputStreamMatchString(&parser->input, attTypeStrings[1], 2) ||
571 _inputStreamMatchString(&parser->input, attTypeStrings[2], 6) ||
572 _inputStreamMatchString(&parser->input, attTypeStrings[3], 8) ||
573 _inputStreamMatchString(&parser->input, attTypeStrings[4], 8) ||
574 _inputStreamMatchString(&parser->input, attTypeStrings[4], 7)) {
576 } else if (_inputStreamMatchString(&parser->input, attTypeStrings[5], 8)) {
578 if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
579 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
582 success = parseEnumeration(parser, false);
585 success = parseEnumeration(parser, true);
589 _inputStreamGetCharactersFromMark(&parser->input, str);
591 _inputStreamClearMark(&parser->input);
597 static Boolean parseAttributeDefaultDeclaration(CFXMLParserRef parser, CFMutableStringRef str) {
604 if (str) _inputStreamSetMark(&parser->input);
605 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
606 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
609 if (_inputStreamMatchString(&parser->input, strings[0], 8) ||
610 _inputStreamMatchString(&parser->input, strings[1], 7)) {
612 } else if (!_inputStreamMatchString(&parser->input, strings[2], 5) || _inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
613 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
617 success = parseAttributeValue(parser, NULL);
620 _inputStreamReturnCharacter(&parser->input, ch);
621 success = parseAttributeValue(parser, NULL);
625 _inputStreamGetCharactersFromMark(&parser->input, str);
627 _inputStreamClearMark(&parser->input);
636 static Boolean parseAttributeListDeclaration(CFXMLParserRef parser) {
644 if (!_inputStreamMatchString(&parser->input, attList, 7) ||
645 _inputStreamSkipWhitespace(&parser->input, NULL) == 0 ||
646 !_inputStreamScanXMLName(&parser->input, false, &name)) {
647 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
651 if (!(*parser->top) || (parser->options & kCFXMLParserSkipMetaData)) {
655 while (_inputStreamPeekCharacter(&parser->input, &ch) && ch != '>' && _inputStreamSkipWhitespace(&parser->input, NULL) != 0) {
657 if (_inputStreamPeekCharacter(&parser->input, &ch) && ch == '>')
663 attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorReallocate(CFGetAllocator(parser), attributes, capacity * sizeof(CFXMLAttributeDeclarationInfo), 0);
665 attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(CFGetAllocator(parser), capacity * sizeof(CFXMLAttributeDeclarationInfo), 0);
670 attribute->typeString = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
671 attribute->defaultString = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
673 if (!_inputStreamScanXMLName(&parser->input, false, &(attribute->attributeName)) || (_inputStreamSkipWhitespace(&parser->input, NULL) == 0)) {
674 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
678 if (!parseAttributeType(parser, attribute ? (CFMutableStringRef)attribute->typeString : NULL)) {
682 if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
683 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
687 if (!parseAttributeDefaultDeclaration(parser, attribute ? (CFMutableStringRef)attribute->defaultString : NULL)) {
694 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
695 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
698 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
701 CFStringRef tmp = parser->node->dataString;
702 parser->node->dataTypeID = kCFXMLNodeTypeAttributeListDeclaration;
703 parser->node->dataString = name;
705 parser->node->additionalData = (void *)&attListData;
706 success = reportNewLeaf(parser);
707 parser->node->additionalData = NULL;
708 parser->node->dataString = tmp;
720 CFAllocatorDeallocate(CFGetAllocator(parser), attributes);
726 CF_INLINE Boolean parseSystemLiteral(CFXMLParserRef parser, CFXMLExternalID *extID) {
729 CFMutableStringRef urlStr = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
730 if (_inputStreamScanQuotedString(&parser->input, urlStr)) {
732 extID->systemID = CFURLCreateWithString(CFGetAllocator(parser), urlStr, parser->input.url);
739 success = _inputStreamScanQuotedString(&parser->input, NULL);
751 // This does NOT report errors itself; caller can check to see if parser->input is at EOF to determine whether the formatting failed or unexpected EOF occurred. -- REW, 2/2/2000
752 static Boolean parseExternalID(CFXMLParserRef parser, Boolean alsoAcceptPublicID, CFXMLExternalID *extID) {
760 if (_inputStreamMatchString(&parser->input, publicString, 6)) {
761 success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
763 extID->publicID = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
764 success = success && _inputStreamScanQuotedString(&parser->input, (CFMutableStringRef)extID->publicID);
766 success = success && _inputStreamScanQuotedString(&parser->input, NULL);
771 _inputStreamSetMark(&parser->input); // In case we need to roll back the parser
773 if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0
774 || !_inputStreamPeekCharacter(&parser->input, &ch)
776 || !parseSystemLiteral(parser, extID)) {
779 _inputStreamBackUpToMark(&parser->input);
785 _inputStreamClearMark(&parser->input);
788 } else if (_inputStreamMatchString(&parser->input, systemString, 6)) {
789 success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0 && parseSystemLiteral(parser, extID);
799 static Boolean parseNotationDeclaration(CFXMLParserRef parser) {
801 Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
805 _inputStreamMatchString(&parser->input, notationString, 8) &&
806 _inputStreamSkipWhitespace(&parser->input, NULL) != 0 &&
807 _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) &&
808 _inputStreamSkipWhitespace(&parser->input, NULL) != 0 &&
809 parseExternalID(parser, true, report ? &(notationData.externalID) : NULL);
813 _inputStreamSkipWhitespace(&parser->input, NULL);
814 success = (_inputStreamGetCharacter(&parser->input, &ch) && ch == '>');
817 if (_inputStreamAtEOF(&parser->input)) {
818 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
820 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
823 CFStringRef tmp = parser->node->dataString;
824 parser->node->dataTypeID = kCFXMLNodeTypeNotation;
825 parser->node->dataString = name;
826 parser->node->additionalData = &notationData;
827 success = reportNewLeaf(parser);
828 parser->node->additionalData = NULL;
829 parser->node->dataString = tmp;
841 static Boolean parseChoiceOrSequence(CFXMLParserRef parser, Boolean pastParen) {
844 if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '(') return false;
845 _inputStreamSkipWhitespace(&parser->input, NULL);
847 if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
851 if (!parseChoiceOrSequence(parser, false)) return false;
853 if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
855 if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
856 if (ch == '?' || ch == '*' || ch == '+') _inputStreamGetCharacter(&parser->input, &ch);
859 _inputStreamSkipWhitespace(&parser->input, NULL);
860 if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
865 _inputStreamSkipWhitespace(&parser->input, NULL);
866 if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
868 if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
869 } else if (!parseChoiceOrSequence(parser, false)) {
872 _inputStreamSkipWhitespace(&parser->input, NULL);
873 if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
881 static Boolean parseMixedElementContent(CFXMLParserRef parser) {
884 if (!_inputStreamMatchString(&parser->input, pcdataString, 7)) return false;
885 _inputStreamSkipWhitespace(&parser->input, NULL);
886 if (!_inputStreamGetCharacter(&parser->input, &ch) && (ch == ')' || ch == '|')) return false;
890 _inputStreamSkipWhitespace(&parser->input, NULL);
891 if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
892 _inputStreamSkipWhitespace(&parser->input, NULL);
893 if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
896 if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '*') return false;
904 static Boolean parseElementContentSpec(CFXMLParserRef parser) {
908 if (_inputStreamMatchString(&parser->input, eltContentEmpty, 5) || _inputStreamMatchString(&parser->input, eltContentAny, 3)) {
910 } else if (!_inputStreamPeekCharacter(&parser->input, &ch) || ch != '(') {
914 _inputStreamGetCharacter(&parser->input, &ch);
915 _inputStreamSkipWhitespace(&parser->input, NULL);
916 if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
919 return parseMixedElementContent(parser);
921 if (parseChoiceOrSequence(parser, true)) {
922 if (_inputStreamPeekCharacter(&parser->input, &ch) && (ch == '*' || ch == '?' || ch == '+')) {
923 _inputStreamGetCharacter(&parser->input, &ch);
936 static Boolean parseElementDeclaration(CFXMLParserRef parser) {
937 Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
943 success = _inputStreamMatchString(&parser->input, eltChars, 7)
944 && _inputStreamSkipWhitespace(&parser->input, NULL) != 0
945 && _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL)
946 && _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
948 if (report) _inputStreamSetMark(&parser->input);
949 success = parseElementContentSpec(parser);
951 contentDesc = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
952 _inputStreamGetCharactersFromMark(&parser->input, contentDesc);
954 if (report) _inputStreamClearMark(&parser->input);
955 if (success) _inputStreamSkipWhitespace(&parser->input, NULL);
956 success = success && _inputStreamMatchString(&parser->input, &ch, 1);
959 if (_inputStreamAtEOF(&parser->input)) {
960 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
962 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
966 CFStringRef tmp = parser->node->dataString;
967 parser->node->dataTypeID = kCFXMLNodeTypeElementTypeDeclaration;
968 parser->node->dataString = name;
970 parser->node->additionalData = &eltData;
971 success = reportNewLeaf(parser);
972 parser->node->additionalData = NULL;
973 parser->node->dataString = tmp;
988 static Boolean parseEntityDeclaration(CFXMLParserRef parser) {
994 Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
996 _inputStreamMatchString(&parser->input, entityStr, 6) &&
997 (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) &&
998 _inputStreamPeekCharacter(&parser->input, &ch);
1007 _inputStreamGetCharacter(&parser->input, &ch);
1008 success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
1011 success = success && _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) && (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) && _inputStreamPeekCharacter(&parser->input, &ch);
1016 entityData.replacementText = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
1017 success = _inputStreamScanQuotedString(&parser->input, (CFMutableStringRef)entityData.replacementText);
1019 success = _inputStreamScanQuotedString(&parser->input, NULL);
1023 success = parseExternalID(parser, false, report ? &(entityData.entityID) : NULL);
1024 if (success && !isPEDecl && _inputStreamSkipWhitespace(&parser->input, NULL) != 0) {
1028 if (_inputStreamMatchString(&parser->input, nDataStr, 5)) {
1029 success = (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) && _inputStreamScanXMLName(&parser->input, false, NULL);
1034 _inputStreamSkipWhitespace(&parser->input, NULL);
1035 success = _inputStreamGetCharacter(&parser->input, &ch) && ch == '>';
1038 if (_inputStreamAtEOF(&parser->input)) {
1039 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
1041 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
1044 CFStringRef tmp = parser->node->dataString;
1049 parser->node->dataTypeID = kCFXMLNodeTypeEntity;
1050 parser->node->dataString = name;
1051 parser->node->additionalData = &entityData;
1052 success = reportNewLeaf(parser);
1053 parser->node->additionalData = NULL;
1054 parser->node->dataString = tmp;
1067 static Boolean parseInlineDTD(CFXMLParserRef parser) {
1069 while (success && !_inputStreamAtEOF(&parser->input)) {
1072 parseWhitespace(parser);
1073 if (!_inputStreamGetCharacter(&parser->input, &ch)) break;
1076 success = parsePhysicalEntityReference(parser);
1079 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
1080 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
1085 success = parseProcessingInstruction(parser, true); // We can safely pass true here, because *parser->top will be NULL if kCFXMLParserSkipMetaData is true
1088 if (_inputStreamMatchString(&parser->input, dashes, 2)) {
1090 success = parseComment(parser, true);
1093 if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
1094 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
1098 success = parseAttributeListDeclaration(parser);
1100 success = parseNotationDeclaration(parser);
1103 _inputStreamGetCharacter(&parser->input, &ch);
1104 if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
1105 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
1108 _inputStreamReturnCharacter(&parser->input, 'E');
1110 success = parseElementDeclaration(parser);
1112 success = parseEntityDeclaration(parser);
1114 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
1118 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
1123 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
1129 _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
1134 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
1142 static Boolean parseTagContent(CFXMLParserRef parser) {
1143 while (!_inputStreamAtEOF(&parser->input)) {
1147 _inputStreamSetMark(&parser->input);
1148 numWhitespaceCharacters = _inputStreamSkipWhitespace(&parser->input, NULL);
1150 if (!_inputStreamGetCharacter(&parser->input, &ch)) break; // break == report unexpected EOF
1154 _inputStreamBackUpToMark(&parser->input);
1155 _inputStreamClearMark(&parser->input);
1156 if (!parsePCData(parser)) return false;
1157 if(_inputStreamComposingErrorOccurred(&parser->input)) {
1158 _CFReportError(parser, kCFXMLErrorEncodingConversionFailure, "Encountered string encoding error");
1166 if (!(parser->options & kCFXMLParserSkipWhitespace) && numWhitespaceCharacters != 0 && *(parser->top)) {
1167 _inputStreamReturnCharacter(&parser->input, ch);
1168 _inputStreamGetCharactersFromMark(&parser->input, (CFMutableStringRef)(parser->node->dataString));
1169 parser->node->dataTypeID = kCFXMLNodeTypeWhitespace;
1170 parser->node->additionalData = NULL;
1171 if (!reportNewLeaf(parser)) return false;
1172 _inputStreamGetCharacter(&parser->input, &ch);
1174 _inputStreamClearMark(&parser->input);
1178 if (!parseEntityReference(parser, true)) return false;
1183 if (!_inputStreamPeekCharacter(&parser->input, &ch)) break;
1185 _inputStreamGetCharacter(&parser->input, &ch);
1186 if (!parseProcessingInstruction(parser, true))
1189 _inputStreamReturnCharacter(&parser->input, '<'); // Back off to the '<'
1192 if (!parseTag(parser)) return false;
1196 if (_inputStreamMatchString(&parser->input, dashes, 3)) {
1198 if (!parseComment(parser, true)) return false;
1201 _inputStreamReturnCharacter(&parser->input, '<');
1202 if (!parseCDSect(parser)) return false;
1207 if(_inputStreamComposingErrorOccurred(&parser->input)) {
1208 _CFReportError(parser, kCFXMLErrorEncodingConversionFailure, "Encountered string encoding error");
1213 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing tag content");
1217 static Boolean parseCDSect(CFXMLParserRef parser) {
1220 if (!_inputStreamMatchString(&parser->input, _CDSectOpening, 9)) {
1221 _CFReportError(parser, kCFXMLErrorMalformedCDSect, "Encountered bad prefix to a presumed CDATA section");
1224 if (!_inputStreamScanToCharacters(&parser->input, _CDSectClose, 3, (CFMutableStringRef)(parser->node->dataString))) {
1225 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing CDATA section");
1229 parser->node->dataTypeID = kCFXMLNodeTypeCDATASection;
1230 parser->node->additionalData = NULL;
1231 return reportNewLeaf(parser);
1267 static Boolean parseEntityReference(CFXMLParserRef parser, Boolean report) {
1271 if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
1272 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
1277 if (!_inputStreamScanToCharacters(&parser->input, &ch, 1, (CFMutableStringRef)parser->node->dataString)) {
1278 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
1280 } else if (!validateCharacterReference(parser->node->dataString)) {
1281 _CFReportError(parser, kCFXMLErrorMalformedCharacterReference, "Encountered illegal character while parsing character reference");
1285 name = parser->node->dataString;
1286 } else if (!_inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) || !_inputStreamGetCharacter(&parser->input, &ch) || ch != ';') {
1287 if (_inputStreamAtEOF(&parser->input)) {
1288 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
1291 _CFReportError(parser, kCFXMLErrorMalformedName, "Encountered malformed name while parsing EntityReference");
1298 CFStringRef tmp = parser->node->dataString;
1300 parser->node->dataTypeID = kCFXMLNodeTypeEntityReference;
1301 parser->node->dataString = name;
1302 parser->node->additionalData = &entData;
1303 success = reportNewLeaf(parser);
1304 parser->node->additionalData = NULL;
1305 parser->node->dataString = tmp;
1315 switch (*(parser->curr)) {
1317 if (len >= 3 && *(parser->curr+1) == 't' && *(parser->curr+2) == ';') {
1319 parser->curr += 3;
1322 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
1325 if (len >= 3 && *(parser->curr+1) == 't' && *(parser->curr+2) == ';') {
1327 parser->curr += 3;
1330 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
1334 parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
1337 if (*(parser->curr+1) == 'm') {
1339 if (*(parser->curr+2) == 'p' && *(parser->curr+3) == ';') {
1341 parser->curr += 4;
1344 } else if (*(parser->curr+1) == 'p') {
1346 if (len > 4 && *(parser->curr+2) == 'o' && *(parser->curr+3) == 's' && *(parser->curr+4) == ';') {
1348 parser->curr += 5;
1352 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
1355 if (len >= 6 && *(parser->curr+1) == 'u' && *(parser->curr+2) == 'o' && *(parser->curr+3) == 't' && *(parser->curr+4) == 'e' && *(parser->curr+5) == ';') {
1357 parser->curr += 6;
1360 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
1367 parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
1370 parser->curr ++;
1371 if (*(parser->curr) == 'x') {
1373 parser->curr ++;
1375 while (parser->curr < parser->end) {
1376 ch = *(parser->curr);
1379 parser->curr ++;
1387 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(parser));
1394 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(parser));
1398 parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
1402 parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
1412 static Boolean parsePCData(CFXMLParserRef parser) {
1415 _inputStreamSetMark(&parser->input);
1416 while (!done && _inputStreamGetCharacter(&parser->input, &ch)) {
1420 _inputStreamReturnCharacter(&parser->input, ch);
1426 if (_inputStreamMatchString(&parser->input, endSequence, 2)) {
1427 _CFReportError(parser, kCFXMLErrorMalformedParsedCharacterData, "Encountered \"]]>\" in parsed character data");
1428 _inputStreamClearMark(&parser->input);
1437 _inputStreamGetCharactersFromMark(&parser->input, (CFMutableStringRef)(parser->node->dataString));
1438 _inputStreamClearMark(&parser->input);
1439 parser->node->dataTypeID = kCFXMLNodeTypeText;
1440 parser->node->additionalData = NULL;
1441 return reportNewLeaf(parser);
1447 static Boolean parseCloseTag(CFXMLParserRef parser, CFStringRef tag) {
1453 if (_inputStreamMatchString(&parser->input, beginEndTag, 2) && _inputStreamScanXMLName(&parser->input, false, &closeTag) && closeTag == tag) {
1456 _inputStreamSkipWhitespace(&parser->input, NULL);
1457 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
1462 } else if (_inputStreamAtEOF(&parser->input)) {
1470 parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected EOF while parsing close tag for <%@>"), tag);
1471 parser->status = kCFXMLErrorUnexpectedEOF;
1472 if(parser->callBacks.handleError) INVOKE_CALLBACK3(parser->callBacks.handleError, parser, kCFXMLErrorUnexpectedEOF, parser->context.info);
1474 parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered malformed close tag for <%@>"), tag);
1475 parser->status = kCFXMLErrorMalformedCloseTag;
1476 if(parser->callBacks.handleError) INVOKE_CALLBACK3(parser->callBacks.handleError, parser, kCFXMLErrorMalformedCloseTag, parser->context.info);
1488 static Boolean parseTag(CFXMLParserRef parser) {
1495 if (!_inputStreamScanXMLName(&parser->input, false, &tagName)) {
1496 _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Encountered malformed start tag");
1500 _inputStreamSkipWhitespace(&parser->input, NULL);
1502 if (!parseAttributes(parser)) return false; // parsed directly into parser->argDict ; parseAttributes consumes any trailing whitespace
1503 data.attributes = parser->argDict;
1504 data.attributeOrder = parser->argArray;
1505 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
1506 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF");
1511 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
1512 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF");
1519 _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Encountered malformed start tag");
1523 if (*parser->top || parser->top == parser->stack) {
1524 CFStringRef oldStr = parser->node->dataString;
1525 parser->node->dataTypeID = kCFXMLNodeTypeElement;
1526 parser->node->dataString = tagName;
1527 parser->node->additionalData = &data;
1528 tag = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
1529 if (tag && parser->status == kCFXMLStatusParseInProgress) {
1530 INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *parser->top, tag, parser->context.info);
1532 parser->node->additionalData = NULL;
1533 parser->node->dataString = oldStr;
1534 if (parser->status != kCFXMLStatusParseInProgress) {
1536 _CFReportError(parser, parser->status, NULL);
1543 pushXMLNode(parser, tag);
1545 success = parseTagContent(parser);
1547 success = parseCloseTag(parser, tagName);
1550 parser->top --;
1553 INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, tag, parser->context.info);
1554 if (parser->status != kCFXMLStatusParseInProgress) {
1555 _CFReportError(parser, parser->status, NULL);
1568 static Boolean parseAttributeValue(CFXMLParserRef parser, CFMutableStringRef str) {
1570 Boolean success = _inputStreamGetCharacter(&parser->input, &quote);
1572 if (str) _inputStreamSetMark(&parser->input);
1573 while (_inputStreamGetCharacter(&parser->input, &ch) && ch != quote) {
1577 if (!parseEntityReference(parser, false)) {
1586 if (success && _inputStreamAtEOF(&parser->input)) {
1591 _inputStreamReturnCharacter(&parser->input, quote);
1592 _inputStreamGetCharactersFromMark(&parser->input, str);
1593 _inputStreamGetCharacter(&parser->input, &ch);
1595 _inputStreamClearMark(&parser->input);
1606 // Expects parser->curr to be at the first content character; will consume the trailing whitespace.
1607 Boolean parseAttributes(CFXMLParserRef parser) {
1612 if (_inputStreamPeekCharacter(&parser->input, &ch) == '>') {
1613 if (parser->argDict) {
1614 CFDictionaryRemoveAllValues(parser->argDict);
1615 CFArrayRemoveAllValues(parser->argArray);
1619 if (!parser->argDict) {
1620 parser->argDict = CFDictionaryCreateMutable(CFGetAllocator(parser), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1621 parser->argArray = CFArrayCreateMutable(CFGetAllocator(parser), 0, &kCFTypeArrayCallBacks);
1623 CFDictionaryRemoveAllValues(parser->argDict);
1624 CFArrayRemoveAllValues(parser->argArray);
1626 dict = parser->argDict;
1627 array = parser->argArray;
1628 while (!failure && _inputStreamPeekCharacter(&parser->input, &ch) && ch != '>' && ch != '/') {
1631 if (!_inputStreamScanXMLName(&parser->input, false, &key)) {
1636 _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Found repeated attribute");
1639 _inputStreamSkipWhitespace(&parser->input, NULL);
1640 if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '=') {
1644 _inputStreamSkipWhitespace(&parser->input, NULL);
1645 value = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
1646 if (!parseAttributeValue(parser, value)) {
1654 _inputStreamSkipWhitespace(&parser->input, NULL);
1658 _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Found illegal character while parsing element tag");
1660 } else if (_inputStreamAtEOF(&parser->input)) {
1661 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing element attributes");
1678 NOTE: This function assumes parser->stack has a valid top. I.e. the document pointer has already been created!
1680 static Boolean parseXML(CFXMLParserRef parser) {
1683 while (success && _inputStreamPeekCharacter(&parser->input, &ch)) {
1689 success = parseWhitespace(parser);
1692 _inputStreamGetCharacter(&parser->input, &ch);
1693 if (!_inputStreamGetCharacter(&parser->input, &ch)) {
1694 _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing top-level document");
1700 if (_inputStreamMatchString(&parser->input, dashes, 2)) {
1702 success = parseComment(parser, true);
1706 _CFReportError(parser, kCFXMLErrorMalformedDocument, "Encountered a second DTD");
1709 success = parseDTD(parser);
1714 success = parseProcessingInstruction(parser, true);
1718 _CFReportError(parser, kCFXMLErrorMalformedDocument, "Encountered second top-level element");
1721 _inputStreamReturnCharacter(&parser->input, ch);
1722 success = parseTag(parser);
1727 parser->status = kCFXMLErrorMalformedDocument;
1728 parser->errorString = ch < 256 ?
1729 CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected character 0x%x (\'%c\') at top-level"), ch, ch) :
1730 CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected Unicode character 0x%x at top-level"), ch);
1732 if (parser->callBacks.handleError) {
1733 INVOKE_CALLBACK3(parser->callBacks.handleError, parser, parser->status, parser->context.info);
1742 _CFReportError(parser, kCFXMLErrorElementlessDocument, "No element found in document");
1748 static void _CFReportError(CFXMLParserRef parser, CFXMLParserStatusCode errNum, const char *str) {
1750 parser->status = errNum;
1751 parser->errorString = CFStringCreateWithCString(CFGetAllocator(parser), str, kCFStringEncodingASCII);
1753 if (parser->callBacks.handleError) {
1754 INVOKE_CALLBACK3(parser->callBacks.handleError, parser, errNum, parser->context.info);
1758 // Assumes parser->node has been set and is ready to go
1759 static Boolean reportNewLeaf(CFXMLParserRef parser) {
1761 if (*(parser->top) == NULL) return true;
1763 xmlStruct = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
1764 if (xmlStruct && parser->status == kCFXMLStatusParseInProgress) {
1765 INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *(parser->top), xmlStruct, parser->context.info);
1766 if (parser->status == kCFXMLStatusParseInProgress) INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, xmlStruct, parser->context.info);
1768 if (parser->status != kCFXMLStatusParseInProgress) {
1769 _CFReportError(parser, parser->status, NULL);
1775 static void pushXMLNode(CFXMLParserRef parser, void *node) {
1776 parser->top ++;
1777 if ((unsigned)(parser->top - parser->stack) == parser->capacity) {
1778 parser->stack = (void **)CFAllocatorReallocate(CFGetAllocator(parser), parser->stack, 2 * parser->capacity * sizeof(void *), 0);
1779 parser->top = parser->stack + parser->capacity;
1780 parser->capacity = 2*parser->capacity;
1782 *(parser->top) = node;
1789 static void *_XMLTreeCreateXMLStructure(CFXMLParserRef parser, CFXMLNodeRef node, void *context) {
1790 CFXMLNodeRef myNode = CFXMLNodeCreateCopy(CFGetAllocator(parser), node);
1791 CFXMLTreeRef tree = CFXMLTreeCreateWithNode(CFGetAllocator(parser), myNode);
1796 static void _XMLTreeAddChild(CFXMLParserRef parser, void *parent, void *child, void *context) {
1800 static void _XMLTreeEndXMLStructure(CFXMLParserRef parser, void *xmlType, void *context) {
1807 CFXMLParserRef parser;
1818 parser = CFXMLParserCreateWithDataFromURL(allocator, dataSource, parseOptions, version, &callbacks, NULL);
1820 if (CFXMLParserParse(parser)) {
1821 result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
1823 result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
1827 CFRelease(parser);
1841 CFXMLParserRef parser;
1853 parser = CFXMLParserCreate(allocator, xmlData, dataSource, parseOptions, parserVersion, &callbacks, NULL);
1855 if (CFXMLParserParse(parser)) {
1856 result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
1865 rawnum = CFXMLParserGetLocation(parser);
1872 rawnum = CFXMLParserGetLineNumber(parser);
1879 rawnum = CFXMLParserGetStatusCode(parser);
1886 errstring = CFXMLParserCopyErrorDescription(parser);
1893 result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
1897 CFRelease(parser);