/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFXMLParser.c
	Copyright 1999-2002, Apple, Inc. All rights reserved.
	Responsibility: Chris Parker
*/

#include <CoreFoundation/CFXMLParser.h>
#include <CoreFoundation/CFNumber.h>
#include "CFXMLInputStream.h"
#include "CFUniChar.h" 
#include "CFInternal.h"

struct __CFXMLParser {
    CFRuntimeBase _cfBase;

    _CFXMLInputStream input;
    
    void **stack;
    void **top;
    UInt32 capacity;

    struct __CFXMLNode *node;  // Our private node; we use it to report back information
    CFMutableDictionaryRef argDict;
    CFMutableArrayRef argArray;

    UInt32 options;
    CFXMLParserCallBacks callBacks;
    CFXMLParserContext context;

    CFXMLParserStatusCode status;
    CFStringRef errorString;
};

static CFStringRef __CFXMLParserCopyDescription(CFTypeRef cf) {
    const struct __CFXMLParser *parser = (const struct __CFXMLParser *)cf;
    return CFStringCreateWithFormat(CFGetAllocator(cf), NULL, CFSTR("<CFXMLParser %p>"), parser);
}

static void __CFXMLParserDeallocate(CFTypeRef cf) {
    struct __CFXMLParser *parser = (struct __CFXMLParser *)cf;
    CFAllocatorRef alloc = CFGetAllocator(parser);
    _freeInputStream(&(parser->input));
    if (parser->argDict) CFRelease(parser->argDict);
    if (parser->argArray) CFRelease(parser->argArray);
    if (parser->errorString) CFRelease(parser->errorString);
    if (parser->node) CFRelease(parser->node);
    CFAllocatorDeallocate(alloc, parser->stack);
    if (parser->context.info && parser->context.release) {
        parser->context.release(parser->context.info);
    }
}

static CFTypeID __kCFXMLParserTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFXMLParserClass = {
    0,
    "CFXMLParser",
    NULL,      // init
    NULL,      // copy
    __CFXMLParserDeallocate,
    NULL,
    NULL,
    NULL,      // 
    __CFXMLParserCopyDescription
};

static void __CFXMLParserInitialize(void) {
    __kCFXMLParserTypeID = _CFRuntimeRegisterClass(&__CFXMLParserClass);
}

CFTypeID CFXMLParserGetTypeID(void) {
    if (_kCFRuntimeNotATypeID == __kCFXMLParserTypeID) __CFXMLParserInitialize();
    return __kCFXMLParserTypeID;
}

void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context) {
    CFAssert1(parser != NULL, __kCFLogAssertion, "%s(): NULL parser not permitted", __PRETTY_FUNCTION__);
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    if (context) {
	context->version = parser->context.version;
	context->info = parser->context.info;
	context->retain = parser->context.retain;
	context->release = parser->context.release;
	context->copyDescription = parser->context.copyDescription;
	UNFAULT_CALLBACK(context->retain);
	UNFAULT_CALLBACK(context->release);
	UNFAULT_CALLBACK(context->copyDescription);
    }
}

void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    if (callBacks) {
        callBacks->version = parser->callBacks.version;
        callBacks->createXMLStructure = parser->callBacks.createXMLStructure;
        callBacks->addChild = parser->callBacks.addChild;
        callBacks->endXMLStructure = parser->callBacks.endXMLStructure;
        callBacks->resolveExternalEntity = parser->callBacks.resolveExternalEntity;
        callBacks->handleError = parser->callBacks.handleError;
	UNFAULT_CALLBACK(callBacks->createXMLStructure);
	UNFAULT_CALLBACK(callBacks->addChild);
	UNFAULT_CALLBACK(callBacks->endXMLStructure);
	UNFAULT_CALLBACK(callBacks->resolveExternalEntity);
	UNFAULT_CALLBACK(callBacks->handleError);
    }
}

CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    return parser->input.url;
}

/* Returns the character index or line number of the current parse location */
CFIndex CFXMLParserGetLocation(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    return _inputStreamCurrentLocation(&parser->input);
}

CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    return _inputStreamCurrentLine(&parser->input);
}

/* Returns the top-most object returned by the createXMLStructure callback */
void *CFXMLParserGetDocument(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    if (parser->capacity > 0)
        return parser->stack[0];
    else
        return NULL;
}

CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    return parser->status;
}

CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    return (CFStringRef)CFRetain(parser->errorString);
}

void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription) {
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    CFAssert1(errorCode > 0, __kCFLogAssertion, "%s(): errorCode must be greater than zero", __PRETTY_FUNCTION__);
    CFAssert1(errorDescription != NULL, __kCFLogAssertion, "%s(): errorDescription may not be NULL", __PRETTY_FUNCTION__);
    __CFGenericValidateType(errorDescription, CFStringGetTypeID());

    parser->status = errorCode;
    if (parser->errorString) CFRelease(parser->errorString);
    parser->errorString = (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, errorDescription);
}


static Boolean parseXML(CFXMLParserRef parser);
static Boolean parseComment(CFXMLParserRef parser, Boolean report);
static Boolean parseProcessingInstruction(CFXMLParserRef parser, Boolean report);
static Boolean parseInlineDTD(CFXMLParserRef parser);
static Boolean parseDTD(CFXMLParserRef parser);
static Boolean parsePhysicalEntityReference(CFXMLParserRef parser);
static Boolean parseCDSect(CFXMLParserRef parser);
static Boolean parseEntityReference(CFXMLParserRef parser, Boolean report);
static Boolean parsePCData(CFXMLParserRef parser);
static Boolean parseWhitespace(CFXMLParserRef parser);
static Boolean parseAttributeListDeclaration(CFXMLParserRef parser);
static Boolean parseNotationDeclaration(CFXMLParserRef parser);
static Boolean parseElementDeclaration(CFXMLParserRef parser);
static Boolean parseEntityDeclaration(CFXMLParserRef parser);
static Boolean parseExternalID(CFXMLParserRef parser, Boolean alsoAcceptPublicID, CFXMLExternalID *extID);
static Boolean parseCloseTag(CFXMLParserRef parser, CFStringRef tag);
static Boolean parseTagContent(CFXMLParserRef parser);
static Boolean parseTag(CFXMLParserRef parser);
static Boolean parseAttributes(CFXMLParserRef parser);
static Boolean parseAttributeValue(CFXMLParserRef parser, CFMutableStringRef str);

// Utilities; may need to make these accessible to the property list parser to avoid code duplication
static void _CFReportError(CFXMLParserRef parser, CFXMLParserStatusCode errNum, const char *str);
static Boolean reportNewLeaf(CFXMLParserRef parser); // Assumes parser->node has been set and is ready to go
static void pushXMLNode(CFXMLParserRef parser, void *node);

static CFXMLParserRef __CFXMLParserInit(CFAllocatorRef alloc, CFURLRef dataSource, CFOptionFlags options, CFDataRef xmlData, CFIndex version, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) {
    struct __CFXMLParser *parser = (struct __CFXMLParser *)_CFRuntimeCreateInstance(alloc, CFXMLParserGetTypeID(), sizeof(struct __CFXMLParser) - sizeof(CFRuntimeBase), NULL);
    struct __CFXMLNode *node = (struct __CFXMLNode *)_CFRuntimeCreateInstance(alloc, CFXMLNodeGetTypeID(), sizeof(struct __CFXMLNode) - sizeof(CFRuntimeBase), NULL);
    UniChar *buf;
    if (parser && node) {
        alloc = CFGetAllocator(parser);
        _initializeInputStream(&(parser->input), alloc, dataSource, xmlData);
        parser->top = parser->stack;
        parser->stack = NULL;
        parser->capacity = 0;

        buf = (UniChar *)CFAllocatorAllocate(alloc, 128*sizeof(UniChar), 0);
        parser->node = node;
        parser->node->dataString = CFStringCreateMutableWithExternalCharactersNoCopy(alloc, buf, 0, 128, alloc);
        parser->node->additionalData = NULL;
        parser->node->version = version;
        parser->argDict = NULL; // don't create these until necessary
        parser->argArray = NULL;

        parser->options = options;
        parser->callBacks = *callBacks;

        FAULT_CALLBACK((void **)&(parser->callBacks.createXMLStructure));
        FAULT_CALLBACK((void **)&(parser->callBacks.addChild));
        FAULT_CALLBACK((void **)&(parser->callBacks.endXMLStructure));
        FAULT_CALLBACK((void **)&(parser->callBacks.resolveExternalEntity));
        FAULT_CALLBACK((void **)&(parser->callBacks.handleError));
        
        if (context) {
            parser->context = *context;
            if (parser->context.info && parser->context.retain) {
                parser->context.retain(parser->context.info);
            }
        } else {
            parser->context.version = 0;
            parser->context.info = NULL;
            parser->context.retain = NULL;
            parser->context.release = NULL;
            parser->context.copyDescription = NULL;
        }
        parser->status = kCFXMLStatusParseNotBegun;
        parser->errorString = NULL;
    } else {
        if (parser) CFRelease(parser);
        if (node) CFRelease(node);
        parser = NULL;
    }
    return parser;
}

CFXMLParserRef CFXMLParserCreate(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) {
    CFAssert1(xmlData != NULL, __kCFLogAssertion, "%s(): NULL data not permitted", __PRETTY_FUNCTION__);
    __CFGenericValidateType(xmlData, CFDataGetTypeID());
    CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__);
    CFAssert1(callBacks != NULL && callBacks->createXMLStructure != NULL && callBacks->addChild != NULL && callBacks->endXMLStructure != NULL, __kCFLogAssertion, "%s(): callbacks createXMLStructure, addChild, and endXMLStructure must all be non-NULL", __PRETTY_FUNCTION__);
    CFAssert2(versionOfNodes <= 1, __kCFLogAssertion, "%s(): version number %d is higher than supported by CFXMLParser", __PRETTY_FUNCTION__, versionOfNodes);
    CFAssert1(versionOfNodes != 0, __kCFLogAssertion, "%s(): version number 0 is no longer supported by CFXMLParser", __PRETTY_FUNCTION__);
    return __CFXMLParserInit(allocator, dataSource, parseOptions, xmlData, versionOfNodes, callBacks, context);
}

