// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


/*	CFXMLNode.c
	Copyright (c) 1998 - 2015 Apple Inc. and the Swift project authors
	Responsibility: David Smith
*/

#include <CoreFoundation/CFXMLNode.h>
#include <CoreFoundation/CFPropertyList.h>
#include "CFInternal.h"
#include "CFXMLInputStream.h"

CF_INLINE Boolean _nullSafeCFEqual(CFTypeRef cf1, CFTypeRef cf2) {
    if (cf1 && !cf2) return false;
    if (cf2 && !cf1) return false;
    if (cf1) return CFEqual(cf1, cf2);
    return true;
}

static Boolean externalIDEqual(CFXMLExternalID *ext1, CFXMLExternalID *ext2) {
    return _nullSafeCFEqual(ext1->systemID, ext2->systemID) && _nullSafeCFEqual(ext1->publicID, ext2->publicID);
}

static Boolean __CFXMLNodeEqual(CFTypeRef  cf1, CFTypeRef  cf2) {
    CFXMLNodeRef desc1 = (CFXMLNodeRef)cf1, desc2 = (CFXMLNodeRef)cf2;
    if (desc1 == desc2) return true;
    if (!desc1 || !desc2) return false;
    if (desc1->dataTypeID != desc2->dataTypeID) return false;
    if ((desc1->dataString && !desc2->dataString) || (!desc1->dataString && desc2->dataString)) return false;
    if (desc1->dataString && !CFEqual(desc1->dataString, desc2->dataString)) return false;
    if ((desc1->additionalData && !desc2->additionalData) || (!desc1->additionalData && desc2->additionalData)) return false;
    if (!desc1->additionalData) return true;
    switch (desc1->dataTypeID) {
        case kCFXMLNodeTypeDocument:{
            CFURLRef url1, url2;
            url1 = ((CFXMLDocumentInfo *)desc1->additionalData)->sourceURL;
            url2 = ((CFXMLDocumentInfo *)desc2->additionalData)->sourceURL;
            return _nullSafeCFEqual(url1, url2);
        }
        case kCFXMLNodeTypeElement: {
            CFXMLElementInfo *elt1, *elt2;
            elt1 = (CFXMLElementInfo *)desc1->additionalData;
            elt2 = (CFXMLElementInfo *)desc2->additionalData;
            if (elt1->isEmpty != elt2->isEmpty) return false;
            if (elt1->attributes == elt2->attributes) return true;
            if (!elt1->attributes) return (CFDictionaryGetCount(elt2->attributes) == 0);
            if (!elt2->attributes) return (CFDictionaryGetCount(elt1->attributes) == 0);
            return CFEqual(elt1->attributes, elt2->attributes);
        }
        case kCFXMLNodeTypeProcessingInstruction: {
            CFStringRef str1, str2;
            str1 = ((CFXMLProcessingInstructionInfo *)desc1->additionalData)->dataString;
            str2 = ((CFXMLProcessingInstructionInfo *)desc2->additionalData)->dataString;
            return _nullSafeCFEqual(str1, str2);
        }
        case kCFXMLNodeTypeEntity: {
            CFXMLEntityInfo *data1, *data2;
            data1 = (CFXMLEntityInfo *)desc1->additionalData;
            data2 = (CFXMLEntityInfo *)desc2->additionalData;
            if (data1->entityType != data2->entityType) return false;
            if (!_nullSafeCFEqual(data1->replacementText, data2->replacementText)) return false;
            if (!_nullSafeCFEqual(data1->notationName, data2->notationName)) return false;
            return externalIDEqual(&data1->entityID, &data2->entityID);
        }
        case kCFXMLNodeTypeEntityReference: {
            return ((CFXMLEntityReferenceInfo *)(desc1->additionalData))->entityType == ((CFXMLEntityReferenceInfo *)(desc2->additionalData))->entityType;
        }
        case kCFXMLNodeTypeNotation: {
            CFXMLNotationInfo *data1, *data2;
            data1 = (CFXMLNotationInfo *)desc1->additionalData;
            data2 = (CFXMLNotationInfo *)desc2->additionalData;
            return externalIDEqual(&(data1->externalID), &(data2->externalID));
        }
        case kCFXMLNodeTypeDocumentType: {
            CFXMLDocumentTypeInfo *data1, *data2;
            data1 = (CFXMLDocumentTypeInfo *)desc1->additionalData;
            data2 = (CFXMLDocumentTypeInfo *)desc2->additionalData;
            return externalIDEqual(&(data1->externalID), &(data2->externalID));
        }
        case kCFXMLNodeTypeElementTypeDeclaration: {
            CFXMLElementTypeDeclarationInfo *d1 = (CFXMLElementTypeDeclarationInfo *)desc1->additionalData;
            CFXMLElementTypeDeclarationInfo *d2 = (CFXMLElementTypeDeclarationInfo *)desc2->additionalData;
            return _nullSafeCFEqual(d1->contentDescription, d2->contentDescription);
        }
        case kCFXMLNodeTypeAttributeListDeclaration: {
            CFXMLAttributeListDeclarationInfo *attList1 = (CFXMLAttributeListDeclarationInfo *)desc1->additionalData;
            CFXMLAttributeListDeclarationInfo *attList2 = (CFXMLAttributeListDeclarationInfo *)desc2->additionalData;
            CFIndex idx;
            if (attList1->numberOfAttributes != attList2->numberOfAttributes) return false;
            for (idx = 0; idx < attList1->numberOfAttributes; idx ++) {
                CFXMLAttributeDeclarationInfo *attr1 = &(attList1->attributes[idx]);
                CFXMLAttributeDeclarationInfo *attr2 = &(attList2->attributes[idx]);
                if (!_nullSafeCFEqual(attr1->attributeName, attr2->attributeName)) return false;
                if (!_nullSafeCFEqual(attr1->typeString, attr2->typeString)) return false;
                if (!_nullSafeCFEqual(attr1->defaultString, attr2->defaultString)) return false;
            }
            return true;
        }
        default:
            return false;
    }
    return true;
}

