/*	CFURLAccess.c
	Copyright (c) 1999-2017, Apple Inc. and the Swift project authors
 
	Portions Copyright (c) 2014-2017, 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
	Responsibility: Jim Luther/Chris Linn
*/

/*------
CFData read/write routines
-------*/

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated"

#include "CFInternal.h"
#include <CoreFoundation/CFBase.h>
#include <CoreFoundation/CFURL.h>
#include <CoreFoundation/CFDictionary.h>
#include <CoreFoundation/CFURLAccess.h>
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFNumber.h>
#include <string.h>
#include <ctype.h>
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pwd.h>
#include <fcntl.h>
#elif DEPLOYMENT_TARGET_WINDOWS
#include <io.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <ctype.h>
#else
#error Unknown or unspecified DEPLOYMENT_TARGET
#endif
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
#include <dlfcn.h>
#endif

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED


DEFINE_WEAK_CFNETWORK_FUNC_FAIL(Boolean, _CFURLCreateDataAndPropertiesFromResource, (CFAllocatorRef A, CFURLRef B, CFDataRef *C, CFDictionaryRef *D, CFArrayRef E, SInt32 *F), (A, B, C, D, E, F), { if(C) *C=NULL; if (D) *D=NULL; if(F) *F=kCFURLImproperArgumentsError; }, false)
DEFINE_WEAK_CFNETWORK_FUNC_FAIL(Boolean, _CFURLWriteDataAndPropertiesToResource, (CFURLRef A, CFDataRef B, CFDictionaryRef C, SInt32 *D), (A, B, C, D), if (D) *D = kCFURLImproperArgumentsError, false)

DEFINE_WEAK_CFNETWORK_FUNC_FAIL(Boolean, _CFURLDestroyResource, (CFURLRef A, SInt32 *B), (A, B), if(B) *B = kCFURLImproperArgumentsError, false)

#endif

typedef struct __NSString__ *NSString;

/*
    Pre-10.6 property keys
*/

CONST_STRING_DECL(kCFURLFileExists, "kCFURLFileExists")
CONST_STRING_DECL(kCFURLFilePOSIXMode, "kCFURLFilePOSIXMode")
CONST_STRING_DECL(kCFURLFileDirectoryContents, "kCFURLFileDirectoryContents")
CONST_STRING_DECL(kCFURLFileLength, "kCFURLFileLength")
CONST_STRING_DECL(kCFURLFileLastModificationTime, "kCFURLFileLastModificationTime")
CONST_STRING_DECL(kCFURLFileOwnerID, "kCFURLFileOwnerID")
CONST_STRING_DECL(kCFURLHTTPStatusCode, "kCFURLHTTPStatusCode")
CONST_STRING_DECL(kCFURLHTTPStatusLine, "kCFURLHTTPStatusLine")

CONST_STRING_DECL(kCFDataURLDataLength, "kCFDataURLDataLength")
CONST_STRING_DECL(kCFDataURLMimeType, "kCFDataURLMimeType")
CONST_STRING_DECL(kCFDataURLTextEncodingName, "kCFDataURLTextEncodingName")

// Compatibility property strings -- we obsoleted these names pre-DP4. REW, 5/22/2000
CONST_STRING_DECL(kCFFileURLExists, "kCFURLFileExists")
CONST_STRING_DECL(kCFFileURLPOSIXMode, "kCFURLFilePOSIXMode")
CONST_STRING_DECL(kCFFileURLDirectoryContents, "kCFURLFileDirectoryContents")
CONST_STRING_DECL(kCFFileURLSize, "kCFURLFileLength")
CONST_STRING_DECL(kCFFileURLLastModificationTime, "kCFURLFileLastModificationTime")
CONST_STRING_DECL(kCFHTTPURLStatusCode, "kCFURLHTTPStatusCode")
CONST_STRING_DECL(kCFHTTPURLStatusLine, "kCFURLHTTPStatusLine")

// Copied pretty much verbatim from NSData; note that files are still special cased in this code.  Ultimately, we probably want to treat file URLs the same way as any other URL (go through the URL Access layer).  -- REW, 10/21/98

/*************************/
/* file: access routines */
/*************************/

//#warning CF:For the moment file access failures are ill defined and set the error code to kCFURLUnknownError