CFXMLParserRef CFXMLParserCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) {
    CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__);
    CFAssert1(callBacks != NULL && callBacks->createXMLStructure != NULL && callBacks->addChild != NULL && callBacks->endXMLStructure != NULL, __kCFLogAssertion, "%s(): callbacks createXMLStructure, addChild, and endXMLStructure must all be non-NULL", __PRETTY_FUNCTION__);
    CFAssert2(versionOfNodes <= 1, __kCFLogAssertion, "%s(): version number %d is higher than supported by CFXMLParser", __PRETTY_FUNCTION__, versionOfNodes);
    CFAssert1(versionOfNodes != 0, __kCFLogAssertion, "%s(): version number 0 is no longer supported by CFXMLParser", __PRETTY_FUNCTION__);

    return __CFXMLParserInit(allocator, dataSource, parseOptions, NULL, versionOfNodes, callBacks, context);
}

Boolean CFXMLParserParse(CFXMLParserRef parser) {
    CFXMLDocumentInfo docData;
    __CFGenericValidateType(parser, CFXMLParserGetTypeID());
    if (parser->status != kCFXMLStatusParseNotBegun) return false;
    parser->status = kCFXMLStatusParseInProgress;

    if (!_openInputStream(&parser->input)) {
        if (!parser->input.data) {
            // couldn't load URL
            parser->status = kCFXMLErrorNoData;
            parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("No data found at %@"), CFURLGetString(parser->input.url));
        } else {
            // couldn't figure out the encoding
            CFAssert(parser->input.encoding == kCFStringEncodingInvalidId, __kCFLogAssertion, "CFXMLParser internal error: input stream could not be opened");
            parser->status = kCFXMLErrorUnknownEncoding;
            parser->errorString = CFStringCreateWithCString(CFGetAllocator(parser), "Encountered unknown encoding", kCFStringEncodingASCII);
        }
        if (parser->callBacks.handleError) {
            INVOKE_CALLBACK3(parser->callBacks.handleError, parser, parser->status, parser->context.info);
        }
        return false;
    }
    
    // Create the document
    parser->stack = (void **)CFAllocatorAllocate(CFGetAllocator(parser), 16 * sizeof(void *), 0);
    parser->capacity = 16;
    parser->node->dataTypeID = kCFXMLNodeTypeDocument;
    docData.encoding = _inputStreamGetEncoding(&parser->input);
    docData.sourceURL = parser->input.url;
    parser->node->additionalData = &docData;
    parser->stack[0] = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
    parser->top = parser->stack;
    parser->node->additionalData = NULL;

    // Client may have called CFXMLParserAbort() during any callback, so we must always check to see if we have an error status after a callback
    if (parser->status != kCFXMLStatusParseInProgress) {
        _CFReportError(parser, parser->status, NULL);
        return false;
    }
    return parseXML(parser);
}

/* 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. */

// [3]  S ::= (#x20 | #x9 | #xD | #xA)+ 
static Boolean parseWhitespace(CFXMLParserRef parser) {
    CFIndex len;
    Boolean report = !(parser->options & kCFXMLParserSkipWhitespace);
    len = _inputStreamSkipWhitespace(&parser->input, report ? (CFMutableStringRef)(parser->node->dataString) : NULL);
    if (report && len) {
        parser->node->dataTypeID = kCFXMLNodeTypeWhitespace;
        parser->node->additionalData = NULL;
        return reportNewLeaf(parser);
    } else {
        return true;
    }
}

// parser should be just past "<!--"
static Boolean parseComment(CFXMLParserRef parser, Boolean report) {
    const UniChar dashes[2] = {'-', '-'};
    UniChar ch;
    report = report && (!(parser->options & kCFXMLParserSkipMetaData));
    if (!_inputStreamScanToCharacters(&parser->input, dashes, 2, report ? (CFMutableStringRef)(parser->node->dataString) : NULL) || !_inputStreamGetCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF,"Found unexpected EOF while parsing comment");
        return false;
    } else if (ch != '>') {
        _CFReportError(parser, kCFXMLErrorMalformedComment, "Found \"--\" within a comment");
        return false;
    } else if (report) {
        parser->node->dataTypeID = kCFXMLNodeTypeComment;
        parser->node->additionalData = NULL;
        return reportNewLeaf(parser);
    } else {
        return true;
    }
}

/* 
[16] PI ::= '<?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'
[17] PITarget ::= Name - (('X' | 'x') ('M' | 'm') ('L' | 'l'))
 */
// parser should be set to the first character after "<?"
static Boolean parseProcessingInstruction(CFXMLParserRef parser, Boolean report) {
    const UniChar piTermination[2] = {'?', '>'};
    CFMutableStringRef str;
    CFStringRef name;
    
    if (!_inputStreamScanXMLName(&parser->input, false, &name)) {
        _CFReportError(parser, kCFXMLErrorMalformedProcessingInstruction, "Found malformed processing instruction");
        return false;
    }
    _inputStreamSkipWhitespace(&parser->input, NULL);
    str = (report && *parser->top) ? CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser)) : NULL;
    if (!_inputStreamScanToCharacters(&parser->input, piTermination, 2, str)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing processing instruction");
        if (str) CFRelease(str);
        return false;
    }

    if (str) {
        CFXMLProcessingInstructionInfo data;
        Boolean result;
        CFStringRef tmp = parser->node->dataString;
        parser->node->dataTypeID = kCFXMLNodeTypeProcessingInstruction;
        parser->node->dataString = name;
        data.dataString = str;
        parser->node->additionalData = &data;
        result = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
        CFRelease(str);
        return result;
    } else {
        return true;
    }
}

/*
 [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
*/
static const UniChar _DoctypeOpening[7] = {'D', 'O', 'C', 'T', 'Y', 'P', 'E'};
// first character should be immediately after the "<!"
static Boolean parseDTD(CFXMLParserRef parser) {
    UniChar ch;
    Boolean success, hasExtID = false;
    CFXMLDocumentTypeInfo docData = {{NULL, NULL}};
    void *dtdStructure = NULL;
    CFStringRef name;
    
    // First pass "DOCTYPE"
    success = _inputStreamMatchString(&parser->input, _DoctypeOpening, 7);
    success = success && _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
    success = success && _inputStreamScanXMLName(&parser->input, false, &name);
    if (success) {
        _inputStreamSkipWhitespace(&parser->input, NULL);
        success = _inputStreamPeekCharacter(&parser->input, &ch);
    } else {
        // didn't make it past "DOCTYPE" successfully.
        _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found malformed DTD");
        return false;
    }
    if (success && ch != '[' && ch != '>') {
        // ExternalID
        hasExtID = true;
        success = parseExternalID(parser, false, &(docData.externalID));
        if (success)  {
            _inputStreamSkipWhitespace(&parser->input, NULL);
            success = _inputStreamPeekCharacter(&parser->input, &ch);
        }
    }

    if (!(parser->options & kCFXMLParserSkipMetaData) && *(parser->top)) {
        CFStringRef tmp = parser->node->dataString;
        parser->node->dataTypeID = kCFXMLNodeTypeDocumentType;
        parser->node->dataString = name;
        parser->node->additionalData = &docData;
        dtdStructure = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
        if (dtdStructure && parser->status == kCFXMLStatusParseInProgress) {
            INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *parser->top, dtdStructure, parser->context.info);
        }
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
        if (parser->status != kCFXMLStatusParseInProgress) {
            // callback called CFXMLParserAbort()
            _CFReportError(parser, parser->status, NULL);
            return false;
        }
    } else {
        dtdStructure = NULL;
    }
    if (docData.externalID.publicID) CFRelease(docData.externalID.publicID);
    if (docData.externalID.systemID) CFRelease(docData.externalID.systemID);
    pushXMLNode(parser, dtdStructure);

    if (success && ch == '[')  {
        // inline DTD
        _inputStreamGetCharacter(&parser->input, &ch);
        if (!parseInlineDTD(parser)) return false;
        _inputStreamSkipWhitespace(&parser->input, NULL);
        success = _inputStreamGetCharacter(&parser->input, &ch) && ch == '>';
    } else if (success && ch == '>') {
        // End of the DTD
        _inputStreamGetCharacter(&parser->input, &ch);
    }
    if (!success) {
        if (_inputStreamAtEOF(&parser->input)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing DTD");
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found malformed DTD");
        }
        return false;
    }

    parser->top --; // Remove dtdStructure from the stack

    if (success && dtdStructure) {
        INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, dtdStructure, parser->context.info);
        if (parser->status != kCFXMLStatusParseInProgress) {
            _CFReportError(parser, parser->status, NULL);
            return false;
        }
    }
    return true;
}

/*
 [69] PEReference ::= '%' Name ';'
*/
static Boolean parsePhysicalEntityReference(CFXMLParserRef parser) {
    UniChar ch;
    CFStringRef name;
    if (!_inputStreamScanXMLName(&parser->input, false, &name)) {
        _CFReportError(parser, kCFXMLErrorMalformedName, "Found malformed name while parsing physical entity reference");
        return false;
    } else if (!_inputStreamGetCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing physical entity reference");
        return false;
    } else if (ch != ';') {
        _CFReportError(parser, kCFXMLErrorMalformedName, "Found malformed name while parsing physical entity reference");
        return false;
    } else if (!(parser->options & kCFXMLParserSkipMetaData) && *(parser->top)) {
        CFXMLEntityReferenceInfo myData;
        Boolean result;
        CFStringRef tmp = parser->node->dataString;
        parser->node->dataTypeID = kCFXMLNodeTypeEntityReference;
        parser->node->dataString = name;
        myData.entityType = kCFXMLEntityTypeParameter;
        parser->node->additionalData = &myData;
        result = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
        return result;
    } else {
        return true;
    }
}