static CFHashCode __CFXMLNodeHash(CFTypeRef  cf) {
    CFXMLNodeRef node = (CFXMLNodeRef)cf;
    if (node->dataString) {
        return CFHash(node->dataString);
    }
    if (node->dataTypeID == kCFXMLNodeTypeDocument) {
        CFURLRef url = ((CFXMLDocumentInfo *)node->additionalData)->sourceURL;
        return url ? CFHash(url) : (CFHashCode)cf;
    } else {
        CFAssert(false, __kCFLogAssertion, "%s(): Saw unexpected XML type code %d", __PRETTY_FUNCTION__, node->dataTypeID);
        return CFHash(cf);
    }
}

static CFStringRef __CFXMLNodeCopyDescription(CFTypeRef  cf) {
    struct __CFXMLNode *node = (struct __CFXMLNode *)cf;
    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFXMLNode %p>{typeID = %ld, string = %@}"), cf, (unsigned long)node->dataTypeID, node->dataString);
}

static void __CFXMLNodeDeallocate(CFTypeRef  cf) {
    struct __CFXMLNode *node = (struct __CFXMLNode *)cf;
    if (node->dataString) CFRelease(node->dataString);
    if (node->additionalData) {
        switch (node->dataTypeID) {
            case kCFXMLNodeTypeDocument:
                if (((CFXMLDocumentInfo *)node->additionalData)->sourceURL) {
                    CFRelease(((CFXMLDocumentInfo *)node->additionalData)->sourceURL);
                }
                break;
            case kCFXMLNodeTypeElement:
                if (((CFXMLElementInfo *)node->additionalData)->attributes) {
                    CFRelease(((CFXMLElementInfo *)node->additionalData)->attributes);
                    CFRelease(((CFXMLElementInfo *)node->additionalData)->attributeOrder);
                }
                break;
            case kCFXMLNodeTypeProcessingInstruction:
                if (((CFXMLProcessingInstructionInfo *)node->additionalData)->dataString) {
                    CFRelease(((CFXMLProcessingInstructionInfo *)node->additionalData)->dataString);
                }
                break;
            case kCFXMLNodeTypeEntity:
            {
                CFXMLEntityInfo *data = (CFXMLEntityInfo *)node->additionalData;
                if (data->replacementText) CFRelease(data->replacementText);
                if (data->entityID.systemID) CFRelease(data->entityID.systemID);
                if (data->entityID.publicID) CFRelease(data->entityID.publicID);
                if (data->notationName) CFRelease(data->notationName);
                break;
            }
            case kCFXMLNodeTypeEntityReference:
            {
                // Do nothing; additionalData has no structure of its own, with dependent pieces to release.  -- REW, 2/11/2000
                break;
            }
            case kCFXMLNodeTypeDocumentType:
            case kCFXMLNodeTypeNotation:
                // We get away with this because CFXMLNotationInfo and CFXMLDocumentTypeInfo have identical formats
            {
                CFXMLNotationInfo *data = (CFXMLNotationInfo *)node->additionalData;
                if (data->externalID.systemID) CFRelease(data->externalID.systemID);
                if (data->externalID.publicID) CFRelease(data->externalID.publicID);
                break;
            }
            case kCFXMLNodeTypeElementTypeDeclaration:
                if (((CFXMLElementTypeDeclarationInfo *)node->additionalData)->contentDescription) {
                    CFRelease(((CFXMLElementTypeDeclarationInfo *)node->additionalData)->contentDescription);
                }
                break;
            case kCFXMLNodeTypeAttributeListDeclaration:
            {
                CFXMLAttributeListDeclarationInfo *data = (CFXMLAttributeListDeclarationInfo *)node->additionalData;
                CFIndex idx;
                for (idx = 0; idx < data->numberOfAttributes; idx ++) {
                    CFRelease(data->attributes[idx].attributeName);
                    CFRelease(data->attributes[idx].typeString);
                    CFRelease(data->attributes[idx].defaultString);
                }
                CFAllocatorDeallocate(CFGetAllocator(node), data->attributes);
                break;
            }
            default:
                CFAssert(false, __kCFLogAssertion, "%s(): Encountered unexpected typeID %d (additionalData should be empty)", node->dataTypeID);
        }
    }
}