static CFDictionaryRef _CFFileURLCreatePropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFArrayRef desiredProperties, SInt32 *errorCode) {
    // MF:!!! This could/should be changed to use _CFGetFileProperties() to do the actual figuring.
    static CFArrayRef _allProps = NULL;
    CFRange arrayRange;
    SInt32 idx;
    CFMutableDictionaryRef propertyDict = NULL;

    Boolean exists;
    SInt32 posixMode;
    int64_t size;
    CFDateRef modTime = NULL, *modTimePtr = NULL;
    CFArrayRef contents = NULL, *contentsPtr = NULL;
    SInt32 ownerID;

    if (errorCode) *errorCode = 0;
    if (!desiredProperties) {
        // Cheap and dirty hack to make this work for the moment; ultimately we need to do something more sophisticated.  This will result in an error return whenever a property key is defined which isn't applicable to all file URLs.  REW, 3/2/99
        if (!_allProps) {
            const void *values[9];
            values[0] = kCFURLFileExists;
            values[1] = kCFURLFilePOSIXMode;
            values[2] = kCFURLFileDirectoryContents;
            values[3] = kCFURLFileLength;
            values[4] = kCFURLFileLastModificationTime;
            values[5] = kCFURLFileOwnerID;
            _allProps = CFArrayCreate(kCFAllocatorSystemDefault, values, 6, &kCFTypeArrayCallBacks);
        }
        desiredProperties = _allProps;
    }

    arrayRange.location = 0;
    arrayRange.length = CFArrayGetCount(desiredProperties);
    propertyDict = CFDictionaryCreateMutable(alloc, 0, & kCFTypeDictionaryKeyCallBacks, & kCFTypeDictionaryValueCallBacks);
    if (arrayRange.length == 0) return propertyDict;

    if (CFArrayContainsValue(desiredProperties, arrayRange, kCFURLFileDirectoryContents)) {
        contentsPtr = &contents;
    }
    if (CFArrayContainsValue(desiredProperties, arrayRange, kCFURLFileLastModificationTime)) {
        modTimePtr = &modTime;
    }

    if (_CFGetFileProperties(alloc, url, &exists, &posixMode, &size, modTimePtr, &ownerID, contentsPtr) != 0) {
	
	//  If all they've asked for is whether this file exists, then any error will just make
	//  this return kCFURLFileExists = kCFBooleanFalse, which handles the case where the filename is invalid or too long or something.
	if ( arrayRange.length == 1 && CFArrayContainsValue( desiredProperties, arrayRange, kCFURLFileExists ) ) {
	    CFDictionarySetValue(propertyDict, kCFURLFileExists, kCFBooleanFalse);
	}
	else if (errorCode) {
            *errorCode = kCFURLUnknownError;
        }
        return propertyDict;
    }
    
    for (idx = 0; idx < arrayRange.length; idx ++) {
        CFStringRef key = (CFMutableStringRef )CFArrayGetValueAtIndex(desiredProperties, idx);
        if (key == kCFURLFilePOSIXMode || CFEqual(kCFURLFilePOSIXMode, key)) {
            if (exists) {
                CFNumberRef num = CFNumberCreate(alloc, kCFNumberSInt32Type, &posixMode);
                CFDictionarySetValue(propertyDict, kCFURLFilePOSIXMode, num);
                CFRelease(num);
            } else if (errorCode) {
                *errorCode = kCFURLUnknownError;
            }
        } else if (key == kCFURLFileDirectoryContents || CFEqual(kCFURLFileDirectoryContents, key)) {
            if (exists && (posixMode & S_IFMT) == S_IFDIR && contents) {
                CFDictionarySetValue(propertyDict, kCFURLFileDirectoryContents, contents);
            } else if (errorCode) {
                *errorCode = kCFURLUnknownError;
            }
        } else if (key == kCFURLFileLength || CFEqual(kCFURLFileLength, key)) {
            if (exists) {
                CFNumberRef num = CFNumberCreate(alloc, kCFNumberSInt64Type, &size);
                CFDictionarySetValue(propertyDict, kCFURLFileLength, num);
                CFRelease(num);
            } else if (errorCode) {
                *errorCode = kCFURLUnknownError;
            }
        } else if (key == kCFURLFileLastModificationTime || CFEqual(kCFURLFileLastModificationTime, key)) {
            if (exists && modTime) {
                CFDictionarySetValue(propertyDict, kCFURLFileLastModificationTime, modTime);
            } else if (errorCode) {
                *errorCode = kCFURLUnknownError;
            }
        } else if (key == kCFURLFileExists || CFEqual(kCFURLFileExists, key)) {
            if (exists) {
                CFDictionarySetValue(propertyDict, kCFURLFileExists, kCFBooleanTrue);
            } else {
                CFDictionarySetValue(propertyDict, kCFURLFileExists, kCFBooleanFalse);
            }
        } else if (key == kCFURLFileOwnerID || CFEqual(kCFURLFileOwnerID, key)) {
            if (exists) {
                CFNumberRef num  = CFNumberCreate(alloc, kCFNumberSInt32Type, &ownerID);
                CFDictionarySetValue(propertyDict, kCFURLFileOwnerID, num);
                CFRelease(num);
            } else if (errorCode) {
                *errorCode = kCFURLUnknownError;
            }
        // Add more properties here
        } else if (errorCode) {
            *errorCode = kCFURLUnknownPropertyKeyError;
        }
    }
    if (modTime) CFRelease(modTime);
    if (contents) CFRelease(contents);
    return propertyDict;
}