/*
 [54] AttType ::= StringType | TokenizedType | EnumeratedType
 [55] StringType ::= 'CDATA'
 [56] TokenizedType ::= 'ID' | 'IDREF'| 'IDREFS'| 'ENTITY'| 'ENTITIES'| 'NMTOKEN'| 'NMTOKENS'
 [57] EnumeratedType ::= NotationType | Enumeration
 [58] NotationType ::= 'NOTATION' S '(' S? Name (S? '|' S? Name)* S? ')'
 [59] Enumeration ::= '(' S? Nmtoken (S? '|' S? Nmtoken)* S? ')'
*/
static Boolean parseEnumeration(CFXMLParserRef parser, Boolean useNMTokens) {
    UniChar ch;
    Boolean done = false;
    if (!_inputStreamGetCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
        return false;
    } else if (ch != '(') {
        _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        return false;
    }
    _inputStreamSkipWhitespace(&parser->input, NULL);
    if (!_inputStreamScanXMLName(&parser->input, useNMTokens, NULL)) {
        _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        return false;
    }
    while (!done) {
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamGetCharacter(&parser->input, &ch)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
            return false;
        } else if (ch == ')') {
            done = true;
        } else if (ch == '|') {
            _inputStreamSkipWhitespace(&parser->input, NULL);
            if (!_inputStreamScanXMLName(&parser->input, useNMTokens, NULL)) {
                _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
                return false;
            }
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            return false;
        }
    }
    return true;
}

static Boolean parseAttributeType(CFXMLParserRef parser, CFMutableStringRef str) {
    Boolean success = false;
    static const UniChar attTypeStrings[6][8] = {
    {'C', 'D', 'A', 'T', 'A', '\0', '\0', '\0'},
    {'I', 'D', 'R', 'E', 'F', 'S', '\0', '\0'},
    {'E', 'N', 'T', 'I', 'T', 'Y', '\0', '\0'},
    {'E', 'N', 'T', 'I', 'T', 'I', 'E', 'S'},
    {'N', 'M', 'T', 'O', 'K', 'E', 'N', 'S'},
    {'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N'} };
    if (str) _inputStreamSetMark(&parser->input);
    if (_inputStreamMatchString(&parser->input, attTypeStrings[0], 5) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[1], 6) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[1], 5) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[1], 2) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[2], 6) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[3], 8) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[4], 8) ||
        _inputStreamMatchString(&parser->input, attTypeStrings[4], 7)) {
        success = true;
    } else if (_inputStreamMatchString(&parser->input, attTypeStrings[5], 8)) {
        // Notation
        if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            success = false;
        } else  {
            success = parseEnumeration(parser, false);
        }
    } else {
        success = parseEnumeration(parser, true);
    }
    if (str) {
        if (success) {
            _inputStreamGetCharactersFromMark(&parser->input, str);
        }
        _inputStreamClearMark(&parser->input);
    }
    return success;
}

/*  [60] DefaultDecl ::= '#REQUIRED' | '#IMPLIED' | (('#FIXED' S)? AttValue) */
static Boolean parseAttributeDefaultDeclaration(CFXMLParserRef parser, CFMutableStringRef str) {
    const UniChar strings[3][8] = {
    {'R', 'E', 'Q', 'U', 'I', 'R', 'E', 'D'},
    {'I', 'M', 'P', 'L', 'I', 'E', 'D', '\0'},
    {'F', 'I', 'X', 'E', 'D', '\0', '\0', '\0'}};
    UniChar ch;
    Boolean success;
    if (str) _inputStreamSetMark(&parser->input);
    if (!_inputStreamGetCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
        success = false;
    } else if (ch == '#') {
        if (_inputStreamMatchString(&parser->input, strings[0], 8) ||
            _inputStreamMatchString(&parser->input, strings[1], 7)) {
            success = true;
        } else if (!_inputStreamMatchString(&parser->input, strings[2], 5) || _inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            success = false;
        } else {
            // we fall through if "#FIXED" was matched, and at least one whitespace character was stripped.
            success = parseAttributeValue(parser, NULL);
        }
    } else {
        _inputStreamReturnCharacter(&parser->input, ch);
        success = parseAttributeValue(parser, NULL);
    }
    if (str) {
        if (success) {
            _inputStreamGetCharactersFromMark(&parser->input, str);
        }
        _inputStreamClearMark(&parser->input);
    }
    return success;
}

/*
 [52] AttlistDecl ::= '<!ATTLIST' S Name AttDef* S? '>'
 [53] AttDef ::= S Name S AttType S DefaultDecl
*/
static Boolean parseAttributeListDeclaration(CFXMLParserRef parser) {
    const UniChar attList[7] = {'A', 'T', 'T', 'L', 'I', 'S', 'T'};
    CFXMLAttributeListDeclarationInfo attListData;
    CFXMLAttributeDeclarationInfo attributeArray[8], *attributes=attributeArray;
    CFIndex capacity = 8;
    UniChar ch;
    Boolean success = true;
    CFStringRef name;
    if (!_inputStreamMatchString(&parser->input, attList, 7) ||
        _inputStreamSkipWhitespace(&parser->input, NULL) == 0 ||
        !_inputStreamScanXMLName(&parser->input, false, &name)) {
        _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        return false;
    }
    attListData.numberOfAttributes = 0;
    if (!(*parser->top) || (parser->options & kCFXMLParserSkipMetaData)) {
        // Use this to mark that we don't need to collect attribute information to report to the client.  Ultimately, we may want to collect this for our own use (for validation, for instance), but for now, the only reason we would create it would be for the client.  -- REW, 2/9/2000
        attributes = NULL;
    }
    while (_inputStreamPeekCharacter(&parser->input, &ch) && ch != '>' && _inputStreamSkipWhitespace(&parser->input, NULL) != 0) {
        CFXMLAttributeDeclarationInfo *attribute = NULL;
        if (_inputStreamPeekCharacter(&parser->input, &ch) && ch == '>')
            break;
        if (attributes) {
            if (capacity == attListData.numberOfAttributes) {
                capacity = 2*capacity;
                if (attributes != attributeArray) {
                    attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorReallocate(CFGetAllocator(parser), attributes, capacity * sizeof(CFXMLAttributeDeclarationInfo), 0);
                } else {
                    attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(CFGetAllocator(parser), capacity * sizeof(CFXMLAttributeDeclarationInfo), 0);
                }
            }
            attribute = &(attributes[attListData.numberOfAttributes]);
            // Much better if we can somehow create these strings immutable - then if the client (or we ourselves) has to copy them, they will end up multiply-retained, rather than having a new alloc and data copy performed.  -- REW, 2/9/2000
            attribute->typeString = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
            attribute->defaultString = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
        }
        if (!_inputStreamScanXMLName(&parser->input, false, &(attribute->attributeName)) || (_inputStreamSkipWhitespace(&parser->input, NULL) == 0)) {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            success = false;
            break;
        }
        if (!parseAttributeType(parser, attribute ? (CFMutableStringRef)attribute->typeString : NULL)) {
            success = false;
            break;
        }
        if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0) {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            success = false;
            break;
        }
        if (!parseAttributeDefaultDeclaration(parser, attribute ? (CFMutableStringRef)attribute->defaultString : NULL)) {
            success = false;
            break;
        }
        attListData.numberOfAttributes ++;
    }
    if (success) {
        if (!_inputStreamGetCharacter(&parser->input, &ch)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
            success = false;
        } else if (ch != '>') {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            success = false;
        } else if (attributes) {
            CFStringRef tmp = parser->node->dataString;
            parser->node->dataTypeID = kCFXMLNodeTypeAttributeListDeclaration;
            parser->node->dataString = name;
            attListData.attributes = attributes;
            parser->node->additionalData = (void *)&attListData;
            success = reportNewLeaf(parser);
            parser->node->additionalData = NULL;
            parser->node->dataString = tmp;
        }
    }
    if (attributes) {
        // Free up all that memory
        CFIndex idx;
        for (idx = 0; idx < attListData.numberOfAttributes; idx ++) {
            // Do not release attributeName here; it's a uniqued string from scanXMLName
            CFRelease(attributes[idx].typeString);
            CFRelease(attributes[idx].defaultString);
        }
        if (attributes != attributeArray) {
            CFAllocatorDeallocate(CFGetAllocator(parser), attributes);
        }
    }
    return success;
}

CF_INLINE Boolean parseSystemLiteral(CFXMLParserRef parser, CFXMLExternalID *extID) {
    Boolean success;
    if (extID) {
        CFMutableStringRef urlStr = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
        if (_inputStreamScanQuotedString(&parser->input, urlStr)) {
            success = true;
            extID->systemID = CFURLCreateWithString(CFGetAllocator(parser), urlStr, parser->input.url);
        } else {
            extID->systemID = NULL;
            success = false;
        }
        CFRelease(urlStr);
    } else {
        success = _inputStreamScanQuotedString(&parser->input, NULL);
    }
    return success;
}

/*
 [75] ExternalID ::= 'SYSTEM' S SystemLiteral | 'PUBLIC' S PubidLiteral S SystemLiteral
 [83] PublicID ::= 'PUBLIC' S PubidLiteral
 [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'"
 [13] PubidChar ::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%]
 [11] SystemLiteral ::= ('"' [^"]* '"') | ("'" [^']* "'") 
*/
// 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
static Boolean parseExternalID(CFXMLParserRef parser, Boolean alsoAcceptPublicID, CFXMLExternalID *extID) {
    const UniChar publicString[6] = {'P', 'U', 'B', 'L', 'I', 'C'};
    const UniChar systemString[6] = {'S', 'Y', 'S', 'T', 'E', 'M'};
    Boolean success;
    if (extID) {
        extID->systemID = NULL;
        extID->publicID = NULL;
    }
    if (_inputStreamMatchString(&parser->input, publicString, 6)) {
        success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
        if (extID) {
            extID->publicID = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
            success = success && _inputStreamScanQuotedString(&parser->input, (CFMutableStringRef)extID->publicID);
        } else {
            success = success && _inputStreamScanQuotedString(&parser->input, NULL);
        }
        if (success) {
            UniChar ch;
            if (alsoAcceptPublicID) {
                _inputStreamSetMark(&parser->input); // In case we need to roll back the parser
            }
            if (_inputStreamSkipWhitespace(&parser->input, NULL) == 0
                || !_inputStreamPeekCharacter(&parser->input, &ch)
                || (ch != '\'' && ch != '\"')
                || !parseSystemLiteral(parser, extID)) {
                success = alsoAcceptPublicID;
                if (alsoAcceptPublicID) {
                    _inputStreamBackUpToMark(&parser->input);
                }
            } else {
                success = true;
            }
            if (alsoAcceptPublicID) {
                _inputStreamClearMark(&parser->input);
            }
        }
    } else if (_inputStreamMatchString(&parser->input, systemString, 6)) {
        success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0 && parseSystemLiteral(parser, extID);
    } else {
        success = false;
    }
    return success;
}