static CFTypeID __kCFXMLNodeTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFXMLNodeClass = {
    0,
    "CFXMLNode",
    NULL,      // init
    NULL,      // copy
    __CFXMLNodeDeallocate,
    __CFXMLNodeEqual,
    __CFXMLNodeHash,
    NULL,      // 
    __CFXMLNodeCopyDescription
};

CFTypeID CFXMLNodeGetTypeID(void) {
    static dispatch_once_t initOnce = 0;
    dispatch_once(&initOnce, ^{ __kCFXMLNodeTypeID = _CFRuntimeRegisterClass(&__CFXMLNodeClass); });
    return __kCFXMLNodeTypeID;
}

CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode) {
    return CFXMLNodeCreate(alloc, origNode->dataTypeID, origNode->dataString, origNode->additionalData, origNode->version);
}

static void _copyAddlDataForType(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, const void *src, void *dest) {
    switch(xmlType) {
        case kCFXMLNodeTypeDocument: {
            CFXMLDocumentInfo *srcData = (CFXMLDocumentInfo *)src;
            CFXMLDocumentInfo *destData = (CFXMLDocumentInfo *)dest;
            destData->sourceURL = srcData->sourceURL ? (CFURLRef)CFRetain(srcData->sourceURL) : NULL;
            destData->encoding = srcData->encoding;
            break;
        }
        case kCFXMLNodeTypeElement: {
            CFXMLElementInfo *srcData = (CFXMLElementInfo *)src;
            CFXMLElementInfo *destData = (CFXMLElementInfo *)dest;
            if (srcData->attributes && CFDictionaryGetCount(srcData->attributes) != 0) {
                destData->attributes =  (CFDictionaryRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributes, kCFPropertyListImmutable);
                destData->attributeOrder = (CFArrayRef)CFPropertyListCreateDeepCopy(alloc, srcData->attributeOrder, kCFPropertyListImmutable);
            } else {
                destData->attributes = NULL;
                destData->attributeOrder = NULL;
            }
            destData->isEmpty = srcData->isEmpty;
            break;
        }
        case kCFXMLNodeTypeProcessingInstruction: {
            CFXMLProcessingInstructionInfo *srcData = (CFXMLProcessingInstructionInfo *)src;
            CFXMLProcessingInstructionInfo *destData = (CFXMLProcessingInstructionInfo *)dest;
            destData->dataString = srcData->dataString ? (CFStringRef)CFStringCreateCopy(alloc, srcData->dataString) : NULL;
            break;
        }
        case kCFXMLNodeTypeEntity:
        {
            CFXMLEntityInfo *sourceData = (CFXMLEntityInfo *)src;
            CFXMLEntityInfo *destData = (CFXMLEntityInfo *)dest;
            destData->entityType = sourceData->entityType;
            destData->replacementText = sourceData->replacementText ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->replacementText) : NULL;
            destData->entityID.systemID = sourceData->entityID.systemID ? (CFURLRef)CFRetain(sourceData->entityID.systemID) : NULL;
            destData->entityID.publicID = sourceData->entityID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->entityID.publicID) : NULL;
            destData->notationName = sourceData->notationName ? (CFStringRef)CFStringCreateCopy(alloc, sourceData->notationName) : NULL;
            break;
        }
        case kCFXMLNodeTypeEntityReference:
        {
            CFXMLEntityReferenceInfo *srcData = (CFXMLEntityReferenceInfo *)src;
            CFXMLEntityReferenceInfo *destData = (CFXMLEntityReferenceInfo *)dest;
            destData->entityType = srcData->entityType;
            break;
        }
        case kCFXMLNodeTypeDocumentType:
        case kCFXMLNodeTypeNotation:
        {
            // We can get away with this because the structures of CFXMLNotationInfo and CFXMLDocumentTypeInfo match.  -- REW, 3/8/2000
            CFXMLNotationInfo *srcData = (CFXMLNotationInfo *)src;
            CFXMLNotationInfo *destData = (CFXMLNotationInfo *)dest;
            destData->externalID.systemID = srcData->externalID.systemID ? (CFURLRef)CFRetain(srcData->externalID.systemID) : NULL;
            destData->externalID.publicID = srcData->externalID.publicID ? (CFStringRef)CFStringCreateCopy(alloc, srcData->externalID.publicID) : NULL;
            break;
        }
        case kCFXMLNodeTypeElementTypeDeclaration: {
            CFXMLElementTypeDeclarationInfo *srcData = (CFXMLElementTypeDeclarationInfo *)src;
            CFXMLElementTypeDeclarationInfo *destData = (CFXMLElementTypeDeclarationInfo *)dest;
            destData->contentDescription = srcData->contentDescription ? (CFStringRef)CFStringCreateCopy(alloc, srcData->contentDescription) : NULL;
            break;
        }
        case kCFXMLNodeTypeAttributeListDeclaration:
        {
            CFXMLAttributeListDeclarationInfo *sourceData = (CFXMLAttributeListDeclarationInfo *)src;
            CFXMLAttributeListDeclarationInfo *destData = (CFXMLAttributeListDeclarationInfo *)dest;
            CFIndex idx;
            destData->numberOfAttributes = sourceData->numberOfAttributes;
            destData->attributes = sourceData->numberOfAttributes ? (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(alloc, sizeof(CFXMLAttributeDeclarationInfo)*sourceData->numberOfAttributes, 0) : NULL;
            for (idx = 0; idx < sourceData->numberOfAttributes; idx ++) {
                CFXMLAttributeDeclarationInfo sourceAttr = sourceData->attributes[idx];
                CFXMLAttributeDeclarationInfo *destAttr = &(destData->attributes[idx]);
                destAttr->attributeName = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.attributeName);
                destAttr->typeString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.typeString);
                destAttr->defaultString = (CFStringRef)CFStringCreateCopy(alloc, sourceAttr.defaultString);
            }
            break;
        }
        default:
            CFAssert(false, __kCFLogAssertion, "%s(): Encountered unexpected typeID %d (additionalData should be empty)", __PRETTY_FUNCTION__, xmlType);
    }
}