static Boolean _CFFileURLWritePropertiesToResource(CFURLRef url, CFDictionaryRef propertyDict, SInt32 *errorCode) {
    CFTypeRef buffer[16];
    CFTypeRef *keys;
    CFTypeRef *values;
    Boolean result = true;
    SInt32 idx, count;
    char cPath[CFMaxPathSize];

    if (!CFURLGetFileSystemRepresentation(url, true, (unsigned char *)cPath, CFMaxPathSize)) {
        if (errorCode) *errorCode = kCFURLImproperArgumentsError;
        return false;
    }

    count = CFDictionaryGetCount(propertyDict);
    if (count < 8) {
        keys = buffer;
        values = buffer+8;
    } else {
        keys = (CFTypeRef *)CFAllocatorAllocate(CFGetAllocator(url), sizeof(void *) * count * 2, 0);
        values = keys + count;
    }
    CFDictionaryGetKeysAndValues(propertyDict, keys, values);

    for (idx = 0; idx < count; idx ++) {
        CFStringRef key = (CFStringRef)keys[idx];
        CFTypeRef value = values[idx];
        if (key == kCFURLFilePOSIXMode || CFEqual(kCFURLFilePOSIXMode, key)) {
            SInt32 mode;
            int err;
            if (CFNumberGetTypeID() == CFGetTypeID(value)) {
                CFNumberRef modeNum = (CFNumberRef)value;
                CFNumberGetValue(modeNum, kCFNumberSInt32Type, &mode);
            } else {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
#define MODE_TYPE mode_t
#elif DEPLOYMENT_TARGET_WINDOWS
#define MODE_TYPE uint16_t
#else
#error Unknown or unspecified DEPLOYMENT_TARGET
#endif
                const MODE_TYPE *modePtr = (const MODE_TYPE *)CFDataGetBytePtr((CFDataRef)value);
                mode = *modePtr;
            }
            err = chmod(cPath, mode);
            if (err != 0) result = false;
        } else {
            result = false;
        }
    }

    if ((CFTypeRef)keys != buffer) CFAllocatorDeallocate(CFGetAllocator(url), keys);

    if (errorCode) *errorCode = result ? 0 : kCFURLUnknownError;
    return result;
}