/*
 [82] NotationDecl ::= '<!NOTATION' S Name S (ExternalID |  PublicID) S? '>'
*/
static Boolean parseNotationDeclaration(CFXMLParserRef parser) {
    static UniChar notationString[8] = {'N', 'O', 'T', 'A', 'T', 'I', 'O', 'N'};
    Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
    CFXMLNotationInfo notationData = {{NULL, NULL}};
    CFStringRef name;
    Boolean success =
        _inputStreamMatchString(&parser->input, notationString, 8) &&
        _inputStreamSkipWhitespace(&parser->input, NULL) != 0 &&
        _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) &&
        _inputStreamSkipWhitespace(&parser->input, NULL) != 0 &&
        parseExternalID(parser, true, report ? &(notationData.externalID) : NULL);

    if (success) {
        UniChar ch;
        _inputStreamSkipWhitespace(&parser->input, NULL);
        success = (_inputStreamGetCharacter(&parser->input, &ch) && ch == '>');
    }
    if (!success) {
        if (_inputStreamAtEOF(&parser->input)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        }
    } else if (report) {
        CFStringRef tmp = parser->node->dataString;
        parser->node->dataTypeID = kCFXMLNodeTypeNotation;
        parser->node->dataString = name;
        parser->node->additionalData = &notationData;
        success = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
    }
    if (notationData.externalID.systemID) CFRelease(notationData.externalID.systemID);
    if (notationData.externalID.publicID) CFRelease(notationData.externalID.publicID);
    return success;
}

/*
 [48] cp ::= (Name | choice | seq) ('?' | '*' | '+')?
 [49] choice ::= '(' S? cp ( S? '|' S? cp )* S? ')'
 [50] seq ::= '(' S? cp ( S? ',' S? cp )* S? ')'
*/
static Boolean parseChoiceOrSequence(CFXMLParserRef parser, Boolean pastParen) {
    UniChar ch, separator;
    if (!pastParen) {
        if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '(') return false;
        _inputStreamSkipWhitespace(&parser->input, NULL);
    }
    if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;

    /* Now scanning cp, production [48] */
    if (ch == '(') {
        if (!parseChoiceOrSequence(parser, false)) return false;
    } else {
        if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
    }
    if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
    if (ch == '?' || ch == '*' || ch == '+') _inputStreamGetCharacter(&parser->input, &ch);

    /* Now past cp */
    _inputStreamSkipWhitespace(&parser->input, NULL);
    if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
    if (ch == ')') return true;
    if (ch != '|' && ch != ',') return false;
    separator = ch;
    while (ch == separator) {
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
        if (ch != '(') {
            if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
        } else if (!parseChoiceOrSequence(parser, false)) {
            return false;
        }
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
    }
    return ch == ')';
}

/*
 [51] Mixed ::= '(' S? '#PCDATA' (S? '|' S? Name)* S? ')*' | '(' S? '#PCDATA' S? ')'
*/
static Boolean parseMixedElementContent(CFXMLParserRef parser) {
    static const UniChar pcdataString[7] = {'#', 'P', 'C', 'D', 'A', 'T', 'A'};
    UniChar ch;
    if (!_inputStreamMatchString(&parser->input, pcdataString, 7)) return false;
    _inputStreamSkipWhitespace(&parser->input, NULL);
    if (!_inputStreamGetCharacter(&parser->input, &ch) && (ch == ')' || ch == '|')) return false;
    if (ch == ')') return true;

    while (ch == '|') {
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamScanXMLName(&parser->input, false, NULL)) return false;
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamGetCharacter(&parser->input, &ch)) return false;
    }
    if (ch != ')') return false;
    if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '*') return false;
    return true;
}

/*
 [46] contentspec ::= 'EMPTY' | 'ANY' | Mixed | children
 [47] children ::= (choice | seq) ('?' | '*' | '+')?
 */
static Boolean parseElementContentSpec(CFXMLParserRef parser) {
    static const UniChar eltContentEmpty[5] = {'E', 'M', 'P', 'T', 'Y'};
    static const UniChar eltContentAny[3] = {'A', 'N', 'Y'};
    UniChar ch;
    if (_inputStreamMatchString(&parser->input, eltContentEmpty, 5) || _inputStreamMatchString(&parser->input, eltContentAny, 3)) {
        return true;
    } else if (!_inputStreamPeekCharacter(&parser->input, &ch) || ch != '(') {
        return false;
    } else {
        // We want to know if we have a Mixed per production [51].  If we don't, we will need to back up and call the parseChoiceOrSequence function.  So we set the mark now.  -- REW, 2/10/2000
        _inputStreamGetCharacter(&parser->input, &ch);
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamPeekCharacter(&parser->input, &ch)) return false;
        if (ch == '#') {
            // Mixed
            return parseMixedElementContent(parser);
        } else {
            if (parseChoiceOrSequence(parser, true)) {
                if (_inputStreamPeekCharacter(&parser->input, &ch) && (ch == '*' || ch == '?' || ch == '+')) {
                    _inputStreamGetCharacter(&parser->input, &ch);
                }
                return true;
            } else {
                return false;
            }
        }
    }
}

/*
 [45] elementdecl ::= '<!ELEMENT' S Name S contentspec S? '>'
 */
static Boolean parseElementDeclaration(CFXMLParserRef parser) {
    Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
    Boolean success;
    static const UniChar eltChars[7] = {'E', 'L', 'E', 'M', 'E', 'N', 'T'};
    UniChar ch = '>';
    CFMutableStringRef contentDesc = NULL;
    CFStringRef name;
    success = _inputStreamMatchString(&parser->input, eltChars, 7)
        && _inputStreamSkipWhitespace(&parser->input, NULL) != 0
        && _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL)
        && _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
    if (success) {
        if (report) _inputStreamSetMark(&parser->input);
        success = parseElementContentSpec(parser);
        if (success && report) {
            contentDesc = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
            _inputStreamGetCharactersFromMark(&parser->input, contentDesc);
        }
        if (report) _inputStreamClearMark(&parser->input);
        if (success) _inputStreamSkipWhitespace(&parser->input, NULL);
        success = success && _inputStreamMatchString(&parser->input, &ch, 1);
    }
    if (!success) {
        if (_inputStreamAtEOF(&parser->input)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        }
    } else if (report) {
        CFXMLElementTypeDeclarationInfo eltData;
        CFStringRef tmp = parser->node->dataString;
        parser->node->dataTypeID = kCFXMLNodeTypeElementTypeDeclaration;
        parser->node->dataString = name;
        eltData.contentDescription = contentDesc;
        parser->node->additionalData = &eltData;
        success = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
    }
    if (contentDesc) CFRelease(contentDesc);
    return success;
}

/*
 [70] EntityDecl ::= GEDecl | PEDecl
 [71] GEDecl ::= '<!ENTITY' S Name S EntityDef S? '>'
 [72] PEDecl ::= '<!ENTITY' S '%' S Name S PEDef S? '>'
 [73] EntityDef ::= EntityValue | (ExternalID NDataDecl?)
 [74] PEDef ::= EntityValue | ExternalID
 [76] NDataDecl ::= S 'NDATA' S Name
 [9]  EntityValue ::= '"' ([^%&"] | PEReference | Reference)* '"' |  "'" ([^%&'] | PEReference | Reference)* "'"
*/
static Boolean parseEntityDeclaration(CFXMLParserRef parser) {
    const UniChar entityStr[6] = {'E', 'N', 'T', 'I', 'T', 'Y'};
    UniChar ch;
    Boolean isPEDecl = false;
    CFXMLEntityInfo entityData;
    CFStringRef name;
    Boolean report = *(parser->top) && !(parser->options & kCFXMLParserSkipMetaData);
    Boolean success =
        _inputStreamMatchString(&parser->input, entityStr, 6) &&
        (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) &&
        _inputStreamPeekCharacter(&parser->input, &ch);

    entityData.replacementText = NULL;
    entityData.entityID.publicID = NULL;
    entityData.entityID.systemID = NULL;
    entityData.notationName = NULL;
    // We will set entityType immediately before reporting

    if (success && ch == '%') {
        _inputStreamGetCharacter(&parser->input, &ch);
        success = _inputStreamSkipWhitespace(&parser->input, NULL) != 0;
        isPEDecl = true;
    }
    success = success && _inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) && (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) && _inputStreamPeekCharacter(&parser->input, &ch);
    if (success && (ch == '\"' || ch == '\'')) {
        // EntityValue
        // This is not quite correct - the string scanned cannot contain '%' or '&' unless it's as part of a valid entity reference -- REW, 2/2/2000
        if (report) {
            entityData.replacementText = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
            success = _inputStreamScanQuotedString(&parser->input, (CFMutableStringRef)entityData.replacementText);
        } else {
            success = _inputStreamScanQuotedString(&parser->input, NULL);
        }
    } else if (success) {
        // ExternalID
        success = parseExternalID(parser, false, report ? &(entityData.entityID) : NULL);
        if (success && !isPEDecl && _inputStreamSkipWhitespace(&parser->input, NULL) != 0) {
            // There could be an option NDataDecl
            // Don't we need to set entityData.notationName? -- REW, 3/6/2000
            const UniChar nDataStr[5] = {'N', 'D', 'A', 'T', 'A'};
            if (_inputStreamMatchString(&parser->input, nDataStr, 5)) {
                success = (_inputStreamSkipWhitespace(&parser->input, NULL) != 0) && _inputStreamScanXMLName(&parser->input, false, NULL);
            }
        }
    }
    if (success) {
        _inputStreamSkipWhitespace(&parser->input, NULL);
        success = _inputStreamGetCharacter(&parser->input, &ch) && ch == '>';
    }
    if (!success) {
        if (_inputStreamAtEOF(&parser->input)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
        }
    } else {
        CFStringRef tmp = parser->node->dataString;
        if (isPEDecl) entityData.entityType = kCFXMLEntityTypeParameter;
        else if (entityData.replacementText) entityData.entityType = kCFXMLEntityTypeParsedInternal;
        else if (!entityData.notationName) entityData.entityType = kCFXMLEntityTypeParsedExternal;
        else entityData.entityType = kCFXMLEntityTypeUnparsed;
        parser->node->dataTypeID = kCFXMLNodeTypeEntity;
        parser->node->dataString = name;
        parser->node->additionalData = &entityData;
        success = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
        if (entityData.replacementText) CFRelease(entityData.replacementText);
    }
    if (entityData.entityID.publicID) CFRelease(entityData.entityID.publicID);
    if (entityData.entityID.systemID) CFRelease(entityData.entityID.systemID);
    return success;
}