// Designated initializer; all node creation (except the wonky one created by the parser) should happen here.
CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalData, CFIndex version) {
    struct __CFXMLNode *node;
    UInt32 extraSize;
    // Add assertions checking xmlType against the presence/absence of additionalData & dataString
    switch (xmlType) {
        case kCFXMLNodeTypeDocument: extraSize = sizeof(CFXMLDocumentInfo); break;
        case kCFXMLNodeTypeElement: extraSize = sizeof(CFXMLElementInfo); break;
        case kCFXMLNodeTypeProcessingInstruction: extraSize = sizeof(CFXMLProcessingInstructionInfo); break;
        case kCFXMLNodeTypeEntity: extraSize = sizeof(CFXMLEntityInfo); break;
        case kCFXMLNodeTypeEntityReference: extraSize = sizeof(CFXMLEntityReferenceInfo); break;
        case kCFXMLNodeTypeDocumentType: extraSize = sizeof(CFXMLDocumentTypeInfo); break;
        case kCFXMLNodeTypeNotation: extraSize = sizeof(CFXMLNotationInfo); break;
        case kCFXMLNodeTypeElementTypeDeclaration: extraSize = sizeof(CFXMLElementTypeDeclarationInfo); break;
        case kCFXMLNodeTypeAttributeListDeclaration: extraSize = sizeof(CFXMLAttributeListDeclarationInfo); break;
        default: extraSize = 0;
    }

    node = (struct __CFXMLNode *)_CFRuntimeCreateInstance(alloc, CFXMLNodeGetTypeID(), sizeof(struct __CFXMLNode) + extraSize - sizeof(CFRuntimeBase), NULL);
    if (node) {
        alloc = CFGetAllocator(node);
        node->version = version;
        node->dataTypeID = xmlType;
        node->dataString = dataString ? (CFStringRef)CFStringCreateCopy(alloc, dataString) : NULL;
        if (extraSize != 0) {
            node->additionalData = (void *)((uint8_t *)node + sizeof(struct __CFXMLNode));
            _copyAddlDataForType(alloc, xmlType, additionalData, node->additionalData);
        } else {
            node->additionalData = NULL;
        }
    }
    return node;
}

CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) {
    return node->dataTypeID;
}

CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) {
    return node->dataString;
}

const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) {
    return node->additionalData;
}

CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node) {
    return node->version;
}