static Boolean _CFFileURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *fetchedData, CFArrayRef desiredProperties, CFDictionaryRef *fetchedProperties, SInt32 *errorCode) {
    Boolean success = true;

    if (errorCode) *errorCode = 0;
    if (fetchedData) {
        void *bytes;
        CFIndex length;
        Boolean releaseAlloc = false;
        
        if (alloc == NULL) {
            // We need a real allocator to pass to _CFReadBytesFromFile so that the CFDataRef we create with
			//	CFDataCreateWithBytesNoCopy() can free up the object _CFReadBytesFromFile() returns.
            alloc = (CFAllocatorRef)CFRetain(__CFGetDefaultAllocator());
            releaseAlloc = true;
        }
        if (!_CFReadBytesFromFile(alloc, url, &bytes, &length, 0, 0)) {
            if (errorCode) *errorCode = kCFURLUnknownError;
            *fetchedData = NULL;
            success = false;
        } else {
            *fetchedData = CFDataCreateWithBytesNoCopy(alloc, (const UInt8 *)bytes, length, alloc);
        }
        if (releaseAlloc) {
            // Now the CFData should be hanging on to it.
            CFRelease(alloc);
        }
    }

    if (fetchedProperties) {
        *fetchedProperties = _CFFileURLCreatePropertiesFromResource(alloc, url, desiredProperties, errorCode);
        if (!*fetchedProperties)
	    success = false;
    }

    if ( ! success && fetchedData && *fetchedData ) {
	CFRelease( *fetchedData );
	*fetchedData = NULL;
    }
    
    return success;
}

/*
 * Support for data: URLs - RFC 2397
 * Currently this is spi for CFNetwork, to make it API, just put these constants in CFURLAccess.h
 */

/*
CF_EXPORT
const CFStringRef kCFDataURLDataLength;
CF_EXPORT
const CFStringRef kCFDataURLMimeType;
CF_EXPORT
const CFStringRef kCFDataURLTextEncodingName;
*/

/* Properties for the data: scheme. */
/* kCFDataURLDataLength is a CFNumber giving the data's length in bytes. */
/* kCFDataURLMimeType is a CFString. */
/* kCFDataURLTextEncodingName is a CFString. */

/* REMINDSMZ: From CFURLResponse.c */
static CFStringRef mimeTypeFromContentTypeComponent(CFStringRef component) {
    CFIndex compLen = CFStringGetLength(component);
    CFStringInlineBuffer buf;
    CFIndex idx;
    CFIndex firstChar = -1, lastChar = -1;
    CFCharacterSetRef whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
    CFStringInitInlineBuffer(component, &buf, CFRangeMake(0, compLen));
    
    for (idx = 0; idx < compLen; idx ++) {
		UniChar ch = CFStringGetCharacterFromInlineBuffer(&buf, idx);
		if (ch == ';') {
			// Delimits the charset
			break;
		} else if (firstChar == -1) {
			if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) {
				firstChar = idx;
			}
		} else if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) {
			lastChar = idx;
		}
    }
    if (firstChar != -1 && lastChar != -1) {
		CFMutableStringRef newContentType = CFStringCreateMutableCopy(CFGetAllocator(component), compLen, component);
		if (lastChar != compLen - 1) {
			CFStringDelete(newContentType, CFRangeMake(lastChar + 1, compLen - lastChar - 1));
		}
		if (firstChar > 0) {
			CFStringDelete(newContentType, CFRangeMake(0, firstChar));
		}
		CFStringLowercase(newContentType, NULL);
		return newContentType;
    }
    return NULL;
}

/* REMINDSMZ: From CFURLResponse.c */
static CFStringRef charsetFromContentTypeHeader(CFStringRef contentType) {
    // FIXME: Should this use KeyValuePair parsing to handle quoting properly?
    CFRange range;
    CFIndex compLen = CFStringGetLength(contentType);
    CFIndex start, end, idx;
    CFCharacterSetRef whitespaceSet;
    CFMutableStringRef result;
    
	CFStringRef kCFURLResponseCharsetPrefix = CFSTR("charset=");
	
    if (!CFStringFindWithOptions(contentType, kCFURLResponseCharsetPrefix, CFRangeMake(0, compLen), kCFCompareCaseInsensitive, &range) || range.length == 0) return NULL;
	
    whitespaceSet = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
    start = -1; 
    end = -1;
    for (idx = range.location + range.length; idx < compLen; idx ++) {
		UniChar ch = CFStringGetCharacterAtIndex(contentType, idx);
		if (ch == ';' || ch == ',') break;
		if (start == -1) {
			if (!CFCharacterSetIsCharacterMember(whitespaceSet, ch)) {
				start = idx;
				end = idx;
			} 
		} else if (!CFCharacterSetIsCharacterMember(whitespaceSet,ch)) {
			end = idx;
		}
    }
	
    if (start == -1) return NULL;
	
    result = CFStringCreateMutableCopy(CFGetAllocator(contentType), compLen,contentType);
    if (end != compLen) {
		CFStringDelete(result, CFRangeMake(end+1, compLen-end-1));
    }
    CFStringDelete(result, CFRangeMake(0, start));
    CFStringLowercase(result, NULL);
    return result;
}