/*
 [28] doctypedecl ::= '<!DOCTYPE' S Name (S ExternalID)? S? ('[' (markupdecl | PEReference | S)* ']' S?)? '>'
 [29] markupdecl ::= elementdecl | AttlistDecl | EntityDecl | NotationDecl | PI | Comment 
*/ 
// First character should be just past '['
static Boolean parseInlineDTD(CFXMLParserRef parser) {
    Boolean success = true;
    while (success && !_inputStreamAtEOF(&parser->input)) {
        UniChar ch;

        parseWhitespace(parser);
        if (!_inputStreamGetCharacter(&parser->input, &ch)) break;
        if (ch == '%') {
            // PEReference
            success = parsePhysicalEntityReference(parser);
        } else if (ch == '<') {
            // markupdecl
            if (!_inputStreamGetCharacter(&parser->input, &ch)) {
                _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
                return false;
            }
            if (ch == '?') {
                // Processing Instruction
                success = parseProcessingInstruction(parser, true); // We can safely pass true here, because *parser->top will be NULL if kCFXMLParserSkipMetaData is true
            } else if (ch == '!') {
                UniChar dashes[2] = {'-', '-'};
                if (_inputStreamMatchString(&parser->input, dashes, 2)) {
                    // Comment
                    success = parseComment(parser, true);
                } else {
                    // elementdecl | AttListDecl | EntityDecl | NotationDecl
                    if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
                        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
                        return false;
                    } else if (ch == 'A') {
                        // AttListDecl
                        success = parseAttributeListDeclaration(parser);
                    } else if (ch == 'N') {
                        success = parseNotationDeclaration(parser);
                    } else if (ch == 'E') {
                        // elementdecl | EntityDecl
                        _inputStreamGetCharacter(&parser->input, &ch);
                        if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
                            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
                            return false;
                        }
                        _inputStreamReturnCharacter(&parser->input, 'E');
                        if (ch == 'L') {
                            success = parseElementDeclaration(parser);
                        } else if (ch == 'N') {
                            success = parseEntityDeclaration(parser);
                        } else {
                            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
                            return false;
                        }
                    } else {
                        _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
                        return false;
                    }                        
                }
            } else {
                _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
                return false;
            }
        } else if (ch == ']') {
            return true;
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedDTD, "Found unexpected character while parsing inline DTD");
            return false;
        }
    }
    if (success) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Found unexpected EOF while parsing inline DTD");
    }
    return false;
}

/*
[43] content ::= (element | CharData | Reference | CDSect | PI | Comment)*
 */
static Boolean parseTagContent(CFXMLParserRef parser) {
    while (!_inputStreamAtEOF(&parser->input)) {
        UniChar ch;
        CFIndex numWhitespaceCharacters;
        
        _inputStreamSetMark(&parser->input);
        numWhitespaceCharacters = _inputStreamSkipWhitespace(&parser->input, NULL);
        // Don't report the whitespace yet; if the first thing we see is character data, we put the whitespace back and report it as part of the character data.
        if (!_inputStreamGetCharacter(&parser->input, &ch)) break;  // break == report unexpected EOF

        if (ch != '<' && ch != '&') { // CharData
            // Back off the whitespace; we'll report it with the PCData
            _inputStreamBackUpToMark(&parser->input);
            _inputStreamClearMark(&parser->input);
             if (!parsePCData(parser)) return false;
             if(_inputStreamComposingErrorOccurred(&parser->input)) {
                 _CFReportError(parser, kCFXMLErrorEncodingConversionFailure, "Encountered string encoding error");
                 return false;
             }
             continue;
        }

        // element | Reference | CDSect | PI | Comment
        // We can safely report any whitespace now
        if (!(parser->options & kCFXMLParserSkipWhitespace) && numWhitespaceCharacters != 0 && *(parser->top)) {
            _inputStreamReturnCharacter(&parser->input, ch);
            _inputStreamGetCharactersFromMark(&parser->input, (CFMutableStringRef)(parser->node->dataString));
            parser->node->dataTypeID = kCFXMLNodeTypeWhitespace;
            parser->node->additionalData = NULL;
            if (!reportNewLeaf(parser)) return false;
            _inputStreamGetCharacter(&parser->input, &ch);
        }
        _inputStreamClearMark(&parser->input);
        
        if (ch == '&') {
            // Reference; for the time being, we don't worry about processing these; just report them as Entity references
            if (!parseEntityReference(parser, true)) return false;
            continue;
        }

        // ch == '<'; element | CDSect | PI | Comment
        if (!_inputStreamPeekCharacter(&parser->input, &ch)) break;
        if (ch == '?') { // PI
            _inputStreamGetCharacter(&parser->input, &ch);
            if (!parseProcessingInstruction(parser, true))
                return false;
        } else if (ch == '/') { // end tag; we're passing outside of content's production
            _inputStreamReturnCharacter(&parser->input, '<'); // Back off to the '<'
            return true;
        } else if (ch != '!') { // element
            if (!parseTag(parser))  return false;
        } else {
            // Comment | CDSect
            UniChar dashes[3] = {'!', '-', '-'};
            if (_inputStreamMatchString(&parser->input, dashes, 3)) {
                // Comment
                if (!parseComment(parser, true)) return false;
            } else {
                // Should have a CDSect; back off the "<!" and call parseCDSect
                _inputStreamReturnCharacter(&parser->input, '<');
                if (!parseCDSect(parser)) return false;
            }
        }
    }

    if(_inputStreamComposingErrorOccurred(&parser->input)) {
        _CFReportError(parser, kCFXMLErrorEncodingConversionFailure, "Encountered string encoding error");
        return false;
    }
    // Only way to get here is if premature EOF was found
//#warning CF:Include the tag name here
    _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing tag content");
    return false;
}

static Boolean parseCDSect(CFXMLParserRef parser) {
    const UniChar _CDSectOpening[9] = {'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '['};
    const UniChar _CDSectClose[3] = {']', ']', '>'};
    if (!_inputStreamMatchString(&parser->input, _CDSectOpening, 9)) {
        _CFReportError(parser, kCFXMLErrorMalformedCDSect, "Encountered bad prefix to a presumed CDATA section");
        return false;
    }
    if (!_inputStreamScanToCharacters(&parser->input, _CDSectClose, 3, (CFMutableStringRef)(parser->node->dataString))) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing CDATA section");
        return false;
    }

    parser->node->dataTypeID = kCFXMLNodeTypeCDATASection;
    parser->node->additionalData = NULL;
    return reportNewLeaf(parser);
}

/*
 [66] CharRef ::= '&#' [0-9]+ ';' | '&#x' [0-9a-fA-F]+ ';'
*/
static Boolean validateCharacterReference(CFStringRef str) {
    Boolean isHex;
    CFIndex idx, len = CFStringGetLength(str);
    if (len < 2) return false;
    if (CFStringGetCharacterAtIndex(str, 0) != '#') return false;
    if (CFStringGetCharacterAtIndex(str, 1) == 'x') {
        isHex = true;
        idx = 2;
        if (len == 2) return false;
    } else {
        isHex = false;
        idx = 1;
    }

    while (idx < len) {
        UniChar ch;
        ch = CFStringGetCharacterAtIndex(str, idx);
        idx ++;
        if (!(ch <= '9' && ch >= '0') &&
            !(isHex && ((ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F')))) {
            break;
        }
    }
    return (idx == len);
}

/*
 [67] Reference ::= EntityRef | CharRef
 [68] EntityRef ::= '&' Name ';'
*/
static Boolean parseEntityReference(CFXMLParserRef parser, Boolean report) {
    UniChar ch;
    CFXMLEntityReferenceInfo entData;
    CFStringRef name = NULL;
    if (!_inputStreamPeekCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
        return false;
    }
    if (ch == '#') {
        ch = ';';
        if (!_inputStreamScanToCharacters(&parser->input, &ch, 1, (CFMutableStringRef)parser->node->dataString)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
            return false;
        } else if (!validateCharacterReference(parser->node->dataString)) {
            _CFReportError(parser, kCFXMLErrorMalformedCharacterReference, "Encountered illegal character while parsing character reference");
            return false;
        }
        entData.entityType = kCFXMLEntityTypeCharacter;
        name = parser->node->dataString;
    } else if (!_inputStreamScanXMLName(&parser->input, false, report ? &name : NULL) || !_inputStreamGetCharacter(&parser->input, &ch) || ch != ';') {
        if (_inputStreamAtEOF(&parser->input)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing EntityReference");
            return false;
        } else {
            _CFReportError(parser, kCFXMLErrorMalformedName, "Encountered malformed name while parsing EntityReference");
            return false;
        }
    } else {
        entData.entityType = kCFXMLEntityTypeParsedInternal;
    }
    if (report) {
        CFStringRef tmp = parser->node->dataString;
        Boolean success;
        parser->node->dataTypeID = kCFXMLNodeTypeEntityReference;
        parser->node->dataString = name;
        parser->node->additionalData = &entData;
        success = reportNewLeaf(parser);
        parser->node->additionalData = NULL;
        parser->node->dataString = tmp;
        return success;
    } else {
        return true;
    }
}

#if 0
// Kept from old entity reference parsing....
{
    switch (*(parser->curr)) {
        case 'l':  // "lt"
            if (len >= 3 && *(parser->curr+1) == 't' && *(parser->curr+2) == ';') {
                ch = '<';
                parser->curr += 3;
                break;
            }
            parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
            return;
        case 'g': // "gt"
            if (len >= 3 && *(parser->curr+1) == 't' && *(parser->curr+2) == ';') {
                ch = '>';
                parser->curr += 3;
                break;
            }
            parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
            return;
        case 'a': // "apos" or "amp"
            if (len < 4) {   // Not enough characters for either conversion
                parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
                return;
            }
            if (*(parser->curr+1) == 'm') {
                // "amp"
                if (*(parser->curr+2) == 'p' && *(parser->curr+3) == ';') {
                    ch = '&';
                    parser->curr += 4;
                    break;
                }
            } else if (*(parser->curr+1) == 'p') {
                // "apos"
                if (len > 4 && *(parser->curr+2) == 'o' && *(parser->curr+3) == 's' && *(parser->curr+4) == ';') {
                    ch = '\'';
                    parser->curr += 5;
                    break;
                }
            }
            parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
            return;
        case 'q':  // "quote"
            if (len >= 6 && *(parser->curr+1) == 'u' && *(parser->curr+2) == 'o' && *(parser->curr+3) == 't' && *(parser->curr+4) == 'e' && *(parser->curr+5) == ';') {
                ch = '\"';
                parser->curr += 6;
                break;
            }
            parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
            return;
        case '#':
        {
            UniChar num = 0;
            Boolean isHex = false;
            if ( len < 4) {  // Not enough characters to make it all fit!  Need at least "&#d;"
                parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
                return;
            }
            parser->curr ++;
            if (*(parser->curr) == 'x') {
                isHex = true;
                parser->curr ++;
            }
            while (parser->curr < parser->end) {
                ch = *(parser->curr);
                if (ch == ';') {
                    CFStringAppendCharacters(string, &num, 1);
                    parser->curr ++;
                    return;
                }
                if (!isHex) num = num*10;
                else num = num << 4;
                if (ch <= '9' && ch >= '0') {
                    num += (ch - '0');
                } else if (!isHex) {
                    parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(parser));
                    return;
                } else if (ch >= 'a' && ch <= 'f') {
                    num += 10 + (ch - 'a');
                } else if (ch >= 'A' && ch <= 'F') {
                    num += 10 + (ch - 'A');
                } else {
                    parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(parser));
                    return;                    
                }
            }
            parser->errorString = CFStringCreateWithCString(parser->allocator, "Encountered unexpected EOF", kCFStringEncodingASCII);
            return;
        }
        default:
            parser->errorString = CFStringCreateWithFormat(parser->allocator, NULL, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(parser));
            return;
    }
    CFStringAppendCharacters(string, &ch, 1);
}
#endif

/*
[14] CharData ::= [^<&]* - ([^<&]* ']]>' [^<&]*)
*/
static Boolean parsePCData(CFXMLParserRef parser) {
    UniChar ch;
    Boolean done = false;
    _inputStreamSetMark(&parser->input);
    while (!done && _inputStreamGetCharacter(&parser->input, &ch)) {
        switch (ch) {
            case '<': 
            case '&':
                _inputStreamReturnCharacter(&parser->input, ch);
                done = true;
                break;
            case ']':
            {
                const UniChar endSequence[2] = {']', '>'};
                if (_inputStreamMatchString(&parser->input, endSequence, 2)) {
                    _CFReportError(parser, kCFXMLErrorMalformedParsedCharacterData, "Encountered \"]]>\" in parsed character data");
                    _inputStreamClearMark(&parser->input);
                    return false;
                }
                break;
            }
            default:
                ;
        }
    }
    _inputStreamGetCharactersFromMark(&parser->input, (CFMutableStringRef)(parser->node->dataString));
    _inputStreamClearMark(&parser->input);
    parser->node->dataTypeID = kCFXMLNodeTypeText;
    parser->node->additionalData = NULL;
    return reportNewLeaf(parser);
}

/*
[42] ETag ::= '</' Name S? '>'
 */
static Boolean parseCloseTag(CFXMLParserRef parser, CFStringRef tag) {
    const UniChar beginEndTag[2] = {'<', '/'};
    Boolean unexpectedEOF = false, mismatch = false;
    CFStringRef closeTag;

    // We can get away with testing pointer equality between tag & closeTag because scanXMLName guarantees the strings it returns are unique.
    if (_inputStreamMatchString(&parser->input, beginEndTag, 2) && _inputStreamScanXMLName(&parser->input, false, &closeTag) && closeTag == tag) {
        
        UniChar ch;
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamGetCharacter(&parser->input, &ch)) {
            unexpectedEOF = true;
        } else if (ch != '>') {
            mismatch = true;
        }
    } else if (_inputStreamAtEOF(&parser->input)) {
        unexpectedEOF = true;
    } else {
        mismatch = true;
    }
        
    if (unexpectedEOF || mismatch) {
        if (unexpectedEOF) {
            parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected EOF while parsing close tag for <%@>"), tag);
            parser->status = kCFXMLErrorUnexpectedEOF;
            if(parser->callBacks.handleError) INVOKE_CALLBACK3(parser->callBacks.handleError, parser, kCFXMLErrorUnexpectedEOF, parser->context.info);
        } else {
            parser->errorString = CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered malformed close tag for <%@>"), tag);
            parser->status = kCFXMLErrorMalformedCloseTag;
            if(parser->callBacks.handleError) INVOKE_CALLBACK3(parser->callBacks.handleError, parser, kCFXMLErrorMalformedCloseTag, parser->context.info);
        }
        return false;
    }
    return true;
}

/*
 [39] element ::= EmptyElementTag | STag content ETag
 [40] STag ::= '<' Name (S Attribute)* S? '>'
 [44] EmptyElemTag ::= '<' Name (S Attribute)* S? '/>'
*/
static Boolean parseTag(CFXMLParserRef parser) {
    UniChar ch;
    void *tag;
    CFXMLElementInfo data;
    Boolean success = true;
    CFStringRef tagName;

    if (!_inputStreamScanXMLName(&parser->input, false, &tagName)) {
        _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Encountered malformed start tag");
        return false;
    }

    _inputStreamSkipWhitespace(&parser->input, NULL);
    
    if (!parseAttributes(parser)) return false; // parsed directly into parser->argDict ; parseAttributes consumes any trailing whitespace
    data.attributes = parser->argDict;
    data.attributeOrder = parser->argArray;
    if (!_inputStreamGetCharacter(&parser->input, &ch)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF");
        return false;
    }
    if (ch == '/') {
        data.isEmpty = true;
        if (!_inputStreamGetCharacter(&parser->input, &ch)) {
            _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF");
            return false;
        }
    } else {
        data.isEmpty = false;
    }
    if (ch != '>') {
        _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Encountered malformed start tag");
        return false;
    }

    if (*parser->top || parser->top == parser->stack) {
        CFStringRef oldStr = parser->node->dataString;
	parser->node->dataTypeID = kCFXMLNodeTypeElement;
        parser->node->dataString = tagName;
	parser->node->additionalData = &data;
        tag = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
        if (tag && parser->status == kCFXMLStatusParseInProgress) {
            INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *parser->top, tag, parser->context.info);
        }
	parser->node->additionalData = NULL;
        parser->node->dataString = oldStr;
        if (parser->status != kCFXMLStatusParseInProgress) {
            // callback called CFXMLParserAbort()
            _CFReportError(parser, parser->status, NULL);
            return false;
        }
    } else {
        tag = NULL;
    }

    pushXMLNode(parser, tag);
    if (!data.isEmpty) {
        success =  parseTagContent(parser);
        if (success) {
            success = parseCloseTag(parser, tagName);
        }
    }
    parser->top --;

    if (success && tag) {
        INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, tag, parser->context.info);
        if (parser->status != kCFXMLStatusParseInProgress) {
            _CFReportError(parser, parser->status, NULL);
            return false;
        }
    }
    return success;
}

/*
 [10] AttValue ::= '"' ([^<&"] | Reference)* '"' |  "'" ([^<&'] | Reference)* "'"
 [67] Reference ::= EntityRef | CharRef
 [68] EntityRef ::= '&' Name ';'
 */
// For the moment, we don't worry about references in the attribute values.
static Boolean parseAttributeValue(CFXMLParserRef parser, CFMutableStringRef str) {
    UniChar quote, ch;
    Boolean success = _inputStreamGetCharacter(&parser->input, &quote);
    if (!success || (quote != '\'' && quote != '\"')) return false;
    if (str) _inputStreamSetMark(&parser->input);
    while (_inputStreamGetCharacter(&parser->input, &ch) && ch != quote) {
        switch (ch) {
            case '<': success = false; break;
            case '&':
                if (!parseEntityReference(parser, false)) {
                    success = false;
                    break;
                }
            default:
                ;
        }
    }
    
    if (success && _inputStreamAtEOF(&parser->input)) {
        success = false;
    }
    if (str) {
        if (success) {
            _inputStreamReturnCharacter(&parser->input, quote);
            _inputStreamGetCharactersFromMark(&parser->input, str);
            _inputStreamGetCharacter(&parser->input, &ch);
        }
        _inputStreamClearMark(&parser->input);
    }
    return success;
}