#define STATIC_BUFFER_SIZE 1024

static BOOL isHexDigit(char c)
{
    return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
}

static UInt8 hexDigitValue(char c)
{
    if (c >= '0' && c <= '9') {
        return c - '0';
    }
    if (c >= 'A' && c <= 'F') {
        return c - 'A' + 10;
    }
    if (c >= 'a' && c <= 'f') {
        return c - 'a' + 10;
    }
    // NSURL_ERROR("illegal hex digit");
    return 0;
}

static CFDataRef percentEscapeDecodeBuffer(CFAllocatorRef alloc, const UInt8* srcBuffer, CFRange range, Boolean stripWhitespace) CF_RETURNS_RETAINED
{
    UInt8* dstBuffer;
    UInt8 staticDstBuffer[STATIC_BUFFER_SIZE];
	
    if (range.length > STATIC_BUFFER_SIZE) {
		dstBuffer = (UInt8*) malloc(range.length);
    } else {
		dstBuffer = staticDstBuffer;
    }
	
    CFIndex end = range.location + range.length;
	
    CFIndex i;
    CFIndex j;
    for (i = range.location, j = 0; i < end; ++i) {
		char value;
		
		if (srcBuffer[i] == '%' && end > i + 2 && isHexDigit(srcBuffer[i+1]) && isHexDigit(srcBuffer[i+2])) {
			value = hexDigitValue(srcBuffer[i+1]) * 16 + hexDigitValue(srcBuffer[i+2]);
			i += 2;
		} else {
			value = srcBuffer[i];
		}
		
		if (!stripWhitespace || !isspace(value)) {
			dstBuffer[j++] = value;
		}
    }
	
    CFDataRef result = CFDataCreate(alloc, dstBuffer, j);
	
    if (dstBuffer != staticDstBuffer) {
		free(dstBuffer);
    }
	
    return result;
}


// base 64 digits: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

static BOOL isBase64Digit(char c)
{
    return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/');
}

static BOOL isBase64DigitOrEqualSign(char c)
{
    return isBase64Digit(c) || c == '=';
}

static UInt8 base64DigitValue(char c)
{
    if (c >= 'A' && c <= 'Z') {
		return c - 'A';
    } else if (c >= 'a' && c <= 'z') {
		return 26 + c - 'a';
    } else if (c >= '0' && c <= '9') {
		return 52 + c - '0';
    } else if (c == '+') {
		return 62;
    } else if (c == '/') {
		return 63;
    } else {
		return 0;
    }
}

static CFDataRef base64DecodeData(CFAllocatorRef alloc, CFDataRef data)
{
    const UInt8 *srcBuffer = CFDataGetBytePtr(data);
    CFIndex length = CFDataGetLength(data);
    UInt8 *dstBuffer = NULL;
    UInt8 staticDstBuffer[STATIC_BUFFER_SIZE];
	CFDataRef result = NULL;
	
    // base64 encoded data length must be multiple of 4
    if (length % 4 != 0) {
		goto done;
    }
	
    if (length > STATIC_BUFFER_SIZE) {
		dstBuffer = (UInt8*) malloc(length);
    } else {
		dstBuffer = staticDstBuffer;
    }
	
    CFIndex i;
    CFIndex j;
    for (i = 0, j = 0; i < length; i+=4) {
		if (!(isBase64Digit(srcBuffer[i]) &&
			  isBase64Digit(srcBuffer[i+1]) &&
			  isBase64DigitOrEqualSign(srcBuffer[i+2]) &&
			  isBase64DigitOrEqualSign(srcBuffer[i+3]))) {
			if (dstBuffer != staticDstBuffer) {
				free(dstBuffer);
			}
			return NULL;
		}
		
		dstBuffer[j++] = (base64DigitValue(srcBuffer[i]) << 2) + (base64DigitValue(srcBuffer[i+1]) >> 4);
		if (srcBuffer[i+2] != '=') {
			dstBuffer[j++] = ((base64DigitValue(srcBuffer[i+1]) & 0xf) << 4) + (base64DigitValue(srcBuffer[i+2]) >> 2);
		}
		if (srcBuffer[i+3] != '=') {
			dstBuffer[j++] = ((base64DigitValue(srcBuffer[i+2]) & 0x3) << 6) + (base64DigitValue(srcBuffer[i+3]));
		}
    }
    
    result = CFDataCreate(alloc, dstBuffer, j);
	
done:
    if (dstBuffer != staticDstBuffer) {
		free(dstBuffer);
    }
	
    return result;
}