/*
 [40] STag ::= '<' Name (S Attribute)* S? '>'
 [41] Attribute ::= Name Eq AttValue
 [25] Eq ::= S? '=' S?
*/

// Expects parser->curr to be at the first content character; will consume the trailing whitespace.  
Boolean parseAttributes(CFXMLParserRef parser) {
    UniChar ch;
    CFMutableDictionaryRef dict;
    CFMutableArrayRef array;
    Boolean failure = false;
    if (_inputStreamPeekCharacter(&parser->input, &ch) == '>') {
        if (parser->argDict) {
            CFDictionaryRemoveAllValues(parser->argDict);
            CFArrayRemoveAllValues(parser->argArray);
        }
        return true;  // No attributes; let caller deal with it
    }
    if (!parser->argDict) {
        parser->argDict = CFDictionaryCreateMutable(CFGetAllocator(parser), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
        parser->argArray = CFArrayCreateMutable(CFGetAllocator(parser), 0, &kCFTypeArrayCallBacks);
    } else {
        CFDictionaryRemoveAllValues(parser->argDict);
        CFArrayRemoveAllValues(parser->argArray);
    }
    dict = parser->argDict;
    array = parser->argArray; 
    while (!failure && _inputStreamPeekCharacter(&parser->input, &ch) && ch != '>' && ch != '/') {
        CFStringRef key;
        CFMutableStringRef value;
        if (!_inputStreamScanXMLName(&parser->input, false, &key)) {
            failure = true;
            break;
        }
        if (CFArrayGetFirstIndexOfValue(array, CFRangeMake(0, CFArrayGetCount(array)), key) != kCFNotFound) {
            _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Found repeated attribute");
            return false;
        }
        _inputStreamSkipWhitespace(&parser->input, NULL);
        if (!_inputStreamGetCharacter(&parser->input, &ch) || ch != '=') { 
            failure = true;
            break;
        }
        _inputStreamSkipWhitespace(&parser->input, NULL);
        value = CFStringCreateMutableWithExternalCharactersNoCopy(CFGetAllocator(parser), NULL, 0, 0, CFGetAllocator(parser));
        if (!parseAttributeValue(parser, value)) {
            CFRelease(value);
            failure = true;
            break;
        }
        CFArrayAppendValue(array, key);
        CFDictionarySetValue(dict, key, value);
        CFRelease(value);
        _inputStreamSkipWhitespace(&parser->input, NULL);
    }
    if (failure) {
//#warning CF:Include tag name in this error report
        _CFReportError(parser, kCFXMLErrorMalformedStartTag, "Found illegal character while parsing element tag");
        return false;
    } else if (_inputStreamAtEOF(&parser->input)) {
        _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing element attributes");
        return false;
    } else {
        return true;
    }
}

/*
 [1]  document ::= prolog element Misc*
 [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)?
 [27] Misc ::= Comment | PI | S
 [23] XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' 

 We treat XMLDecl as a plain old PI, since PI is part of Misc.  This changes the prolog and document productions to
 [22-1] prolog ::= Misc* (doctypedecl Misc*)?
 [1-1] document ::= Misc* (doctypedecl Misc*)? element Misc*

 NOTE: This function assumes parser->stack has a valid top.  I.e. the document pointer has already been created!
*/
static Boolean parseXML(CFXMLParserRef parser) {
    Boolean success = true, sawDTD = false, sawElement = false;
    UniChar ch;
    while (success && _inputStreamPeekCharacter(&parser->input, &ch)) {
        switch (ch) {
            case ' ':
            case '\n':
            case '\t':
            case '\r':
                success = parseWhitespace(parser);
                break;
            case '<':
                _inputStreamGetCharacter(&parser->input, &ch);
                if (!_inputStreamGetCharacter(&parser->input, &ch)) {
                    _CFReportError(parser, kCFXMLErrorUnexpectedEOF, "Encountered unexpected EOF while parsing top-level document");
                    return false;
                }
                if (ch == '!') {
                    // Comment or DTD
                    UniChar dashes[2] = {'-', '-'};
                    if (_inputStreamMatchString(&parser->input, dashes, 2)) {
                        // Comment
                        success = parseComment(parser, true);
                    } else {
                        // Should be DTD
                        if (sawDTD) {
                            _CFReportError(parser, kCFXMLErrorMalformedDocument, "Encountered a second DTD");
                            return false;
                        }
                        success = parseDTD(parser);
                        if (success) sawDTD = true;
                    }
                } else if (ch == '?') {
                    // Processing instruction
                    success = parseProcessingInstruction(parser, true);
                } else {
                    // Tag or malformed
                    if (sawElement) {
                        _CFReportError(parser, kCFXMLErrorMalformedDocument, "Encountered second top-level element");
                        return false;
                    }
                    _inputStreamReturnCharacter(&parser->input, ch);
                    success = parseTag(parser);
                    if (success) sawElement = true;
                }
                break;
            default: {
                parser->status = kCFXMLErrorMalformedDocument;
                parser->errorString = ch < 256 ?
                    CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected character 0x%x (\'%c\') at top-level"), ch, ch) :
                    CFStringCreateWithFormat(CFGetAllocator(parser), NULL, CFSTR("Encountered unexpected Unicode character 0x%x at top-level"), ch);

                if (parser->callBacks.handleError) {
                    INVOKE_CALLBACK3(parser->callBacks.handleError, parser, parser->status, parser->context.info);
                }
                return false;
            }
        }
    }
    
    if (!success) return false;
    if (!sawElement) {
        _CFReportError(parser, kCFXMLErrorElementlessDocument, "No element found in document");
        return false;
    }
    return true;
}

static void _CFReportError(CFXMLParserRef parser, CFXMLParserStatusCode errNum, const char *str) {
    if (str) {
        parser->status = errNum;
        parser->errorString = CFStringCreateWithCString(CFGetAllocator(parser), str, kCFStringEncodingASCII);
    }
    if (parser->callBacks.handleError) {
        INVOKE_CALLBACK3(parser->callBacks.handleError, parser, errNum, parser->context.info);
    }
}

// Assumes parser->node has been set and is ready to go
static Boolean reportNewLeaf(CFXMLParserRef parser) {
    void *xmlStruct;
    if (*(parser->top) == NULL) return true;

    xmlStruct = (void *)INVOKE_CALLBACK3(parser->callBacks.createXMLStructure, parser, parser->node, parser->context.info);
    if (xmlStruct && parser->status == kCFXMLStatusParseInProgress) {
        INVOKE_CALLBACK4(parser->callBacks.addChild, parser, *(parser->top), xmlStruct, parser->context.info);
        if (parser->status == kCFXMLStatusParseInProgress) INVOKE_CALLBACK3(parser->callBacks.endXMLStructure, parser, xmlStruct, parser->context.info);
    }
    if (parser->status != kCFXMLStatusParseInProgress) {
        _CFReportError(parser, parser->status, NULL);
        return false;
    }
    return true;
}

static void pushXMLNode(CFXMLParserRef parser, void *node) {
    parser->top ++;
    if ((unsigned)(parser->top - parser->stack) == parser->capacity) {
        parser->stack = (void **)CFAllocatorReallocate(CFGetAllocator(parser), parser->stack, 2 * parser->capacity * sizeof(void *), 0);
        parser->top = parser->stack + parser->capacity;
        parser->capacity = 2*parser->capacity;
    }
    *(parser->top) = node;
}

/**************************/
/* Parsing to a CFXMLTree */
/**************************/

static void *_XMLTreeCreateXMLStructure(CFXMLParserRef parser, CFXMLNodeRef node, void *context) {
    CFXMLNodeRef myNode = CFXMLNodeCreateCopy(CFGetAllocator(parser), node);
    CFXMLTreeRef tree = CFXMLTreeCreateWithNode(CFGetAllocator(parser), myNode);
    CFRelease(myNode);
    return (void *)tree;
}

static void _XMLTreeAddChild(CFXMLParserRef parser, void *parent, void *child, void *context) {
    CFTreeAppendChild((CFTreeRef)parent, (CFTreeRef)child);
}

static void _XMLTreeEndXMLStructure(CFXMLParserRef parser, void *xmlType, void *context) {
    CFXMLTreeRef node = (CFXMLTreeRef)xmlType;
    if (CFTreeGetParent(node))
        CFRelease((CFXMLTreeRef)xmlType);
}

CFXMLTreeRef CFXMLTreeCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex version) {
    CFXMLParserRef parser;
    CFXMLParserCallBacks callbacks;
    CFXMLTreeRef result;

    CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__);

    callbacks.createXMLStructure = _XMLTreeCreateXMLStructure;
    callbacks.addChild = _XMLTreeAddChild;
    callbacks.endXMLStructure = _XMLTreeEndXMLStructure;
    callbacks.resolveExternalEntity = NULL;
    callbacks.handleError = NULL;
    parser = CFXMLParserCreateWithDataFromURL(allocator, dataSource, parseOptions, version, &callbacks, NULL);

    if (CFXMLParserParse(parser)) {
        result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
    } else {
        result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
        if (result) CFRelease(result);
        result = NULL;
    }
    CFRelease(parser);
    return result;
}

CFXMLTreeRef CFXMLTreeCreateFromData(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex parserVersion) {
    return CFXMLTreeCreateFromDataWithError(allocator, xmlData, dataSource, parseOptions, parserVersion, NULL);
}

CONST_STRING_DECL(kCFXMLTreeErrorDescription, "kCFXMLTreeErrorDescription");
CONST_STRING_DECL(kCFXMLTreeErrorLineNumber, "kCFXMLTreeErrorLineNumber");
CONST_STRING_DECL(kCFXMLTreeErrorLocation, "kCFXMLTreeErrorLocation");
CONST_STRING_DECL(kCFXMLTreeErrorStatusCode, "kCFXMLTreeErrorStatusCode");