static inline CFStringRef percentExpandAndTrimContentType(CFAllocatorRef alloc, CFStringRef str, CFRange range)
{
    CFMutableStringRef contentTypeHeader = NULL;
    CFStringRef contentTypeUnexpanded = CFStringCreateWithSubstring(alloc, str, range);
    CFStringRef contentTypeExpanded = CFURLCreateStringByReplacingPercentEscapes(alloc, contentTypeUnexpanded, CFSTR(""));
    
    if (NULL == contentTypeExpanded) {
	contentTypeHeader = CFStringCreateMutableCopy(alloc, 0, contentTypeUnexpanded);
    } else {
	contentTypeHeader = CFStringCreateMutableCopy(alloc, 0, contentTypeExpanded);
	CFRelease(contentTypeExpanded);
    }
    CFRelease(contentTypeUnexpanded);
    CFStringTrimWhitespace(contentTypeHeader);
    
    return contentTypeHeader;
}

static Boolean parseDataRequestURL(CFURLRef url, CFDataRef* outData, CFStringRef* outMimeType, CFStringRef* outTextEncodingName)
{
    Boolean result = FALSE;
    CFAllocatorRef alloc = CFGetAllocator(url);
    CFStringRef str = CFURLCopyResourceSpecifier(url);
    if (str != NULL) {
		CFRange commaRange = CFStringFind(str, CFSTR(","), 0);
		
		if (commaRange.location != kCFNotFound) {
			CFStringRef contentTypeHeader = percentExpandAndTrimContentType(alloc, str, CFRangeMake(0, commaRange.location));
			CFStringRef mimeType = mimeTypeFromContentTypeComponent(contentTypeHeader);
			CFStringRef textEncodingName = charsetFromContentTypeHeader(contentTypeHeader);

			Boolean base64 = CFStringFind(contentTypeHeader, CFSTR(";base64"), kCFCompareCaseInsensitive).location != kCFNotFound;

			if (mimeType == NULL) {
				mimeType = (CFStringRef) CFRetain(CFSTR("text/plain"));
			}
			
			CFIndex bufferSize = CFURLGetBytes(url, NULL, 0);
			UInt8* srcBuffer = (UInt8*) malloc(bufferSize);
			CFURLGetBytes(url, srcBuffer, bufferSize);
			
			CFRange dataRange = CFURLGetByteRangeForComponent(url, kCFURLComponentResourceSpecifier, NULL);
			while (srcBuffer[dataRange.location] != ',') {
				dataRange.location++;
				dataRange.length--;
			}
			dataRange.location++;
			dataRange.length--;
			
			CFDataRef dataRef = NULL;
			
			if (! base64) {
				dataRef = percentEscapeDecodeBuffer(alloc, srcBuffer, dataRange, false);
			} else {
				CFDataRef unescapedAndStripped = percentEscapeDecodeBuffer(alloc, srcBuffer, dataRange, true);
				if (unescapedAndStripped) {
					dataRef = base64DecodeData(alloc, unescapedAndStripped);
					CFRelease(unescapedAndStripped);
				}
			}
			
			if (dataRef != NULL)  {
				*outData = dataRef;
				*outMimeType = (CFStringRef) mimeType == NULL? NULL : CFStringCreateCopy(alloc, mimeType);
				*outTextEncodingName = (CFStringRef) textEncodingName == NULL? NULL : CFStringCreateCopy(alloc, textEncodingName);
				result = true;
			}

			free(srcBuffer);
			
			if (contentTypeHeader) CFRelease(contentTypeHeader);
			if (mimeType) CFRelease(mimeType);
			if (textEncodingName) CFRelease(textEncodingName);
		}
		
		CFRelease(str);
    }
    
    return result;
}

static Boolean _CFDataURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *fetchedData, CFArrayRef desiredProperties, CFDictionaryRef *fetchedProperties, SInt32 *errorCode) {
    Boolean success = true;
	
    if (errorCode) *errorCode = 0;
	
	// We always need to fetch the data...
	CFDataRef data = NULL;
	CFStringRef mimeType = NULL;
	CFStringRef textEncodingName = NULL;

	if (! parseDataRequestURL(url, &data, &mimeType, &textEncodingName)) {
		if (errorCode)
			*errorCode = kCFURLUnknownError;
		*fetchedData = NULL;
		success = false;
	} else {
		if (fetchedData) {
			*fetchedData = CFDataCreateCopy(alloc, data);
		}
		
		if (fetchedProperties) {
			const void* propKeys[] = {
				kCFDataURLDataLength,
				kCFDataURLMimeType,
				kCFDataURLTextEncodingName,
			};
			const CFIndex propKeysCount = sizeof(propKeys) / sizeof(propKeys[0]);
			
			if (desiredProperties == NULL) {
				static CFArrayRef sAllProps = NULL;
				if (sAllProps == NULL) {
					sAllProps = CFArrayCreate(kCFAllocatorSystemDefault, propKeys, propKeysCount, &kCFTypeArrayCallBacks);
				}
				desiredProperties = sAllProps;
			}
				
			const void* vals[propKeysCount];
			const void* keys[propKeysCount];
			int ixVal = 0;
			
			CFIndex count = CFArrayGetCount(desiredProperties);
			for (CFIndex i = 0;  i < count;  i++) {
				CFStringRef key = (CFStringRef) CFArrayGetValueAtIndex(desiredProperties, i);
				
				if (CFEqual(key, kCFDataURLDataLength)) {
					CFIndex len = CFDataGetLength(data);
					keys[ixVal] = key;
					vals[ixVal++] = CFNumberCreate(alloc, kCFNumberCFIndexType, &len);
				} else if (CFEqual(key, kCFDataURLMimeType)) {
					if (mimeType != NULL) {
						keys[ixVal] = key;
						vals[ixVal++] = CFStringCreateCopy(alloc, mimeType);
					}
				} else if (CFEqual(key, kCFDataURLTextEncodingName)) {
					if (textEncodingName != NULL) {
						keys[ixVal] = key;
						vals[ixVal++] = CFStringCreateCopy(alloc, textEncodingName);
					}
				}
			}
			
			*fetchedProperties = CFDictionaryCreate(alloc, keys, vals, ixVal, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
			for (CFIndex i = 0;  i < ixVal; i++) 
				CFRelease(vals[i]);
			if (*fetchedProperties == NULL)
				success = false;
		}
		
		if (data) CFRelease(data);
		if (mimeType) CFRelease(mimeType);
		if (textEncodingName) CFRelease(textEncodingName);
    }
	
	
    return success;
}

/*************************/
/* Public routines       */
/*************************/

Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *fetchedData, CFDictionaryRef *fetchedProperties, CFArrayRef desiredProperties, SInt32 *errorCode) {
    CFStringRef scheme = CFURLCopyScheme(url);

    if (!scheme) {
        if (errorCode) *errorCode = kCFURLImproperArgumentsError;
        if (fetchedData) *fetchedData = NULL;
        if (fetchedProperties) *fetchedProperties = NULL;
        return false;
    } else {
        Boolean result;
        if (CFStringCompare(scheme, CFSTR("file"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
            result = _CFFileURLCreateDataAndPropertiesFromResource(alloc, url, fetchedData, desiredProperties, fetchedProperties, errorCode);
        } else if (CFStringCompare(scheme, CFSTR("data"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
	    result = _CFDataURLCreateDataAndPropertiesFromResource(alloc, url, fetchedData, desiredProperties, fetchedProperties, errorCode);
	} else {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
            result = __CFNetwork__CFURLCreateDataAndPropertiesFromResource(alloc, url, fetchedData, fetchedProperties, desiredProperties, errorCode);
#else
            if (fetchedData) *fetchedData = NULL;
            if (fetchedProperties) *fetchedProperties = NULL;
            if (errorCode) *errorCode = kCFURLUnknownSchemeError;
            result = false;
#endif
        }
        CFRelease(scheme);
        return result;
    }
}

CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) {
    CFArrayRef array = CFArrayCreate(alloc, (const void **)&property, 1, &kCFTypeArrayCallBacks);
    CFDictionaryRef dict;

    if (CFURLCreateDataAndPropertiesFromResource(alloc, url, NULL, &dict, array, errorCode)) {
        CFTypeRef result = CFDictionaryGetValue(dict, property);
        if (result) CFRetain(result);
        CFRelease(array);
        CFRelease(dict);
        return result;
    } else {
        if (dict) CFRelease(dict);
        CFRelease(array);
        return NULL;
    }
}

Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef data, CFDictionaryRef propertyDict, SInt32 *errorCode) {
    CFStringRef scheme = CFURLCopyScheme(url);
    if (!scheme) {
        if (errorCode) *errorCode = kCFURLImproperArgumentsError;
        return false;
    } else if (CFStringCompare(scheme, CFSTR("file"), 0) == kCFCompareEqualTo) {
        Boolean success = true;
        CFRelease(scheme);
        if (errorCode) *errorCode = 0;
        if (data) {
            if (CFURLHasDirectoryPath(url)) {
                // Create a directory
                char cPath[CFMaxPathSize];
                if (!CFURLGetFileSystemRepresentation(url, true, (unsigned char *)cPath, CFMaxPathSize))
                {
                    if (errorCode) *errorCode = kCFURLImproperArgumentsError;
                    success = false;
                } else {
                    success = _CFCreateDirectory(cPath);
                    if (!success && errorCode) *errorCode = kCFURLUnknownError;
                }
            } else {
               // Write data
                SInt32 length = CFDataGetLength(data);
                const void *bytes = (0 == length) ? (const void *)"" : CFDataGetBytePtr(data);
                success = _CFWriteBytesToFile(url, bytes, length);
                if (!success && errorCode) *errorCode = kCFURLUnknownError;
            }
        }
        if (propertyDict) {
            if (!_CFFileURLWritePropertiesToResource(url, propertyDict, errorCode))
                success = false;
        }
        return success;
    } else {
        CFRelease(scheme);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        Boolean result = __CFNetwork__CFURLWriteDataAndPropertiesToResource(url, data, propertyDict, errorCode);
	if (!result) {
	    if (errorCode) *errorCode = kCFURLUnknownSchemeError;
	}
	return result;
#else
        if (errorCode) *errorCode = kCFURLUnknownSchemeError;
        return false;
#endif
    }
}

Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) {
    CFStringRef scheme = CFURLCopyScheme(url);
    char cPath[CFMaxPathSize];

    if (!scheme) {
        if (errorCode) *errorCode = kCFURLImproperArgumentsError;
        return false;
    } else if (CFStringCompare(scheme, CFSTR("file"), 0) == kCFCompareEqualTo) {
        CFRelease(scheme);
        if (!CFURLGetFileSystemRepresentation(url, true, (unsigned char *)cPath, CFMaxPathSize)) {
            if (errorCode) *errorCode = kCFURLImproperArgumentsError;
            return false;
        }

        if (CFURLHasDirectoryPath(url)) {
            if (_CFRemoveDirectory(cPath)) {
                if (errorCode) *errorCode = 0;
                return true;
            } else {
                if (errorCode) *errorCode = kCFURLUnknownError;
                return false;
            }
        } else {
            if (_CFDeleteFile(cPath)) {
                if (errorCode) *errorCode = 0;
                return true;
            } else {
                if (errorCode) *errorCode = kCFURLUnknownError;
                return false;
            }
        }
    } else {
        CFRelease(scheme);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        Boolean result = __CFNetwork__CFURLDestroyResource(url, errorCode);
	if (!result) {
	    if (errorCode) *errorCode = kCFURLUnknownSchemeError;
	}
	return result;
#else
        if (errorCode) *errorCode = kCFURLUnknownSchemeError;
        return false;
#endif
    }
}
#pragma GCC diagnostic pop