CFXMLTreeRef CFXMLTreeCreateFromDataWithError(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex parserVersion, CFDictionaryRef *errorDict) {
    CFXMLParserRef parser;
    CFXMLParserCallBacks callbacks;
    CFXMLTreeRef result;

    __CFGenericValidateType(xmlData, CFDataGetTypeID());
    CFAssert1(dataSource == NULL || CFGetTypeID(dataSource) == CFURLGetTypeID(), __kCFLogAssertion, "%s(): dataSource is not a valid CFURL", __PRETTY_FUNCTION__);

    callbacks.createXMLStructure = _XMLTreeCreateXMLStructure;
    callbacks.addChild = _XMLTreeAddChild;
    callbacks.endXMLStructure = _XMLTreeEndXMLStructure;
    callbacks.resolveExternalEntity = NULL;
    callbacks.handleError = NULL;
    parser = CFXMLParserCreate(allocator, xmlData, dataSource, parseOptions, parserVersion, &callbacks, NULL);

    if (CFXMLParserParse(parser)) {
        result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
    } else {
        if (errorDict) {	// collect the error dictionary
            *errorDict = CFDictionaryCreateMutable(allocator, 4, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
            if (*errorDict) {
                CFIndex rawnum;
                CFNumberRef cfnum;
                CFStringRef errstring;
                
                rawnum = CFXMLParserGetLocation(parser);
                cfnum = CFNumberCreate(allocator, kCFNumberSInt32Type, &rawnum);
                if(cfnum) {
                    CFDictionaryAddValue((CFMutableDictionaryRef)*errorDict, kCFXMLTreeErrorLocation, cfnum);
                    CFRelease(cfnum);                    
                }
                
                rawnum = CFXMLParserGetLineNumber(parser);
                cfnum = CFNumberCreate(allocator, kCFNumberSInt32Type, &rawnum);
                if(cfnum) {
                    CFDictionaryAddValue((CFMutableDictionaryRef)*errorDict, kCFXMLTreeErrorLineNumber, cfnum);
                    CFRelease(cfnum);                    
                }

                rawnum = CFXMLParserGetStatusCode(parser);
                cfnum = CFNumberCreate(allocator, kCFNumberSInt32Type, &rawnum);
                if(cfnum) {
                    CFDictionaryAddValue((CFMutableDictionaryRef)*errorDict, kCFXMLTreeErrorStatusCode, cfnum);
                    CFRelease(cfnum);                    
                }

                errstring = CFXMLParserCopyErrorDescription(parser);
                if(errstring) {
                    CFDictionaryAddValue((CFMutableDictionaryRef)*errorDict, kCFXMLTreeErrorDescription, errstring);
                    CFRelease(errstring);                    
                }
            }
        }
        result = (CFXMLTreeRef)CFXMLParserGetDocument(parser);
        if (result) CFRelease(result);
        result = NULL;
    }
    CFRelease(parser);
    return result;
}

/*
 At the very least we need to do <, >, &, ", and '. In addition, we'll have to do everything else in the string.
 We should also be handling items that are up over certain values correctly.
 */
CFStringRef CFXMLCreateStringByEscapingEntities(CFAllocatorRef allocator, CFStringRef string, CFDictionaryRef entitiesDictionary) {
    CFAssert1(string != NULL, __kCFLogAssertion, "%s(): NULL string not permitted.", __PRETTY_FUNCTION__);
    CFMutableStringRef newString = CFStringCreateMutable(allocator, 0); // unbounded mutable string
    CFMutableCharacterSetRef startChars = CFCharacterSetCreateMutable(allocator);

    CFStringInlineBuffer inlineBuf;
    CFIndex idx = 0;
    CFIndex mark = idx;
    CFIndex stringLength = CFStringGetLength(string);
    UniChar uc;

    CFCharacterSetAddCharactersInString(startChars, CFSTR("&<>'\""));

    CFStringInitInlineBuffer(string, &inlineBuf, CFRangeMake(0, stringLength));
    for(idx = 0; idx < stringLength; idx++) {
        uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, idx);
        if(CFCharacterSetIsCharacterMember(startChars, uc)) {
            CFStringRef previousSubstring = CFStringCreateWithSubstring(allocator, string, CFRangeMake(mark, idx - mark));
            CFStringAppend(newString, previousSubstring);
            CFRelease(previousSubstring);
            switch(uc) {
                case '&':
                    CFStringAppend(newString, CFSTR("&amp;"));
                    break;
                case '<':
                    CFStringAppend(newString, CFSTR("&lt;"));
                    break;
                case '>':
                    CFStringAppend(newString, CFSTR("&gt;"));
                    break;
                case '\'':
                    CFStringAppend(newString, CFSTR("&apos;"));
                    break;
                case '"':
                    CFStringAppend(newString, CFSTR("&quot;"));
                    break;
            }
            mark = idx + 1;
        }
    }
    // Copy the remainder to the output string before returning.
    CFStringRef remainder = CFStringCreateWithSubstring(allocator, string, CFRangeMake(mark, idx - mark));
    if (NULL != remainder) {
        CFStringAppend(newString, remainder);
        CFRelease(remainder);
    }
    
    CFRelease(startChars);
    return newString;
}

CFStringRef CFXMLCreateStringByUnescapingEntities(CFAllocatorRef allocator, CFStringRef string, CFDictionaryRef entitiesDictionary) {
    CFAssert1(string != NULL, __kCFLogAssertion, "%s(): NULL string not permitted.", __PRETTY_FUNCTION__);

    CFStringInlineBuffer inlineBuf; /* use this for fast traversal of the string in question */
    CFStringRef sub;
    CFIndex lastChunkStart, length = CFStringGetLength(string);
    CFIndex i, entityStart;
    UniChar uc;
    UInt32 entity;
    int base;
    CFMutableDictionaryRef fullReplDict = entitiesDictionary ? CFDictionaryCreateMutableCopy(allocator, 0, entitiesDictionary) : CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);

    CFDictionaryAddValue(fullReplDict, (const void *)CFSTR("amp"), (const void *)CFSTR("&"));
    CFDictionaryAddValue(fullReplDict, (const void *)CFSTR("quot"), (const void *)CFSTR("\""));
    CFDictionaryAddValue(fullReplDict, (const void *)CFSTR("lt"), (const void *)CFSTR("<"));
    CFDictionaryAddValue(fullReplDict, (const void *)CFSTR("gt"), (const void *)CFSTR(">"));
    CFDictionaryAddValue(fullReplDict, (const void *)CFSTR("apos"), (const void *)CFSTR("'"));

    CFStringInitInlineBuffer(string, &inlineBuf, CFRangeMake(0, length - 1));
    CFMutableStringRef newString = CFStringCreateMutable(allocator, 0);

    lastChunkStart = 0;
    // Scan through the string in its entirety
    for(i = 0; i < length; ) {
        uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;	// grab the next character and move i.

        if(uc == '&') {
            entityStart = i - 1;
            entity = 0xFFFF;	// set this to a not-Unicode character as sentinel
                             // we've hit the beginning of an entity. Copy everything from lastChunkStart to this point.
            if(lastChunkStart < i - 1) {
                sub = CFStringCreateWithSubstring(allocator, string, CFRangeMake(lastChunkStart, (i - 1) - lastChunkStart));
                CFStringAppend(newString, sub);
                CFRelease(sub);
            }

            uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;	// grab the next character and move i.
                                                                           // Now we can process the entity reference itself
            if(uc == '#') {	// this is a numeric entity.
                base = 10;
                entity = 0;
                uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;

                if(uc == 'x') {	// only lowercase x allowed. Translating numeric entity as hexadecimal.
                    base = 16;
                    uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;
                }

                // process the provided digits 'til we're finished
                while(true) {
                    if (uc >= '0' && uc <= '9')
                        entity = entity * base + (uc-'0');
                    else if (uc >= 'a' && uc <= 'f' && base == 16)
                        entity = entity * base + (uc-'a'+10);
                    else if (uc >= 'A' && uc <= 'F' && base == 16)
                        entity = entity * base + (uc-'A'+10);
                    else break;

                    if (i < length) {
                        uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;
                    }
                    else
                        break;
                }
            }

            // Scan to the end of the entity
            while(uc != ';' && i < length) {
                uc = CFStringGetCharacterFromInlineBuffer(&inlineBuf, i); i++;
            }

            if(0xFFFF != entity) { // it was numeric, and translated.
                // Now, output the result fo the entity
                if(entity >= 0x10000) {
                    UniChar characters[2] = { ((entity - 0x10000) >> 10) + 0xD800, ((entity - 0x10000) & 0x3ff) + 0xDC00 };
                    CFStringAppendCharacters(newString, characters, 2);
                } else {
                    UniChar character = entity;
                    CFStringAppendCharacters(newString, &character, 1);
                }
            } else {	// it wasn't numeric.
                sub = CFStringCreateWithSubstring(allocator, string, CFRangeMake(entityStart + 1, (i - entityStart - 2))); // This trims off the & and ; from the string, so we can use it against the dictionary itself.
                CFStringRef replacementString = (CFStringRef)CFDictionaryGetValue(fullReplDict, sub);
                if(replacementString) {
                    CFStringAppend(newString, replacementString);
                } else {
                    CFRelease(sub); // let the old substring go, since we didn't find it in the dictionary
                    sub =  CFStringCreateWithSubstring(allocator, string, CFRangeMake(entityStart, (i - entityStart))); // create a new one, including the & and ;
                    CFStringAppend(newString, sub); // ...and append that.
                }
                CFRelease(sub); // in either case, release the most-recent "sub"
            }

            // move the lastChunkStart to the beginning of the next chunk.
            lastChunkStart = i;
        }
    }
    if(lastChunkStart < length) { // we've come out of the loop, let's get the rest of the string and tack it on.
        sub = CFStringCreateWithSubstring(allocator, string, CFRangeMake(lastChunkStart, i - lastChunkStart));
        CFStringAppend(newString, sub);
        CFRelease(sub);
    }

    CFRelease(fullReplDict);

    return newString;
}


