]> git.saurik.com Git - apple/cf.git/commitdiff
CF-855.11.tar.gz os-x-109 os-x-1091 v855.11
authorApple <opensource@apple.com>
Fri, 11 Oct 2013 21:48:24 +0000 (21:48 +0000)
committerApple <opensource@apple.com>
Fri, 11 Oct 2013 21:48:24 +0000 (21:48 +0000)
154 files changed:
CFApplicationPreferences.c
CFArray.c
CFArray.h
CFAvailability.h [new file with mode: 0644]
CFBag.c
CFBag.h
CFBase.c
CFBase.h
CFBasicHash.c
CFBasicHash.h
CFBasicHashFindBucket.m
CFBigNumber.c
CFBigNumber.h
CFBinaryHeap.c
CFBinaryHeap.h
CFBinaryPList.c
CFBitVector.c
CFBitVector.h
CFBuiltinConverters.c
CFBundle.c
CFBundle.h
CFBundlePriv.h
CFBundle_BinaryTypes.h
CFBundle_InfoPlist.c [new file with mode: 0644]
CFBundle_Internal.h
CFBundle_Resources.c
CFBurstTrie.c
CFBurstTrie.h
CFByteOrder.h
CFCalendar.c
CFCalendar.h
CFCharacterSet.c
CFCharacterSet.h
CFCharacterSetPriv.h
CFConcreteStreams.c
CFData.c
CFData.h
CFDate.c
CFDate.h
CFDateFormatter.c
CFDateFormatter.h
CFDictionary.c
CFDictionary.h
CFError.c
CFError.h
CFError_Private.h
CFFileUtilities.c
CFICUConverters.c
CFICUConverters.h
CFICULogging.h [new file with mode: 0644]
CFInternal.h
CFLocale.c
CFLocale.h
CFLocaleIdentifier.c
CFLocaleInternal.h
CFLocaleKeys.c
CFLogUtilities.h
CFMachPort.c
CFMachPort.h
CFMessagePort.c
CFMessagePort.h
CFNumber.c
CFNumber.h
CFNumberFormatter.c
CFNumberFormatter.h
CFOldStylePList.c
CFPlatform.c
CFPlatformConverters.c
CFPlugIn.c
CFPlugIn.h
CFPlugInCOM.h
CFPlugIn_Factory.c
CFPlugIn_Factory.h
CFPlugIn_Instance.c
CFPlugIn_PlugIn.c
CFPreferences.c
CFPreferences.h
CFPriv.h
CFPropertyList.c
CFPropertyList.h
CFRunLoop.c
CFRunLoop.h
CFRuntime.c
CFRuntime.h
CFSet.c
CFSet.h
CFSocket.c
CFSocket.h
CFSocketStream.c
CFSortFunctions.c
CFStorage.c
CFStorage.h
CFStream.c
CFStream.h
CFStreamAbstract.h
CFStreamInternal.h
CFStreamPriv.h
CFString.c
CFString.h
CFStringDefaultEncoding.h
CFStringEncodingConverter.c
CFStringEncodingConverter.h
CFStringEncodingConverterExt.h
CFStringEncodingConverterPriv.h
CFStringEncodingDatabase.c
CFStringEncodingDatabase.h
CFStringEncodingExt.h
CFStringEncodings.c
CFStringScanner.c
CFStringUtilities.c
CFSystemDirectories.c
CFTimeZone.c
CFTimeZone.h
CFTree.c
CFTree.h
CFURL.c
CFURL.h
CFURL.inc.h [new file with mode: 0644]
CFURLAccess.c
CFURLAccess.h
CFURLPriv.h
CFUUID.c
CFUUID.h
CFUniChar.c
CFUniChar.h
CFUniCharPriv.h
CFUnicodeDecomposition.c
CFUnicodeDecomposition.h
CFUnicodePrecomposition.c
CFUnicodePrecomposition.h
CFUserNotification.c
CFUserNotification.h
CFUtilities.c
CFUtilities.h [new file with mode: 0644]
CFVersion.c
CFWindowsUtilities.c
CFXMLInputStream.c
CFXMLInputStream.h
CFXMLNode.c
CFXMLNode.h
CFXMLParser.c
CFXMLParser.h
CFXMLPreferencesDomain.c
CFXMLTree.c
CoreFoundation.h
CoreFoundation_Prefix.h
ForFoundationOnly.h
Info.plist
Makefile
MakefileLinux
MakefileVersion
SymbolAliases
TargetConditionals.h
plconvert.c

index 937d7cdf7462bea63c8c85592a5cbebf3fe45ce5..ab38b886d066a76f662423a75f3f505a2fae7bce 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFApplicationPreferences.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -106,7 +106,7 @@ CF_EXPORT Boolean CFPreferencesAppBooleanValue(CFStringRef key, CFStringRef appN
     return result;
 }
 
-__private_extern__ CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
+CF_PRIVATE CFIndex CFPreferencesAppIntegerValue(CFStringRef key, CFStringRef appName, Boolean *keyExistsAndHasValidFormat) {
     CFPropertyListRef value;
     CFIndex result;
     CFTypeID typeID = 0;
@@ -303,7 +303,7 @@ void _CFApplicationPreferencesUpdate(_CFApplicationPreferences *self) {
 
 CF_EXPORT CFDictionaryRef _CFApplicationPreferencesCopyRepresentation(_CFApplicationPreferences *self);
 
-__private_extern__ CFDictionaryRef __CFApplicationPreferencesCopyCurrentState(void) {
+CF_PRIVATE CFDictionaryRef __CFApplicationPreferencesCopyCurrentState(void) {
     _CFApplicationPreferences *self = _CFStandardApplicationPreferences(kCFPreferencesCurrentApplication);
     CFDictionaryRef result = _CFApplicationPreferencesCopyRepresentation(self);
     return result;
@@ -436,7 +436,7 @@ void _CFApplicationPreferencesSetStandardSearchList(_CFApplicationPreferences *a
 #undef ADD_DOMAIN
 
 
-__private_extern__ _CFApplicationPreferences *_CFStandardApplicationPreferences(CFStringRef appName) {
+CF_PRIVATE _CFApplicationPreferences *_CFStandardApplicationPreferences(CFStringRef appName) {
     _CFApplicationPreferences *appPreferences;
 //    CFAssert(appName != kCFPreferencesAnyApplication, __kCFLogAssertion, "Cannot use any of the CFPreferences...App... functions with an appName of kCFPreferencesAnyApplication");
     __CFSpinLock(&__CFApplicationPreferencesLock);
index ff1bc597b863cf3c640607e94bd142d3a6839eaa..c49eb78d3eb2eae21263e8691e846b97214a7710 100644 (file)
--- a/CFArray.c
+++ b/CFArray.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFArray.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -141,7 +141,7 @@ CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketAtIndex(CFArrayRef array, CF
     return NULL;
 }
 
-__private_extern__ CFArrayCallBacks *__CFArrayGetCallBacks(CFArrayRef array) {
+CF_PRIVATE CFArrayCallBacks *__CFArrayGetCallBacks(CFArrayRef array) {
     CFArrayCallBacks *result = NULL;
     switch (__CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 3, 2)) {
     case __kCFArrayHasNullCallBacks:
@@ -229,7 +229,7 @@ static void __CFArrayReleaseValues(CFArrayRef array, CFRange range, bool release
        }
        if (releaseStorageIfPossible && 0 == range.location && __CFArrayGetCount(array) == range.length) {
            allocator = __CFGetAllocator(array);
-           if (NULL != deque && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, deque);
+           if (NULL != deque) if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, deque);
            __CFArraySetCount(array, 0);  // GC: _count == 0 ==> _store == NULL.
            ((struct __CFArray *)array)->_store = NULL;
        }
@@ -287,10 +287,10 @@ static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) {
     result = CFStringCreateMutable(allocator, 0);
     switch (__CFArrayGetType(array)) {
     case __kCFArrayImmutable:
-       CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = immutable, count = %u, values = (%s"), cf, allocator, cnt, cnt ? "\n" : "");
+       CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = immutable, count = %lu, values = (%s"), cf, allocator, (unsigned long)cnt, cnt ? "\n" : "");
        break;
     case __kCFArrayDeque:
-       CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = mutable-small, count = %u, values = (%s"), cf, allocator, cnt, cnt ? "\n" : "");
+       CFStringAppendFormat(result, NULL, CFSTR("<CFArray %p [%p]>{type = mutable-small, count = %lu, values = (%s"), cf, allocator, (unsigned long)cnt, cnt ? "\n" : "");
        break;
     }
     cb = __CFArrayGetCallBacks(array);
@@ -301,10 +301,10 @@ static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) {
            desc = (CFStringRef)INVOKE_CALLBACK1(cb->copyDescription, val);
        }
        if (NULL != desc) {
-           CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@\n"), idx, desc);
+           CFStringAppendFormat(result, NULL, CFSTR("\t%lu : %@\n"), (unsigned long)idx, desc);
            CFRelease(desc);
        } else {
-           CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, val);
+           CFStringAppendFormat(result, NULL, CFSTR("\t%lu : <%p>\n"), (unsigned long)idx, val);
        }
     }
     CFStringAppend(result, CFSTR(")}"));
@@ -355,7 +355,7 @@ static const CFRuntimeClass __CFArrayClass = {
     __CFArrayCopyDescription
 };
 
-__private_extern__ void __CFArrayInitialize(void) {
+CF_PRIVATE void __CFArrayInitialize(void) {
     __kCFArrayTypeID = _CFRuntimeRegisterClass(&__CFArrayClass);
 }
 
@@ -418,7 +418,7 @@ static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex
     return (CFArrayRef)memory;
 }
 
-__private_extern__ CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const void **values, CFIndex numValues) {
+CF_PRIVATE CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const void **values, CFIndex numValues) {
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%d) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     UInt32 flags = __kCFArrayImmutable;
     __CFBitfieldSetValue(flags, 31, 2, 0);
@@ -436,7 +436,7 @@ __private_extern__ CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator,
     return (CFArrayRef)memory;
 }
 
-__private_extern__ CFArrayRef __CFArrayCreate0(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks) {
+CF_PRIVATE CFArrayRef __CFArrayCreate0(CFAllocatorRef allocator, const void **values, CFIndex numValues, const CFArrayCallBacks *callBacks) {
     CFArrayRef result;
     const CFArrayCallBacks *cb;
     struct __CFArrayBucket *buckets;
@@ -467,13 +467,13 @@ __private_extern__ CFArrayRef __CFArrayCreate0(CFAllocatorRef allocator, const v
     return result;
 }
 
-__private_extern__ CFMutableArrayRef __CFArrayCreateMutable0(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) {
+CF_PRIVATE CFMutableArrayRef __CFArrayCreateMutable0(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks) {
     CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%d) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
     CFAssert2(capacity <= LONG_MAX / sizeof(void *), __kCFLogAssertion, "%s(): capacity (%d) is too large for this architecture", __PRETTY_FUNCTION__, capacity);
     return (CFMutableArrayRef)__CFArrayInit(allocator, __kCFArrayDeque, capacity, callBacks);
 }
 
-__private_extern__ CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFArrayRef array) {
+CF_PRIVATE CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFArrayRef array) {
     CFArrayRef result;
     const CFArrayCallBacks *cb;
     struct __CFArrayBucket *buckets;
@@ -503,7 +503,7 @@ __private_extern__ CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFA
     return result;
 }
 
-__private_extern__ CFMutableArrayRef __CFArrayCreateMutableCopy0(CFAllocatorRef allocator, CFIndex capacity, CFArrayRef array) {
+CF_PRIVATE CFMutableArrayRef __CFArrayCreateMutableCopy0(CFAllocatorRef allocator, CFIndex capacity, CFArrayRef array) {
     CFMutableArrayRef result;
     const CFArrayCallBacks *cb;
     CFIndex idx, numValues = CFArrayGetCount(array);
@@ -798,7 +798,6 @@ static void __CFArrayRepositionDequeRegions(CFMutableArrayRef array, CFRange ran
        CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt + wiggle);
        CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
        CFAllocatorRef allocator = __CFGetAllocator(array);
-        allocator = _CFConvertAllocatorToGCRefZeroEquivalent(allocator);
         Boolean collectableMemory = CF_IS_COLLECTABLE_ALLOCATOR(allocator);
        struct __CFArrayDeque *newDeque = (struct __CFArrayDeque *)CFAllocatorAllocate(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
        if (__CFOASafe) __CFSetLastAllocationEventName(newDeque, "CFArray (store-deque)");
@@ -813,6 +812,7 @@ static void __CFArrayRepositionDequeRegions(CFMutableArrayRef array, CFRange ran
        if (0 < C) objc_memmove_collectable(newBuckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket));
        __CFAssignWithWriteBarrier((void **)&array->_store, (void *)newDeque);
         if (!collectableMemory && deque) CFAllocatorDeallocate(allocator, deque);
+        if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) auto_zone_release(objc_collectableZone(), newDeque);
 //printf("3:  array %p store is now %p (%lx)\n", array, array->_store, *(unsigned long *)(array->_store));
        return;
     }
@@ -885,7 +885,6 @@ void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) {
        CFIndex capacity = __CFArrayDequeRoundUpCapacity(cap);
        CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
        CFAllocatorRef allocator = __CFGetAllocator(array);
-        allocator = _CFConvertAllocatorToGCRefZeroEquivalent(allocator);
        Boolean collectableMemory = CF_IS_COLLECTABLE_ALLOCATOR(allocator);
        if (NULL == deque) {
            deque = (struct __CFArrayDeque *)CFAllocatorAllocate(allocator, size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
@@ -903,6 +902,7 @@ void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) {
        }
        deque->_capacity = capacity;
        __CFAssignWithWriteBarrier((void **)&array->_store, (void *)deque);
+        if (collectableMemory) auto_zone_release(objc_collectableZone(), deque);
     }
     END_MUTATION(array);
 }
@@ -965,11 +965,12 @@ void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **
            struct __CFArrayDeque *deque;
            CFIndex capacity = __CFArrayDequeRoundUpCapacity(futureCnt);
            CFIndex size = sizeof(struct __CFArrayDeque) + capacity * sizeof(struct __CFArrayBucket);
-           deque = (struct __CFArrayDeque *)CFAllocatorAllocate(_CFConvertAllocatorToGCRefZeroEquivalent(allocator), size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
+           deque = (struct __CFArrayDeque *)CFAllocatorAllocate((allocator), size, isStrongMemory(array) ? __kCFAllocatorGCScannedMemory : 0);
            if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)");
            deque->_leftIdx = (capacity - newCount) / 2;
            deque->_capacity = capacity;
            __CFAssignWithWriteBarrier((void **)&array->_store, (void *)deque);
+            if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) auto_zone_release(objc_collectableZone(), deque); // GC: now safe to unroot the array body.
        }
     } else {           // Deque
        // reposition regions A and C for new region B elements in gap
@@ -1017,7 +1018,7 @@ CF_INLINE void __CFZSort(CFMutableArrayRef array, CFRange range, CFComparatorFun
     }
 }
 
-__private_extern__ void _CFArraySortValues(CFMutableArrayRef array, CFComparatorFunction comparator, void *context) {
+CF_PRIVATE void _CFArraySortValues(CFMutableArrayRef array, CFComparatorFunction comparator, void *context) {
     CFRange range = {0, CFArrayGetCount(array)};
     if (range.length < 2) {
         return;
index 020cece2d3c8b42ff05e85d4b97785eadd6f0a04..2eaa4f01dab1f41dfc2c1d2059e5babf0cddd42b 100644 (file)
--- a/CFArray.h
+++ b/CFArray.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFArray.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*!
diff --git a/CFAvailability.h b/CFAvailability.h
new file mode 100644 (file)
index 0000000..aaf0236
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+/*     CFAvailability.h
+       Copyright (c) 2013-2013, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFAVAILABILITY__)
+#define __COREFOUNDATION_CFAVAILABILITY__ 1
+
+#include <TargetConditionals.h>
+
+#if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32)
+// Even if unused, these must remain here for compatibility, because projects rely on them being included.
+#include <Availability.h>
+#include <AvailabilityMacros.h>
+#endif
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+#ifndef __has_extension
+#define __has_extension(x) 0
+#endif
+
+// The arguments to these availability macros is a version number, e.g. 10_6, 3_0 or 'NA'
+// To use a deprecation message with the macro, add a string as the last argument.
+#if __has_feature(attribute_availability_with_message)
+
+#define __NSi_2_0 introduced=2.0
+#define __NSi_2_1 introduced=2.1
+#define __NSi_2_2 introduced=2.2
+#define __NSi_3_0 introduced=3.0
+#define __NSi_3_1 introduced=3.1
+#define __NSi_3_2 introduced=3.2
+#define __NSi_4_0 introduced=4.0
+#define __NSi_4_1 introduced=4.1
+#define __NSi_4_2 introduced=4.2
+#define __NSi_4_3 introduced=4.3
+#define __NSi_5_0 introduced=5.0
+#define __NSi_5_1 introduced=5.1
+#define __NSi_6_0 introduced=6.0
+#define __NSi_6_1 introduced=6.1
+#define __NSi_7_0 introduced=7.0
+#define __NSi_8_0 introduced=8.0
+#define __NSi_9_0 introduced=9.0
+#define __NSi_10_0 introduced=10.0
+#define __NSi_10_1 introduced=10.1
+#define __NSi_10_2 introduced=10.2
+#define __NSi_10_3 introduced=10.3
+#define __NSi_10_4 introduced=10.4
+#define __NSi_10_5 introduced=10.5
+#define __NSi_10_6 introduced=10.6
+#define __NSi_10_7 introduced=10.7
+#define __NSi_10_8 introduced=10.8
+#define __NSi_10_9 introduced=10.9
+
+#define __NSd_2_0 ,deprecated=2.0
+#define __NSd_2_1 ,deprecated=2.1
+#define __NSd_2_2 ,deprecated=2.2
+#define __NSd_3_0 ,deprecated=3.0
+#define __NSd_3_1 ,deprecated=3.1
+#define __NSd_3_2 ,deprecated=3.2
+#define __NSd_4_0 ,deprecated=4.0
+#define __NSd_4_1 ,deprecated=4.1
+#define __NSd_4_2 ,deprecated=4.2
+#define __NSd_4_3 ,deprecated=4.3
+#define __NSd_5_0 ,deprecated=5.0
+#define __NSd_5_1 ,deprecated=5.1
+#define __NSd_6_0 ,deprecated=6.0
+#define __NSd_6_1 ,deprecated=6.1
+#define __NSd_7_0 ,deprecated=7.0
+#define __NSd_8_0 ,deprecated=8.0
+#define __NSd_9_0 ,deprecated=9.0
+#define __NSd_10_0 ,deprecated=10.0
+#define __NSd_10_1 ,deprecated=10.1
+#define __NSd_10_2 ,deprecated=10.2
+#define __NSd_10_3 ,deprecated=10.3
+#define __NSd_10_4 ,deprecated=10.4
+#define __NSd_10_5 ,deprecated=10.5
+#define __NSd_10_6 ,deprecated=10.6
+#define __NSd_10_7 ,deprecated=10.7
+#define __NSd_10_8 ,deprecated=10.8
+#define __NSd_10_9 ,deprecated=10.9
+
+#define __NSi_NA unavailable
+#define __NSd_NA
+
+// Do not use TBD as an argument to NS_AVAILABLE
+#define __NSi_TBD introduced=9876.5
+
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
+// This section is for compilers targeting OS X which support attribute_availability_with_message
+
+#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(macosx,__NSi_##_mac)))
+#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(macosx,__NSi_##_mac)))
+#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(macosx,unavailable)))
+#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __attribute__((availability(macosx,__NSi_##_macIntro __NSd_##_macDep,message="" __VA_ARGS__)))
+#define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __attribute__((availability(macosx,__NSi_##_macIntro __NSd_##_macDep,message="" __VA_ARGS__)))
+#define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(macosx,unavailable)))
+
+#elif (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
+// This section is for compilers targeting iOS which support attribute_availability_with_message
+
+#define CF_AVAILABLE(_mac, _ios) __attribute__((availability(ios,__NSi_##_ios)))
+#define CF_AVAILABLE_MAC(_mac) __attribute__((availability(ios,unavailable)))
+#define CF_AVAILABLE_IOS(_ios) __attribute__((availability(ios,__NSi_##_ios)))
+#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __attribute__((availability(ios,__NSi_##_iosIntro __NSd_##_iosDep,message="" __VA_ARGS__)))
+#define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __attribute__((availability(ios,unavailable)))
+#define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __attribute__((availability(ios,__NSi_##_iosIntro __NSd_##_iosDep,message="" __VA_ARGS__)))
+
+#endif
+
+#elif (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
+// This section is for OS X or iOS, and compilers without support for attribute_availability_with_message. We fall back to Availability.h.
+
+#ifndef __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_0
+#define __AVAILABILITY_INTERNAL__MAC_10_0_DEP__MAC_10_0 __AVAILABILITY_INTERNAL_DEPRECATED
+#endif
+
+#define CF_AVAILABLE(_mac, _ios) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_##_ios)
+#define CF_AVAILABLE_MAC(_mac) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_NA)
+#define CF_AVAILABLE_IOS(_ios) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
+#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
+#define CF_DEPRECATED_MAC(_macIntro, _macDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_NA, __IPHONE_NA)
+#define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
+
+#endif // __has_feature(attribute_availability_with_message)
+
+#ifndef CF_AVAILABLE
+// This section is for platforms which do not support availability
+#define CF_AVAILABLE(_mac, _ios)
+#define CF_AVAILABLE_MAC(_mac)
+#define CF_AVAILABLE_IOS(_ios)
+#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...)
+#define CF_DEPRECATED_MAC(_macIntro, _macDep, ...)
+#define CF_DEPRECATED_IOS(_iosIntro, _iosDep, ...)
+#endif
+
+// Older versions of these macros; use iOS versions instead
+#define CF_AVAILABLE_IPHONE(_ios) CF_AVAILABLE_IOS(_ios)
+#define CF_DEPRECATED_IPHONE(_iosIntro, _iosDep) CF_DEPRECATED_IOS(_iosIntro, _iosDep)
+
+// Enum availability macros
+#if __has_feature(enumerator_attributes) && __has_attribute(availability)
+#define CF_ENUM_AVAILABLE(_mac, _ios) CF_AVAILABLE(_mac, _ios)
+#define CF_ENUM_AVAILABLE_MAC(_mac) CF_AVAILABLE_MAC(_mac)
+#define CF_ENUM_AVAILABLE_IOS(_ios) CF_AVAILABLE_IOS(_ios)
+#define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...) CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, __VA_ARGS__)
+#define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep, ...) CF_DEPRECATED_MAC(_macIntro, _macDep, __VA_ARGS__)
+#define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep, ...) CF_DEPRECATED_IOS(_iosIntro, _iosDep, __VA_ARGS__)
+#else
+#define CF_ENUM_AVAILABLE(_mac, _ios)
+#define CF_ENUM_AVAILABLE_MAC(_mac)
+#define CF_ENUM_AVAILABLE_IOS(_ios)
+#define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep, ...)
+#define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep, ...)
+#define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep, ...)
+#endif
+
+// Enums and Options
+#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))
+#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
+#if (__cplusplus)
+#define CF_OPTIONS(_type, _name) _type _name; enum : _type
+#else
+#define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
+#endif
+#else
+#define CF_ENUM(_type, _name) _type _name; enum
+#define CF_OPTIONS(_type, _name) _type _name; enum
+#endif
+
+#endif // __COREFOUNDATION_CFAVAILABILITY__
diff --git a/CFBag.c b/CFBag.c
index da9e3362b76d5a8814989e64188214680e746685..15e0a7af0a141e5c7af6fa5d5ba7546cfb3207de 100644 (file)
--- a/CFBag.c
+++ b/CFBag.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBag.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -47,7 +47,6 @@
 const CFBagKeyCallBacks kCFTypeBagKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFBagKeyCallBacks kCFCopyStringBagKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFBagValueCallBacks kCFTypeBagValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
-__private_extern__ const CFBagValueCallBacks kCFTypeBagValueCompactableCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
 static const CFBagKeyCallBacks __kCFNullBagKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
 static const CFBagValueCallBacks __kCFNullBagValueCallBacks = {0, NULL, NULL, NULL, NULL};
 
@@ -133,328 +132,131 @@ CFTypeID CFBagGetTypeID(void) {
     return __kCFBagTypeID;
 }
 
-#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
-#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
-
-static uintptr_t __CFBagStandardRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0100) return stack_value;
-    return (CFBasicHashHasStrongValues(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_value) : (uintptr_t)CFRetain((CFTypeRef)stack_value);
-}
-
-static uintptr_t __CFBagStandardRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0001) return stack_key;
-    return (CFBasicHashHasStrongKeys(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_key) : (uintptr_t)CFRetain((CFTypeRef)stack_key);
-}
-
-static void __CFBagStandardReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0200) return;
-    if (CFBasicHashHasStrongValues(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_value); else CFRelease((CFTypeRef)stack_value);
-}
-
-static void __CFBagStandardReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0002) return;
-    if (CFBasicHashHasStrongKeys(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_key); else CFRelease((CFTypeRef)stack_key);
-}
-
-static Boolean __CFBagStandardEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0400) return coll_value1 == stack_value2;
-    return CFEqual((CFTypeRef)coll_value1, (CFTypeRef)stack_value2);
-}
-
-static Boolean __CFBagStandardEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0004) return coll_key1 == stack_key2;
-    return CFEqual((CFTypeRef)coll_key1, (CFTypeRef)stack_key2);
-}
-
-static uintptr_t __CFBagStandardHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0008) return stack_key;
-    return (uintptr_t)CFHash((CFTypeRef)stack_key);
-}
-
-static uintptr_t __CFBagStandardGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFBagStandardCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
-    return CFCopyDescription((CFTypeRef)stack_value);
-}
-
-static CFStringRef __CFBagStandardCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
-    return CFCopyDescription((CFTypeRef)stack_key);
-}
-
-static CFBasicHashCallbacks *__CFBagStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-static void __CFBagStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-
-static const CFBasicHashCallbacks CFBagStandardCallbacks = {
-    __CFBagStandardCopyCallbacks,
-    __CFBagStandardFreeCallbacks,
-    __CFBagStandardRetainValue,
-    __CFBagStandardRetainKey,
-    __CFBagStandardReleaseValue,
-    __CFBagStandardReleaseKey,
-    __CFBagStandardEquateValues,
-    __CFBagStandardEquateKeys,
-    __CFBagStandardHashKey,
-    __CFBagStandardGetIndirectKey,
-    __CFBagStandardCopyValueDescription,
-    __CFBagStandardCopyKeyDescription
-};
-
-static CFBasicHashCallbacks *__CFBagStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    return (CFBasicHashCallbacks *)&CFBagStandardCallbacks;
-}
-
-static void __CFBagStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-}
-    
-
-static CFBasicHashCallbacks *__CFBagCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    CFBasicHashCallbacks *newcb = NULL;
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-    } else {
-        newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
-    }
-    if (!newcb) return NULL;
-    memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
-    return newcb;
-}
-
-static void __CFBagFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-    } else {
-       CFAllocatorDeallocate(allocator, cb);
-    }
-}
-    
-static uintptr_t __CFBagRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
-    if (NULL == value_retain) return stack_value;
-    return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_value);
-}
-
-static uintptr_t __CFBagRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
-    if (NULL == key_retain) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_key);
-}
-
-static void __CFBagReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
-    if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t) stack_value);
-}
-
-static void __CFBagReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
-    if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t) stack_key);
-}
-
-static Boolean __CFBagEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
-    if (NULL == value_equal) return (coll_value1 == stack_value2);
-    return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t) coll_value1, (const_any_pointer_t) stack_value2) ? 1 : 0;
-}
-
-static Boolean __CFBagEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
-    if (NULL == key_equal) return (coll_key1 == stack_key2);
-    return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t) coll_key1, (const_any_pointer_t) stack_key2) ? 1 : 0;
-}
-
-static uintptr_t __CFBagHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
-    if (NULL == hash) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t) stack_key);
-}
-
-static uintptr_t __CFBagGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFBagCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
-    if (NULL == value_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_value);
-    return (CFStringRef)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t) stack_value);
-}
-
-static CFStringRef __CFBagCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[9];
-    if (NULL == key_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_key);
-    return (CFStringRef)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t) stack_key);
-}
 
 static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
 
-    CFBasicHashCallbacks *cb = NULL;
-    Boolean std_cb = false;
-    uint16_t specialBits = 0;
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-
-    if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
-        Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
-        Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
-        Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
-        Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
-        Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
-
-        Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
-        Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
-        Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
-        Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
-
-        Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
-        Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
-        Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
-        Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
-        Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
-
-        Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
-        Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
-        Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
-        Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
-
-        if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
-            cb = (CFBasicHashCallbacks *)&CFBagStandardCallbacks;
-            if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
-                std_cb = true;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) { // all this crap is just for figuring out two flags for GC in the way done historically; it probably simplifies down to three lines, but we let the compiler worry about that
+        Boolean set_cb = false;
+        Boolean std_cb = false;
+        const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+
+       if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
+           Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
+           Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
+           Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
+           Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
+           Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
+
+           Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
+           Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
+           Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
+           Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
+
+           Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
+           Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
+           Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
+           Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
+           Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
+
+           Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
+           Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
+           Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
+           Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
+
+           if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
+               set_cb = true;
+               if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
+                   std_cb = true;
+               } else {
+                   // just set these to tickle the GC Strong logic below in a way that mimics past practice
+                   key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+                   key_release = keyCallBacks ? keyCallBacks->release : NULL;
+                   if (useValueCB) {
+                       value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                       value_release = valueCallBacks ? valueCallBacks->release : NULL;
+                   } else {
+                       value_retain = key_retain;
+                       value_release = key_release;
+                   }
+               }
+           }
+       }
+
+        if (!set_cb) {
+            key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+            key_release = keyCallBacks ? keyCallBacks->release : NULL;
+            if (useValueCB) {
+                value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                value_release = valueCallBacks ? valueCallBacks->release : NULL;
             } else {
-                // just set these to tickle the GC Strong logic below in a way that mimics past practice
-                key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-                key_release = keyCallBacks ? keyCallBacks->release : NULL;
-                if (useValueCB) {
-                    value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-                    value_release = valueCallBacks ? valueCallBacks->release : NULL;
-                } else {
-                    value_retain = key_retain;
-                    value_release = key_release;
-                }
+                value_retain = key_retain;
+                value_release = key_release;
             }
-            if (keyRetainNull) specialBits |= 0x0001;
-            if (keyReleaseNull) specialBits |= 0x0002;
-            if (keyEquateNull) specialBits |= 0x0004;
-            if (keyHashNull) specialBits |= 0x0008;
-            if (keyDescribeNull) specialBits |= 0x0010;
-            if (valueRetainNull) specialBits |= 0x0100;
-            if (valueReleaseNull) specialBits |= 0x0200;
-            if (valueEquateNull) specialBits |= 0x0400;
-            if (valueDescribeNull) specialBits |= 0x0800;
-        }
-    }
-
-    if (!cb) {
-        Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        CFStringRef (*key_describe)(const_any_pointer_t) = NULL;
-        CFStringRef (*value_describe)(const_any_pointer_t) = NULL;
-        CFHashCode (*hash_key)(const_any_pointer_t) = NULL;
-        key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-        key_release = keyCallBacks ? keyCallBacks->release : NULL;
-        key_equal = keyCallBacks ? keyCallBacks->equal : NULL;
-        key_describe = keyCallBacks ? keyCallBacks->copyDescription : NULL;
-        if (useValueCB) {
-            value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-            value_release = valueCallBacks ? valueCallBacks->release : NULL;
-            value_equal = valueCallBacks ? valueCallBacks->equal : NULL;
-            value_describe = valueCallBacks ? valueCallBacks->copyDescription : NULL;
-        } else {
-            value_retain = key_retain;
-            value_release = key_release;
-            value_equal = key_equal;
-            value_describe = key_describe;
-        }
-        hash_key = keyCallBacks ? keyCallBacks->hash : NULL;
-
-        CFBasicHashCallbacks *newcb = NULL;
-        if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-        } else {
-            newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) return NULL;
-        newcb->copyCallbacks = __CFBagCopyCallbacks;
-        newcb->freeCallbacks = __CFBagFreeCallbacks;
-        newcb->retainValue = __CFBagRetainValue;
-        newcb->retainKey = __CFBagRetainKey;
-        newcb->releaseValue = __CFBagReleaseValue;
-        newcb->releaseKey = __CFBagReleaseKey;
-        newcb->equateValues = __CFBagEquateValues;
-        newcb->equateKeys = __CFBagEquateKeys;
-        newcb->hashKey = __CFBagHashKey;
-        newcb->getIndirectKey = __CFBagGetIndirectKey;
-        newcb->copyValueDescription = __CFBagCopyValueDescription;
-        newcb->copyKeyDescription = __CFBagCopyKeyDescription;
-        newcb->context[0] = (uintptr_t)value_retain;
-        newcb->context[1] = (uintptr_t)key_retain;
-        newcb->context[2] = (uintptr_t)value_release;
-        newcb->context[3] = (uintptr_t)key_release;
-        newcb->context[4] = (uintptr_t)value_equal;
-        newcb->context[5] = (uintptr_t)key_equal;
-        newcb->context[6] = (uintptr_t)hash_key;
-        newcb->context[8] = (uintptr_t)value_describe;
-        newcb->context[9] = (uintptr_t)key_describe;
-        cb = newcb;
-    }
 
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
         if (std_cb || value_retain != NULL || value_release != NULL) {
             flags |= kCFBasicHashStrongValues;
         }
         if (std_cb || key_retain != NULL || key_release != NULL) {
             flags |= kCFBasicHashStrongKeys;
         }
-#if CFDictionary
-        if (valueCallBacks == &kCFTypeDictionaryValueCompactableCallBacks) {
-            // Foundation allocated collections will have compactable values
-            flags |= kCFBasicHashCompactableValues;
-        }
-#endif
     }
 
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
-    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL;
+    callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL;
+    callbacks.equateKeys = keyCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks->equal : NULL;
+    callbacks.hashKey = keyCallBacks ? (CFHashCode (*)(uintptr_t))keyCallBacks->hash : NULL;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = keyCallBacks ? (CFStringRef (*)(uintptr_t))keyCallBacks->copyDescription : NULL;
+    callbacks.retainValue = useValueCB ? (valueCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))valueCallBacks->retain : NULL) : (callbacks.retainKey);
+    callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey);
+    callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys);
+    callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription);
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
     return ht;
 }
 
 #if CFDictionary
-__private_extern__ CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
 #endif
 #if CFSet || CFBag
-__private_extern__ CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFBagCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
     const_any_pointer_t *vlist = klist;
 #endif
     CFTypeID typeID = CFBagGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
-    CFBasicHashCallbacks *cb = (CFBasicHashCallbacks *)&CFBagStandardCallbacks;
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, 0x0303);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.retain;
+    callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagKeyCallBacks.release;
+    callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagKeyCallBacks.equal;
+    callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeBagKeyCallBacks.hash;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeBagKeyCallBacks.copyDescription;
+    callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.retain : callbacks.retainKey;
+    callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeBagValueCallBacks.release : callbacks.releaseKey;
+    callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeBagValueCallBacks.equal : callbacks.equateKeys;
+    callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeBagValueCallBacks.copyDescription : callbacks.copyKeyDescription;
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
+    CFBasicHashSuppressRC(ht);
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
-    CFBasicHashSetSpecialBits(ht, 0x0000);
+    CFBasicHashUnsuppressRC(ht);
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)");
     return (CFHashRef)ht;
 }
@@ -476,8 +278,7 @@ CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)");
     return (CFHashRef)ht;
 }
@@ -493,8 +294,7 @@ CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity,
     CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
     CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)");
     return (CFMutableHashRef)ht;
 }
@@ -528,8 +328,7 @@ CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     }
     if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (immutable)");
     return (CFHashRef)ht;
 }
@@ -563,8 +362,7 @@ CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)");
     return (CFMutableHashRef)ht;
 }
@@ -799,7 +597,7 @@ void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_point
 void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, setObject:(id)value forKey:(id)key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key);
     if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableSet *)hc, setObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
diff --git a/CFBag.h b/CFBag.h
index a6e60d517860f0caf97f2a60eebd79da88b79b01..15478168041c7721daae64bb3f4a0d6b92699033 100644 (file)
--- a/CFBag.h
+++ b/CFBag.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBag.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBAG__)
index 2ed181dd0355d044367c61e765558c2b16cec8ec..84cb60234852bceb42c3c5d69950cec426034b54 100644 (file)
--- a/CFBase.c
+++ b/CFBase.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBase.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -116,7 +116,7 @@ CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
-__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
+CF_PRIVATE void __CFAllocatorDeallocate(CFTypeRef cf);
 
 static kern_return_t __CFAllocatorZoneIntrospectNoOp(void) {
     return 0;
@@ -404,12 +404,12 @@ static CFStringRef __CFAllocatorCopyDescription(CFTypeRef cf) {
 // remember to release value returned from copydescr function when this happens
 }
 
-__private_extern__ CFAllocatorRef __CFAllocatorGetAllocator(CFTypeRef cf) {
+CF_PRIVATE CFAllocatorRef __CFAllocatorGetAllocator(CFTypeRef cf) {
     CFAllocatorRef allocator = (CFAllocatorRef)cf;
     return (kCFAllocatorUseContext == allocator->_allocator) ? allocator : allocator->_allocator;
 }
 
-__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf) {
+CF_PRIVATE void __CFAllocatorDeallocate(CFTypeRef cf) {
     CFAllocatorRef self = (CFAllocatorRef)cf;
     CFAllocatorRef allocator = self->_allocator;
     CFAllocatorReleaseCallBack releaseFunc = __CFAllocatorGetReleaseFunction(&self->_context);
@@ -446,31 +446,31 @@ static const CFRuntimeClass __CFAllocatorClass = {
     __CFAllocatorCopyDescription
 };
 
-__private_extern__ void __CFAllocatorInitialize(void) {
+static void _CFAllocatorSetInstanceTypeIDAndIsa(struct __CFAllocator *memory) {
+    _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
+    memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+}
+
+CF_PRIVATE void __CFAllocatorInitialize(void) {
     __kCFAllocatorTypeID = _CFRuntimeRegisterClass(&__CFAllocatorClass);
 
-    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorSystemDefault, __kCFAllocatorTypeID);
-    __kCFAllocatorSystemDefault._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    _CFAllocatorSetInstanceTypeIDAndIsa(&__kCFAllocatorSystemDefault);
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __kCFAllocatorSystemDefault._context.info = (kCFUseCollectableAllocator ? objc_collectableZone() : malloc_default_zone());
 #endif
     __kCFAllocatorSystemDefault._allocator = kCFAllocatorSystemDefault;
 
-    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMalloc, __kCFAllocatorTypeID);
-    __kCFAllocatorMalloc._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    _CFAllocatorSetInstanceTypeIDAndIsa(&__kCFAllocatorMalloc);
     __kCFAllocatorMalloc._allocator = kCFAllocatorSystemDefault;
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
-    __kCFAllocatorMallocZone._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    _CFAllocatorSetInstanceTypeIDAndIsa(&__kCFAllocatorMallocZone);
     __kCFAllocatorMallocZone._allocator = kCFAllocatorSystemDefault;
     __kCFAllocatorMallocZone._context.info = malloc_default_zone();
 #endif
 
-    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorNull, __kCFAllocatorTypeID);
-    __kCFAllocatorNull._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    _CFAllocatorSetInstanceTypeIDAndIsa(&__kCFAllocatorNull);
     __kCFAllocatorNull._allocator = kCFAllocatorSystemDefault;
-
 }
 
 CFTypeID CFAllocatorGetTypeID(void) {
@@ -482,9 +482,6 @@ CFAllocatorRef CFAllocatorGetDefault(void) {
 }
 
 void CFAllocatorSetDefault(CFAllocatorRef allocator) {
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator) {
-        HALT;
-    }
     CFAllocatorRef current = __CFGetDefaultAllocator();
 #if defined(DEBUG) 
     if (NULL != allocator) {
@@ -543,15 +540,13 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
        if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator");
     }
     memset(memory, 0, sizeof(CFRuntimeBase));
-    memory->_base._cfisa = 0;
 #if __LP64__
     memory->_base._rc = 1;
 #else
     memory->_base._cfinfo[CF_RC_BITS] = 1;
 #endif
     memory->_base._cfinfo[CF_INFO_BITS] = 0;
-    _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
-    memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
+    _CFAllocatorSetInstanceTypeIDAndIsa(memory);
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     memory->size = __CFAllocatorCustomSize;
     memory->malloc = __CFAllocatorCustomMalloc;
@@ -596,14 +591,7 @@ void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags
     void *newptr = NULL;
 
     Boolean initialRefcountOne = true;
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
-       allocator = kCFAllocatorSystemDefault;
-       initialRefcountOne = false;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
-        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
-       allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
-       if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) initialRefcountOne = false;
-    } else if (NULL == allocator) {
+    if (NULL == allocator) {
        allocator = __CFGetDefaultAllocator();
     }
 
@@ -638,10 +626,9 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
     CFAllocatorDeallocateCallBack deallocateFunc;
     void *newptr;
 
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+    if (0) {
         allocator = kCFAllocatorSystemDefault;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
-        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+    } else if (0) {
        allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
     } else if (NULL == allocator) {
         allocator = __CFGetDefaultAllocator();
@@ -699,11 +686,9 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
 void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
     CFAllocatorDeallocateCallBack deallocateFunc;
 
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
-        if (_CFAllocatorIsGCRefZero(allocator)) return;
+    if (0) {
         allocator = kCFAllocatorSystemDefault;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
-        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+    } else if (0) {
        allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
        if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) return;
     } else if (NULL == allocator) {
@@ -736,10 +721,9 @@ CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex siz
     CFAllocatorPreferredSizeCallBack prefFunc;
     CFIndex newsize = 0;
 
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+    if (0) {
         allocator = kCFAllocatorSystemDefault;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
-        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+    } else if (0) {
        allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
     } else if (NULL == allocator) {
         allocator = __CFGetDefaultAllocator();
@@ -766,10 +750,9 @@ CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex siz
 }
 
 void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context) {
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
+    if (0) {
         allocator = kCFAllocatorSystemDefault;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator) {
-        // Under GC, we can't use just any old allocator when the GCRefZero allocator was requested
+    } else if (0) {
        allocator = kCFUseCollectableAllocator ? kCFAllocatorSystemDefault : __CFGetDefaultAllocator();
     } else if (NULL == allocator) {
         allocator = __CFGetDefaultAllocator();
@@ -799,7 +782,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
     context->preferredSize = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
 }
 
-__private_extern__ void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
+CF_PRIVATE void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
 {
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator))
         return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), false, false);
@@ -807,7 +790,7 @@ __private_extern__ void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFInde
         return CFAllocatorAllocate(allocator, size, hint);
 }
 
-__private_extern__ void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
+CF_PRIVATE void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
 {
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
        if (ptr && (newsize == 0)) {
@@ -821,7 +804,7 @@ __private_extern__ void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void
     return CFAllocatorReallocate(allocator, ptr, newsize, hint);
 }
 
-__private_extern__ void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
+CF_PRIVATE void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
 {
     // when running GC, don't deallocate.
     if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, ptr);
@@ -873,10 +856,9 @@ static const CFRuntimeClass __CFNullClass = {
     __CFNullCopyDescription
 };
 
-__private_extern__ void __CFNullInitialize(void) {
+CF_PRIVATE void __CFNullInitialize(void) {
     __kCFNullTypeID = _CFRuntimeRegisterClass(&__CFNullClass);
-    _CFRuntimeSetInstanceTypeID(&__kCFNull, __kCFNullTypeID);
-    __kCFNull._base._cfisa = __CFISAForTypeID(__kCFNullTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFNull, __kCFNullTypeID);
 }
 
 CFTypeID CFNullGetTypeID(void) {
index e2d7aca7d80c1b379b2128d1096b8206d6a00593..7a83135c779a97bde6f6dae09d3ca14399fbcfe2 100644 (file)
--- a/CFBase.h
+++ b/CFBase.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 
 /*     CFBase.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBASE__)
 #define __COREFOUNDATION_CFBASE__ 1
 
 #include <TargetConditionals.h>
+#include <CoreFoundation/CFAvailability.h>
 
 #if (defined(__CYGWIN32__) || defined(_WIN32)) && !defined(__WIN32__)
 #define __WIN32__ 1
 #include <Block.h>
 #endif
 
-// The arguments to these availability macros is a version number, e.g. 10_6, 3_0
-#if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
-#include <AvailabilityMacros.h>
-#include <Availability.h>
-
-#ifndef __IPHONE_5_0
-#define __IPHONE_5_0 50000
-#endif
-
-#ifndef __IPHONE_6_0
-#define __IPHONE_6_0 60000
-#endif
-
-// Available on MacOS and iOS
-#define CF_AVAILABLE(_mac, _ios) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_##_ios)
-
-// Available on MacOS only
-#define CF_AVAILABLE_MAC(_mac) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_NA)
-
-// Available on iOS only
-#define CF_AVAILABLE_IOS(_ios) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
-
-// Deprecated on either MacOS or iOS, or deprecated on both (check version numbers for details)
-#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
-
-// Deprecated on MacOS, unavailable on iOS
-#define CF_DEPRECATED_MAC(_macIntro, _macDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_NA, __IPHONE_NA)
-
-// Unavailable on MacOS, deprecated on iOS
-#define CF_DEPRECATED_IOS(_iosIntro, _iosDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
-
-#else
-
-#if TARGET_OS_WIN32
-#include <AvailabilityMacros.h>
-#include <Availability.h>
-#endif
-
-#define CF_AVAILABLE(_mac, _ios)
-#define CF_AVAILABLE_MAC(_mac)
-#define CF_AVAILABLE_IOS(_ios)
-#define CF_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep)
-#define CF_DEPRECATED_MAC(_macIntro, _macDep)
-#define CF_DEPRECATED_IOS(_iosIntro, _iosDep)
-
-#endif
-
-#if __has_feature(enumerator_attributes) && __has_attribute(availability)
-#define CF_ENUM_AVAILABLE(_mac, _ios) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_##_ios)
-#define CF_ENUM_AVAILABLE_MAC(_mac) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_NA)
-#define CF_ENUM_AVAILABLE_IOS(_ios) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_##_ios)
-#define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
-#define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_##_macIntro, __MAC_##_macDep, __IPHONE_NA, __IPHONE_NA)
-#define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA, __MAC_NA, __IPHONE_##_iosIntro, __IPHONE_##_iosDep)
-#else
-#define CF_ENUM_AVAILABLE(_mac, _ios)
-#define CF_ENUM_AVAILABLE_MAC(_mac)
-#define CF_ENUM_AVAILABLE_IOS(_ios)
-#define CF_ENUM_DEPRECATED(_macIntro, _macDep, _iosIntro, _iosDep)
-#define CF_ENUM_DEPRECATED_MAC(_macIntro, _macDep)
-#define CF_ENUM_DEPRECATED_IOS(_iosIntro, _iosDep)
-#endif
-
-#if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))
-#define CF_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
-#if (__cplusplus)
-#define CF_OPTIONS(_type, _name) _type _name; enum : _type
-#else
-#define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
-#endif
-#else
-#define CF_ENUM(_type, _name) _type _name; enum
-#define CF_OPTIONS(_type, _name) _type _name; enum
-#endif
-
-// Older versions of these macro; use IOS versions instead
-#define CF_AVAILABLE_IPHONE(_ios) CF_AVAILABLE_IOS(_ios)
-#define CF_DEPRECATED_IPHONE(_iosIntro, _iosDep) CF_DEPRECATED_IOS(_iosIntro, _iosDep)
-
   #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
     #include <libkern/OSTypes.h>
   #endif
@@ -396,6 +318,12 @@ CF_EXPORT double kCFCoreFoundationVersionNumber;
 #define kCFCoreFoundationVersionNumber10_7_2    635.15
 #define kCFCoreFoundationVersionNumber10_7_3    635.19
 #define kCFCoreFoundationVersionNumber10_7_4    635.21
+#define kCFCoreFoundationVersionNumber10_7_5    635.21
+#define kCFCoreFoundationVersionNumber10_8      744.00
+#define kCFCoreFoundationVersionNumber10_8_1    744.00
+#define kCFCoreFoundationVersionNumber10_8_2    744.12
+#define kCFCoreFoundationVersionNumber10_8_3    744.18
+#define kCFCoreFoundationVersionNumber10_8_4    744.19
 #endif
 
 #if TARGET_OS_IPHONE
@@ -409,8 +337,10 @@ CF_EXPORT double kCFCoreFoundationVersionNumber;
 #define kCFCoreFoundationVersionNumber_iOS_4_1 550.38
 #define kCFCoreFoundationVersionNumber_iOS_4_2 550.52
 #define kCFCoreFoundationVersionNumber_iOS_4_3 550.52
-#define kCFCoreFoundationVersionNumber_iOS_5_0 675
-#define kCFCoreFoundationVersionNumber_iOS_5_1 690.1
+#define kCFCoreFoundationVersionNumber_iOS_5_0 675.00
+#define kCFCoreFoundationVersionNumber_iOS_5_1 690.10
+#define kCFCoreFoundationVersionNumber_iOS_6_0 793.00
+#define kCFCoreFoundationVersionNumber_iOS_6_1 793.00
 #endif
 
 #if __LLP64__
@@ -494,8 +424,6 @@ const CFNullRef kCFNull;    // the singleton null instance
    argument indicates "use the default"; this is the same as using kCFAllocatorDefault
    or the return value from CFAllocatorGetDefault().  This assures that you will use
    the allocator in effect at that time.
-
-   You should rarely use kCFAllocatorSystemDefault, the default default allocator.
 */
 typedef const struct __CFAllocator * CFAllocatorRef;
 
@@ -609,6 +537,8 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
 
 /* Polymorphic CF functions */
 
+CF_IMPLICIT_BRIDGING_ENABLED
+
 CF_EXPORT
 CFTypeID CFGetTypeID(CFTypeRef cf);
 
@@ -622,11 +552,10 @@ CF_EXPORT
 void CFRelease(CFTypeRef cf);
 
 CF_EXPORT
-CFIndex CFGetRetainCount(CFTypeRef cf);
+CFTypeRef CFAutorelease(CFTypeRef CF_RELEASES_ARGUMENT arg) CF_AVAILABLE(10_9, 7_0);
 
-// This function is unavailable in ARC mode. Use CFBridgingRelease instead.
 CF_EXPORT
-CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE;
+CFIndex CFGetRetainCount(CFTypeRef cf);
 
 CF_EXPORT
 Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2);
@@ -640,6 +569,12 @@ CFStringRef CFCopyDescription(CFTypeRef cf);
 CF_EXPORT
 CFAllocatorRef CFGetAllocator(CFTypeRef cf);
 
+CF_IMPLICIT_BRIDGING_DISABLED
+
+// This function is unavailable in ARC mode.
+CF_EXPORT
+CFTypeRef CFMakeCollectable(CFTypeRef cf) CF_AUTOMATED_REFCOUNT_UNAVAILABLE;
+
 CF_EXTERN_C_END
 
 #endif /* ! __COREFOUNDATION_CFBASE__ */
index 6e94e1a1b28b7398b127f6d82c33a0dc0d8cba16..074a505a7d344af045abc4740955b24f80606b81 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBasicHash.m
-       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -31,6 +31,9 @@
 #import <CoreFoundation/CFSet.h>
 #import <Block.h>
 #import <math.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#import <dispatch/dispatch.h>
+#endif
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 #define __SetLastAllocationEventName(A, B) do { if (__CFOASafe && (A)) __CFSetLastAllocationEventName(A, B); } while (0)
@@ -38,9 +41,6 @@
 #define __SetLastAllocationEventName(A, B) do { } while (0)
 #endif
 
-#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
-#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
-
 #define __AssignWithWriteBarrier(location, value) objc_assign_strongCast((id)value, (id *)location)
 
 #define ENABLE_DTRACE_PROBES 0
@@ -307,9 +307,9 @@ typedef union {
 
 struct __CFBasicHash {
     CFRuntimeBase base;
-    struct { // 128 bits
+    struct { // 192 bits
+        uint16_t mutations;
         uint8_t hash_style:2;
-        uint8_t fast_grow:1;
         uint8_t keys_offset:1;
         uint8_t counts_offset:2;
         uint8_t counts_width:2;
@@ -321,49 +321,71 @@ struct __CFBasicHash {
         uint8_t int_values:1;
         uint8_t int_keys:1;
         uint8_t indirect_keys:1;
-        uint8_t compactable_keys:1;
-        uint8_t compactable_values:1;
-        uint8_t finalized:1;
-        uint8_t __2:4;
-        uint8_t num_buckets_idx;  /* index to number of buckets */
-        uint32_t used_buckets;    /* number of used buckets */
-        uint8_t __8:8;
-        uint8_t __9:8;
-        uint16_t special_bits;
-        uint16_t deleted;
-        uint16_t mutations;
+        uint32_t used_buckets;      /* number of used buckets */
+        uint64_t deleted:16;
+        uint64_t num_buckets_idx:8; /* index to number of buckets */
+        uint64_t __kret:10;
+        uint64_t __vret:10;
+        uint64_t __krel:10;
+        uint64_t __vrel:10;
+        uint64_t __:1;
+        uint64_t null_rc:1;
+        uint64_t fast_grow:1;
+        uint64_t finalized:1;
+        uint64_t __kdes:10;
+        uint64_t __vdes:10;
+        uint64_t __kequ:10;
+        uint64_t __vequ:10;
+        uint64_t __khas:10;
+        uint64_t __kget:10;
     } bits;
-    __strong CFBasicHashCallbacks *callbacks;
     void *pointers[1];
 };
 
-__private_extern__ Boolean CFBasicHashHasStrongValues(CFConstBasicHashRef ht) {
-#if DEPLOYMENT_TARGET_MACOSX
-    return ht->bits.strong_values ? true : false;
-#else
-    return false;
-#endif
-}
+static void *CFBasicHashCallBackPtrs[(1UL << 10)];
+static int32_t CFBasicHashCallBackPtrsCount = 0;
 
-__private_extern__ Boolean CFBasicHashHasStrongKeys(CFConstBasicHashRef ht) {
-#if DEPLOYMENT_TARGET_MACOSX
-    return ht->bits.strong_keys ? true : false;
-#else
-    return false;
-#endif
+static int32_t CFBasicHashGetPtrIndex(void *ptr) {
+    static dispatch_once_t once;
+    dispatch_once(&once, ^{
+        CFBasicHashCallBackPtrs[0] = NULL;
+        CFBasicHashCallBackPtrs[1] = (void *)CFCopyDescription;
+        CFBasicHashCallBackPtrs[2] = (void *)__CFTypeCollectionRelease;
+        CFBasicHashCallBackPtrs[3] = (void *)__CFTypeCollectionRetain;
+        CFBasicHashCallBackPtrs[4] = (void *)CFEqual;
+        CFBasicHashCallBackPtrs[5] = (void *)CFHash;
+        CFBasicHashCallBackPtrs[6] = (void *)__CFStringCollectionCopy;
+        CFBasicHashCallBackPtrs[7] = NULL;
+        CFBasicHashCallBackPtrsCount = 8;
+    });
+
+    // The uniquing here is done locklessly for best performance, and in
+    // a way that will keep multiple threads from stomping each other's
+    // newly registered values, but may result in multiple slots
+    // containing the same pointer value.
+
+    int32_t idx;
+    for (idx = 0; idx < CFBasicHashCallBackPtrsCount; idx++) {
+        if (CFBasicHashCallBackPtrs[idx] == ptr) return idx;
+    }
+
+    if (1000 < CFBasicHashCallBackPtrsCount) HALT;
+    idx = OSAtomicIncrement32(&CFBasicHashCallBackPtrsCount); // returns new value
+    CFBasicHashCallBackPtrs[idx - 1] = ptr;
+    return idx - 1;
 }
 
-CF_INLINE Boolean __CFBasicHashHasCompactableKeys(CFConstBasicHashRef ht) {
+CF_PRIVATE Boolean CFBasicHashHasStrongValues(CFConstBasicHashRef ht) {
 #if DEPLOYMENT_TARGET_MACOSX
-    return ht->bits.compactable_keys ? true : false;
+    return ht->bits.strong_values ? true : false;
 #else
     return false;
 #endif
 }
 
-CF_INLINE Boolean __CFBasicHashHasCompactableValues(CFConstBasicHashRef ht) {
+CF_PRIVATE Boolean CFBasicHashHasStrongKeys(CFConstBasicHashRef ht) {
 #if DEPLOYMENT_TARGET_MACOSX
-    return ht->bits.compactable_values ? true : false;
+    return ht->bits.strong_keys ? true : false;
 #else
     return false;
 #endif
@@ -394,36 +416,71 @@ CF_INLINE Boolean __CFBasicHashHasHashCache(CFConstBasicHashRef ht) {
 }
 
 CF_INLINE uintptr_t __CFBasicHashImportValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    return ht->callbacks->retainValue(ht, stack_value);
+    uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vret];
+    if (!func || ht->bits.null_rc) return stack_value;
+    CFAllocatorRef alloc = CFGetAllocator(ht);
+    return func(alloc, stack_value);
 }
 
 CF_INLINE uintptr_t __CFBasicHashImportKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    return ht->callbacks->retainKey(ht, stack_key);
+    uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kret];
+    if (!func || ht->bits.null_rc) return stack_key;
+    CFAllocatorRef alloc = CFGetAllocator(ht);
+    return func(alloc, stack_key);
 }
 
 CF_INLINE void __CFBasicHashEjectValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    ht->callbacks->releaseValue(ht, stack_value);
+    void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vrel];
+    if (!func || ht->bits.null_rc) return;
+    CFAllocatorRef alloc = CFGetAllocator(ht);
+    func(alloc, stack_value);
 }
 
 CF_INLINE void __CFBasicHashEjectKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    ht->callbacks->releaseKey(ht, stack_key);
+    void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__krel];
+    if (!func || ht->bits.null_rc) return;
+    CFAllocatorRef alloc = CFGetAllocator(ht);
+    func(alloc, stack_key);
+}
+
+CF_INLINE CFStringRef __CFBasicHashDescValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+    CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vdes];
+    if (!func) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
+    return func(stack_value);
+}
+
+CF_INLINE CFStringRef __CFBasicHashDescKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kdes];
+    if (!func) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
+    return func(stack_key);
 }
 
 CF_INLINE Boolean __CFBasicHashTestEqualValue(CFConstBasicHashRef ht, uintptr_t stack_value_a, uintptr_t stack_value_b) {
-    return ht->callbacks->equateValues(ht, stack_value_a, stack_value_b);
+    Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vequ];
+    if (!func) return (stack_value_a == stack_value_b);
+    return func(stack_value_a, stack_value_b);
 }
 
 CF_INLINE Boolean __CFBasicHashTestEqualKey(CFConstBasicHashRef ht, uintptr_t in_coll_key, uintptr_t stack_key) {
     COCOA_HASHTABLE_TEST_EQUAL(ht, in_coll_key, stack_key);
-    return ht->callbacks->equateKeys(ht, in_coll_key, stack_key);
+    Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kequ];
+    if (!func) return (in_coll_key == stack_key);
+    return func(in_coll_key, stack_key);
 }
 
 CF_INLINE CFHashCode __CFBasicHashHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    CFHashCode hash_code = (CFHashCode)ht->callbacks->hashKey(ht, stack_key);
+    CFHashCode (*func)(uintptr_t) = (CFHashCode (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__khas];
+    CFHashCode hash_code = func ? func(stack_key) : stack_key;
     COCOA_HASHTABLE_HASH_KEY(ht, stack_key, hash_code);
     return hash_code;
 }
 
+CF_INLINE uintptr_t __CFBasicHashGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_key) {
+    uintptr_t (*func)(uintptr_t) = (uintptr_t (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kget];
+    if (!func) return coll_key;
+    return func(coll_key);
+}
+
 CF_INLINE CFBasicHashValue *__CFBasicHashGetValues(CFConstBasicHashRef ht) {
     return (CFBasicHashValue *)ht->pointers[0];
 }
@@ -481,7 +538,7 @@ CF_INLINE uintptr_t __CFBasicHashGetKey(CFConstBasicHashRef ht, CFIndex idx) {
     }
     if (ht->bits.indirect_keys) {
         uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
-        return ht->callbacks->getIndirectKey(ht, stack_value);
+        return __CFBasicHashGetIndirectKey(ht, stack_value);
     }
     return __CFBasicHashGetValue(ht, idx);
 }
@@ -666,11 +723,11 @@ CF_INLINE CFIndex __CFBasicHashGetNumBucketsIndexForCapacity(CFConstBasicHashRef
     return 0;
 }
 
-__private_extern__ CFIndex CFBasicHashGetNumBuckets(CFConstBasicHashRef ht) {
+CF_PRIVATE CFIndex CFBasicHashGetNumBuckets(CFConstBasicHashRef ht) {
     return __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
 }
 
-__private_extern__ CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht) {
+CF_PRIVATE CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht) {
     return __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx);
 }
 
@@ -679,7 +736,7 @@ __private_extern__ CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht) {
 // the found bucket or the index of the bucket which should be filled by
 // an add operation. For a set or multiset, the .weak_key and .weak_value
 // are the same.
-__private_extern__ CFBasicHashBucket CFBasicHashGetBucket(CFConstBasicHashRef ht, CFIndex idx) {
+CF_PRIVATE CFBasicHashBucket CFBasicHashGetBucket(CFConstBasicHashRef ht, CFIndex idx) {
     CFBasicHashBucket result;
     result.idx = idx;
     if (__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
@@ -860,7 +917,7 @@ CF_INLINE CFIndex __CFBasicHashFindBucket_NoCollision(CFConstBasicHashRef ht, ui
     return kCFNotFound;
 }
 
-__private_extern__ CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
+CF_PRIVATE CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
     if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
         CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
         return result;
@@ -868,22 +925,18 @@ __private_extern__ CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef h
     return __CFBasicHashFindBucket(ht, stack_key);
 }
 
-__private_extern__ uint16_t CFBasicHashGetSpecialBits(CFConstBasicHashRef ht) {
-    return ht->bits.special_bits;
+CF_PRIVATE void CFBasicHashSuppressRC(CFBasicHashRef ht) {
+    ht->bits.null_rc = 1;
 }
 
-__private_extern__ uint16_t CFBasicHashSetSpecialBits(CFBasicHashRef ht, uint16_t bits) {
-    uint16_t old =  ht->bits.special_bits;
-    ht->bits.special_bits = bits;
-    return old;
+CF_PRIVATE void CFBasicHashUnsuppressRC(CFBasicHashRef ht) {
+    ht->bits.null_rc = 0;
 }
 
-__private_extern__ CFOptionFlags CFBasicHashGetFlags(CFConstBasicHashRef ht) {
+CF_PRIVATE CFOptionFlags CFBasicHashGetFlags(CFConstBasicHashRef ht) {
     CFOptionFlags flags = (ht->bits.hash_style << 13);
     if (CFBasicHashHasStrongValues(ht)) flags |= kCFBasicHashStrongValues;
     if (CFBasicHashHasStrongKeys(ht)) flags |= kCFBasicHashStrongKeys;
-    if (__CFBasicHashHasCompactableKeys(ht)) flags |= kCFBasicHashCompactableKeys;
-    if (__CFBasicHashHasCompactableValues(ht)) flags |= kCFBasicHashCompactableValues;
     if (ht->bits.fast_grow) flags |= kCFBasicHashAggressiveGrowth;
     if (ht->bits.keys_offset) flags |= kCFBasicHashHasKeys;
     if (ht->bits.counts_offset) flags |= kCFBasicHashHasCounts;
@@ -891,11 +944,7 @@ __private_extern__ CFOptionFlags CFBasicHashGetFlags(CFConstBasicHashRef ht) {
     return flags;
 }
 
-__private_extern__ const CFBasicHashCallbacks *CFBasicHashGetCallbacks(CFConstBasicHashRef ht) {
-    return ht->callbacks;
-}
-
-__private_extern__ CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht) {
+CF_PRIVATE CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht) {
     if (ht->bits.counts_offset) {
         CFIndex total = 0L;
         CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
@@ -907,7 +956,7 @@ __private_extern__ CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht) {
     return (CFIndex)ht->bits.used_buckets;
 }
 
-__private_extern__ CFIndex CFBasicHashGetCountOfKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+CF_PRIVATE CFIndex CFBasicHashGetCountOfKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
     if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
         return 0L;
     }
@@ -917,7 +966,7 @@ __private_extern__ CFIndex CFBasicHashGetCountOfKey(CFConstBasicHashRef ht, uint
     return __CFBasicHashFindBucket(ht, stack_key).count;
 }
 
-__private_extern__ CFIndex CFBasicHashGetCountOfValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+CF_PRIVATE CFIndex CFBasicHashGetCountOfValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
     if (__CFBasicHashSubABZero == stack_value) {
         return 0L;
     }
@@ -935,7 +984,7 @@ __private_extern__ CFIndex CFBasicHashGetCountOfValue(CFConstBasicHashRef ht, ui
     return total;
 }
 
-__private_extern__ Boolean CFBasicHashesAreEqual(CFConstBasicHashRef ht1, CFConstBasicHashRef ht2) {
+CF_PRIVATE Boolean CFBasicHashesAreEqual(CFConstBasicHashRef ht1, CFConstBasicHashRef ht2) {
     CFIndex cnt1 = CFBasicHashGetCount(ht1);
     if (cnt1 != CFBasicHashGetCount(ht2)) return false;
     if (0 == cnt1) return true;
@@ -955,7 +1004,7 @@ __private_extern__ Boolean CFBasicHashesAreEqual(CFConstBasicHashRef ht1, CFCons
     return equal;
 }
 
-__private_extern__ void CFBasicHashApply(CFConstBasicHashRef ht, Boolean (^block)(CFBasicHashBucket)) {
+CF_PRIVATE void CFBasicHashApply(CFConstBasicHashRef ht, Boolean (^block)(CFBasicHashBucket)) {
     CFIndex used = (CFIndex)ht->bits.used_buckets, cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
     for (CFIndex idx = 0; 0 < used && idx < cnt; idx++) {
         CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
@@ -968,7 +1017,7 @@ __private_extern__ void CFBasicHashApply(CFConstBasicHashRef ht, Boolean (^block
     }
 }
 
-__private_extern__ void CFBasicHashApplyIndexed(CFConstBasicHashRef ht, CFRange range, Boolean (^block)(CFBasicHashBucket)) {
+CF_PRIVATE void CFBasicHashApplyIndexed(CFConstBasicHashRef ht, CFRange range, Boolean (^block)(CFBasicHashBucket)) {
     if (range.length < 0) HALT;
     if (range.length == 0) return;
     CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
@@ -983,7 +1032,7 @@ __private_extern__ void CFBasicHashApplyIndexed(CFConstBasicHashRef ht, CFRange
     }
 }
 
-__private_extern__ void CFBasicHashGetElements(CFConstBasicHashRef ht, CFIndex bufferslen, uintptr_t *weak_values, uintptr_t *weak_keys) {
+CF_PRIVATE void CFBasicHashGetElements(CFConstBasicHashRef ht, CFIndex bufferslen, uintptr_t *weak_values, uintptr_t *weak_keys) {
     CFIndex used = (CFIndex)ht->bits.used_buckets, cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
     CFIndex offset = 0;
     for (CFIndex idx = 0; 0 < used && idx < cnt && offset < bufferslen; idx++) {
@@ -999,10 +1048,10 @@ __private_extern__ void CFBasicHashGetElements(CFConstBasicHashRef ht, CFIndex b
     }
 }
 
-__private_extern__ unsigned long __CFBasicHashFastEnumeration(CFConstBasicHashRef ht, struct __objcFastEnumerationStateEquivalent2 *state, void *stackbuffer, unsigned long count) {
+CF_PRIVATE unsigned long __CFBasicHashFastEnumeration(CFConstBasicHashRef ht, struct __objcFastEnumerationStateEquivalent2 *state, void *stackbuffer, unsigned long count) {
     /* copy as many as count items over */
     if (0 == state->state) {        /* first time */
-        state->mutationsPtr = (unsigned long *)&ht->bits + (__LP64__ ? 1 : 3);
+        state->mutationsPtr = (unsigned long *)&ht->bits;
     }
     state->itemsPtr = (unsigned long *)stackbuffer;
     CFIndex cntx = 0;
@@ -1078,10 +1127,6 @@ static void __CFBasicHashDrain(CFBasicHashRef ht, Boolean forFinalization) {
             }
         }
 
-    if (forFinalization) {
-        ht->callbacks->freeCallbacks(ht, allocator, ht->callbacks);
-    }
-
     if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
         CFAllocatorDeallocate(allocator, old_values);
         CFAllocatorDeallocate(allocator, old_keys);
@@ -1121,12 +1166,12 @@ static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) {
     uintptr_t *new_hashes = NULL;
 
     if (0 < new_num_buckets) {
-        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), __CFBasicHashHasCompactableValues(ht));
+        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), 0);
         if (!new_values) HALT;
         __SetLastAllocationEventName(new_values, "CFBasicHash (value-store)");
         memset(new_values, 0, new_num_buckets * sizeof(CFBasicHashValue));
         if (ht->bits.keys_offset) {
-            new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongKeys(ht), __CFBasicHashHasCompactableKeys(ht));
+            new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongKeys(ht), 0);
             if (!new_keys) HALT;
             __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)");
             memset(new_keys, 0, new_num_buckets * sizeof(CFBasicHashValue));
@@ -1180,7 +1225,7 @@ static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) {
                     if (__CFBasicHashSubABOne == stack_key) stack_key = ~0UL;
                 }
                 if (ht->bits.indirect_keys) {
-                    stack_key = ht->callbacks->getIndirectKey(ht, stack_value);
+                    stack_key = __CFBasicHashGetIndirectKey(ht, stack_value);
                 }
                 CFIndex bkt_idx = __CFBasicHashFindBucket_NoCollision(ht, stack_key, old_hashes ? old_hashes[idx] : 0UL);
                 __CFBasicHashSetValue(ht, bkt_idx, stack_value, false, false);
@@ -1219,7 +1264,7 @@ static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) {
 #endif
 }
 
-__private_extern__ void CFBasicHashSetCapacity(CFBasicHashRef ht, CFIndex capacity) {
+CF_PRIVATE void CFBasicHashSetCapacity(CFBasicHashRef ht, CFIndex capacity) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (ht->bits.used_buckets < capacity) {
         ht->bits.mutations++;
@@ -1300,7 +1345,7 @@ static void __CFBasicHashRemoveValue(CFBasicHashRef ht, CFIndex bkt_idx) {
     }
 }
 
-__private_extern__ Boolean CFBasicHashAddValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
+CF_PRIVATE Boolean CFBasicHashAddValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == stack_key) HALT;
     if (__CFBasicHashSubABOne == stack_key) HALT;
@@ -1320,7 +1365,7 @@ __private_extern__ Boolean CFBasicHashAddValue(CFBasicHashRef ht, uintptr_t stac
     return false;
 }
 
-__private_extern__ void CFBasicHashReplaceValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
+CF_PRIVATE void CFBasicHashReplaceValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == stack_key) HALT;
     if (__CFBasicHashSubABOne == stack_key) HALT;
@@ -1332,7 +1377,7 @@ __private_extern__ void CFBasicHashReplaceValue(CFBasicHashRef ht, uintptr_t sta
     }
 }
 
-__private_extern__ void CFBasicHashSetValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
+CF_PRIVATE void CFBasicHashSetValue(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t stack_value) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == stack_key) HALT;
     if (__CFBasicHashSubABOne == stack_key) HALT;
@@ -1346,7 +1391,7 @@ __private_extern__ void CFBasicHashSetValue(CFBasicHashRef ht, uintptr_t stack_k
     }
 }
 
-__private_extern__ CFIndex CFBasicHashRemoveValue(CFBasicHashRef ht, uintptr_t stack_key) {
+CF_PRIVATE CFIndex CFBasicHashRemoveValue(CFBasicHashRef ht, uintptr_t stack_key) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) return 0;
     CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
@@ -1361,7 +1406,7 @@ __private_extern__ CFIndex CFBasicHashRemoveValue(CFBasicHashRef ht, uintptr_t s
     return bkt.count;
 }
 
-__private_extern__ CFIndex CFBasicHashRemoveValueAtIndex(CFBasicHashRef ht, CFIndex idx) {
+CF_PRIVATE CFIndex CFBasicHashRemoveValueAtIndex(CFBasicHashRef ht, CFIndex idx) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
     if (1 < bkt.count) {
@@ -1375,13 +1420,13 @@ __private_extern__ CFIndex CFBasicHashRemoveValueAtIndex(CFBasicHashRef ht, CFIn
     return bkt.count;
 }
 
-__private_extern__ void CFBasicHashRemoveAllValues(CFBasicHashRef ht) {
+CF_PRIVATE void CFBasicHashRemoveAllValues(CFBasicHashRef ht) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (0 == ht->bits.num_buckets_idx) return;
     __CFBasicHashDrain(ht, false);
 }
 
-Boolean CFBasicHashAddIntValueAndInc(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t int_value) {
+CF_PRIVATE Boolean CFBasicHashAddIntValueAndInc(CFBasicHashRef ht, uintptr_t stack_key, uintptr_t int_value) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == stack_key) HALT;
     if (__CFBasicHashSubABOne == stack_key) HALT;
@@ -1413,7 +1458,7 @@ Boolean CFBasicHashAddIntValueAndInc(CFBasicHashRef ht, uintptr_t stack_key, uin
     return false;
 }
 
-void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value) {
+CF_PRIVATE void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value) {
     if (!CFBasicHashIsMutable(ht)) HALT;
     if (__CFBasicHashSubABZero == int_value) HALT;
     if (__CFBasicHashSubABOne == int_value) HALT;
@@ -1435,7 +1480,7 @@ void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value) {
     __CFBasicHashRemoveValue(ht, bkt_idx);
 }
 
-__private_extern__ size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean total) {
+CF_PRIVATE size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean total) {
     size_t size = sizeof(struct __CFBasicHash);
     if (ht->bits.keys_offset) size += sizeof(CFBasicHashValue *);
     if (ht->bits.counts_offset) size += sizeof(void *);
@@ -1447,21 +1492,20 @@ __private_extern__ size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean tot
             if (ht->bits.keys_offset) size += malloc_size(__CFBasicHashGetKeys(ht));
             if (ht->bits.counts_offset) size += malloc_size(__CFBasicHashGetCounts(ht));
             if (__CFBasicHashHasHashCache(ht)) size += malloc_size(__CFBasicHashGetHashes(ht));
-            size += malloc_size((void *)ht->callbacks);
         }
     }
     return size;
 }
 
-__private_extern__ CFStringRef CFBasicHashCopyDescription(CFConstBasicHashRef ht, Boolean detailed, CFStringRef prefix, CFStringRef entryPrefix, Boolean describeElements) {
+CF_PRIVATE CFStringRef CFBasicHashCopyDescription(CFConstBasicHashRef ht, Boolean detailed, CFStringRef prefix, CFStringRef entryPrefix, Boolean describeElements) {
     CFMutableStringRef result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
     CFStringAppendFormat(result, NULL, CFSTR("%@{type = %s %s%s, count = %ld,\n"), prefix, (CFBasicHashIsMutable(ht) ? "mutable" : "immutable"), ((ht->bits.counts_offset) ? "multi" : ""), ((ht->bits.keys_offset) ? "dict" : "set"), CFBasicHashGetCount(ht));
     if (detailed) {
         const char *cb_type = "custom";
         CFStringAppendFormat(result, NULL, CFSTR("%@hash cache = %s, strong values = %s, strong keys = %s, cb = %s,\n"), prefix, (__CFBasicHashHasHashCache(ht) ? "yes" : "no"), (CFBasicHashHasStrongValues(ht) ? "yes" : "no"), (CFBasicHashHasStrongKeys(ht) ? "yes" : "no"), cb_type);
-        CFStringAppendFormat(result, NULL, CFSTR("%@num bucket index = %d, num buckets = %ld, capacity = %d, num buckets used = %u,\n"), prefix, ht->bits.num_buckets_idx, CFBasicHashGetNumBuckets(ht), CFBasicHashGetCapacity(ht), ht->bits.used_buckets);
+        CFStringAppendFormat(result, NULL, CFSTR("%@num bucket index = %d, num buckets = %ld, capacity = %ld, num buckets used = %u,\n"), prefix, ht->bits.num_buckets_idx, CFBasicHashGetNumBuckets(ht), (long)CFBasicHashGetCapacity(ht), ht->bits.used_buckets);
         CFStringAppendFormat(result, NULL, CFSTR("%@counts width = %d, finalized = %s,\n"), prefix,((ht->bits.counts_offset) ? (1 << ht->bits.counts_width) : 0), (ht->bits.finalized ? "yes" : "no"));
-        CFStringAppendFormat(result, NULL, CFSTR("%@num mutations = %ld, num deleted = %ld, size = %ld, total size = %ld,\n"), prefix, ht->bits.mutations, ht->bits.deleted, CFBasicHashGetSize(ht, false), CFBasicHashGetSize(ht, true));
+        CFStringAppendFormat(result, NULL, CFSTR("%@num mutations = %ld, num deleted = %ld, size = %ld, total size = %ld,\n"), prefix, (long)ht->bits.mutations, (long)ht->bits.deleted, CFBasicHashGetSize(ht, false), CFBasicHashGetSize(ht, true));
         CFStringAppendFormat(result, NULL, CFSTR("%@values ptr = %p, keys ptr = %p, counts ptr = %p, hashes ptr = %p,\n"), prefix, __CFBasicHashGetValues(ht), ((ht->bits.keys_offset) ? __CFBasicHashGetKeys(ht) : NULL), ((ht->bits.counts_offset) ? __CFBasicHashGetCounts(ht) : NULL), (__CFBasicHashHasHashCache(ht) ? __CFBasicHashGetHashes(ht) : NULL));
     }
     CFStringAppendFormat(result, NULL, CFSTR("%@entries =>\n"), prefix);
@@ -1473,9 +1517,9 @@ __private_extern__ CFStringRef CFBasicHashCopyDescription(CFConstBasicHashRef ht
                     kDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)bkt.weak_key);
                 }
             } else {
-                vDesc = ht->callbacks->copyValueDescription(ht, bkt.weak_value);
+                vDesc = __CFBasicHashDescValue(ht, bkt.weak_value);
                 if (ht->bits.keys_offset) {
-                    kDesc = ht->callbacks->copyKeyDescription(ht, bkt.weak_key);
+                    kDesc = __CFBasicHashDescKey(ht, bkt.weak_key);
                 }
             }
             if (ht->bits.keys_offset && ht->bits.counts_offset) {
@@ -1495,25 +1539,25 @@ __private_extern__ CFStringRef CFBasicHashCopyDescription(CFConstBasicHashRef ht
     return result;
 }
 
-__private_extern__ void CFBasicHashShow(CFConstBasicHashRef ht) {
+CF_PRIVATE void CFBasicHashShow(CFConstBasicHashRef ht) {
     CFStringRef str = CFBasicHashCopyDescription(ht, true, CFSTR(""), CFSTR("\t"), false);
     CFShow(str);
     CFRelease(str);
 }
 
-__private_extern__ Boolean __CFBasicHashEqual(CFTypeRef cf1, CFTypeRef cf2) {
+CF_PRIVATE Boolean __CFBasicHashEqual(CFTypeRef cf1, CFTypeRef cf2) {
     CFBasicHashRef ht1 = (CFBasicHashRef)cf1;
     CFBasicHashRef ht2 = (CFBasicHashRef)cf2;
 //#warning this used to require that the key and value equal callbacks were pointer identical
     return CFBasicHashesAreEqual(ht1, ht2);
 }
 
-__private_extern__ CFHashCode __CFBasicHashHash(CFTypeRef cf) {
+CF_PRIVATE CFHashCode __CFBasicHashHash(CFTypeRef cf) {
     CFBasicHashRef ht = (CFBasicHashRef)cf;
     return CFBasicHashGetCount(ht);
 }
 
-__private_extern__ CFStringRef __CFBasicHashCopyDescription(CFTypeRef cf) {
+CF_PRIVATE CFStringRef __CFBasicHashCopyDescription(CFTypeRef cf) {
     CFBasicHashRef ht = (CFBasicHashRef)cf;
     CFStringRef desc = CFBasicHashCopyDescription(ht, false, CFSTR(""), CFSTR("\t"), true);
     CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFBasicHash %p [%p]>%@"), cf, CFGetAllocator(cf), desc);
@@ -1521,7 +1565,7 @@ __private_extern__ CFStringRef __CFBasicHashCopyDescription(CFTypeRef cf) {
     return result;
 }
 
-__private_extern__ void __CFBasicHashDeallocate(CFTypeRef cf) {
+CF_PRIVATE void __CFBasicHashDeallocate(CFTypeRef cf) {
     CFBasicHashRef ht = (CFBasicHashRef)cf;
     if (ht->bits.finalized) HALT;
     ht->bits.finalized = 1;
@@ -1546,12 +1590,12 @@ static const CFRuntimeClass __CFBasicHashClass = {
     __CFBasicHashCopyDescription
 };
 
-__private_extern__ CFTypeID CFBasicHashGetTypeID(void) {
+CF_PRIVATE CFTypeID CFBasicHashGetTypeID(void) {
     if (_kCFRuntimeNotATypeID == __kCFBasicHashTypeID) __kCFBasicHashTypeID = _CFRuntimeRegisterClass(&__CFBasicHashClass);
     return __kCFBasicHashTypeID;
 }
 
-CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags, const CFBasicHashCallbacks *cb) {
+CF_PRIVATE CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags, const CFBasicHashCallbacks *cb) {
     size_t size = sizeof(struct __CFBasicHash) - sizeof(CFRuntimeBase);
     if (flags & kCFBasicHashHasKeys) size += sizeof(CFBasicHashValue *); // keys
     if (flags & kCFBasicHashHasCounts) size += sizeof(void *); // counts
@@ -1570,11 +1614,6 @@ CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags,
     ht->bits.int_values = (flags & kCFBasicHashIntegerValues) ? 1 : 0;
     ht->bits.int_keys = (flags & kCFBasicHashIntegerKeys) ? 1 : 0;
     ht->bits.indirect_keys = (flags & kCFBasicHashIndirectKeys) ? 1 : 0;
-    ht->bits.compactable_keys = (flags & kCFBasicHashCompactableKeys) ? 1 : 0;
-    ht->bits.compactable_values = (flags & kCFBasicHashCompactableValues) ? 1 : 0;
-    ht->bits.__2 = 0;
-    ht->bits.__8 = 0;
-    ht->bits.__9 = 0;
     ht->bits.num_buckets_idx = 0;
     ht->bits.used_buckets = 0;
     ht->bits.deleted = 0;
@@ -1603,7 +1642,17 @@ CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags,
     ht->bits.weak_keys = 0;
 #endif
 
-    __AssignWithWriteBarrier(&ht->callbacks, cb);
+    ht->bits.__kret = CFBasicHashGetPtrIndex((void *)cb->retainKey);
+    ht->bits.__vret = CFBasicHashGetPtrIndex((void *)cb->retainValue);
+    ht->bits.__krel = CFBasicHashGetPtrIndex((void *)cb->releaseKey);
+    ht->bits.__vrel = CFBasicHashGetPtrIndex((void *)cb->releaseValue);
+    ht->bits.__kdes = CFBasicHashGetPtrIndex((void *)cb->copyKeyDescription);
+    ht->bits.__vdes = CFBasicHashGetPtrIndex((void *)cb->copyValueDescription);
+    ht->bits.__kequ = CFBasicHashGetPtrIndex((void *)cb->equateKeys);
+    ht->bits.__vequ = CFBasicHashGetPtrIndex((void *)cb->equateValues);
+    ht->bits.__khas = CFBasicHashGetPtrIndex((void *)cb->hashKey);
+    ht->bits.__kget = CFBasicHashGetPtrIndex((void *)cb->getIndirectKey);
+
     for (CFIndex idx = 0; idx < offset; idx++) {
         ht->pointers[idx] = NULL;
     }
@@ -1619,13 +1668,8 @@ CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags,
     return ht;
 }
 
-CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashRef src_ht) {
+CF_PRIVATE CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashRef src_ht) {
     size_t size = CFBasicHashGetSize(src_ht, false) - sizeof(CFRuntimeBase);
-    CFBasicHashCallbacks *newcb = src_ht->callbacks->copyCallbacks(src_ht, allocator, src_ht->callbacks);
-    if (NULL == newcb) {
-        return NULL;
-    }
-
     CFIndex new_num_buckets = __CFBasicHashTableSizes[src_ht->bits.num_buckets_idx];
     CFBasicHashValue *new_values = NULL, *new_keys = NULL;
     void *new_counts = NULL;
@@ -1634,8 +1678,7 @@ CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashR
     if (0 < new_num_buckets) {
         Boolean strongValues = CFBasicHashHasStrongValues(src_ht) && !(kCFUseCollectableAllocator && !CF_IS_COLLECTABLE_ALLOCATOR(allocator));
         Boolean strongKeys = CFBasicHashHasStrongKeys(src_ht) && !(kCFUseCollectableAllocator && !CF_IS_COLLECTABLE_ALLOCATOR(allocator));
-        Boolean compactableValues = __CFBasicHashHasCompactableValues(src_ht) && !(kCFUseCollectableAllocator && !CF_IS_COLLECTABLE_ALLOCATOR(allocator));
-        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory2(allocator, new_num_buckets, sizeof(CFBasicHashValue), strongValues, compactableValues);
+        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory2(allocator, new_num_buckets, sizeof(CFBasicHashValue), strongValues, 0);
         if (!new_values) return NULL; // in this unusual circumstance, leak previously allocated blocks for now
         __SetLastAllocationEventName(new_values, "CFBasicHash (value-store)");
         if (src_ht->bits.keys_offset) {
@@ -1667,7 +1710,6 @@ CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashR
     }
     ht->bits.finalized = 0;
     ht->bits.mutations = 1;
-    __AssignWithWriteBarrier(&ht->callbacks, newcb);
 
     if (0 == new_num_buckets) {
 #if ENABLE_MEMORY_COUNTERS
@@ -1740,13 +1782,4 @@ CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashR
     return ht;
 }
 
-__private_extern__ void __CFBasicHashSetCallbacks(CFBasicHashRef ht, const CFBasicHashCallbacks *cb) {
-    __AssignWithWriteBarrier(&ht->callbacks, cb);
-}
-
-void _CFbhx588461(CFBasicHashRef ht, Boolean growth) {
-    if (!CFBasicHashIsMutable(ht)) HALT;
-    if (ht->bits.finalized) HALT;
-    ht->bits.fast_grow = growth ? 1 : 0;
-}
 
index eb85edfde781a43b4618fb5c5a313f64af41cae1..362d6c99e5328ee3f9b189ffd82915a89a4e90d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBasicHash.h
-       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2013, Apple Inc. All rights reserved.
 */
 
 #include <CoreFoundation/CFBase.h>
@@ -65,9 +65,6 @@ enum {
     kCFBasicHashExponentialHashing = (__kCFBasicHashExponentialHashingValue << 13),
 
     kCFBasicHashAggressiveGrowth = (1UL << 15),
-    
-    kCFBasicHashCompactableValues = (1UL << 16),
-    kCFBasicHashCompactableKeys = (1UL << 17),
 };
 
 // Note that for a hash table without keys, the value is treated as the key,
@@ -96,33 +93,26 @@ CF_INLINE void CFBasicHashMakeImmutable(CFBasicHashRef ht) {
 typedef struct __CFBasicHashCallbacks CFBasicHashCallbacks;
 
 struct __CFBasicHashCallbacks {
-    CFBasicHashCallbacks *(*copyCallbacks)(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);        // Return new value
-    void (*freeCallbacks)(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-    uintptr_t (*retainValue)(CFConstBasicHashRef ht, uintptr_t stack_value);   // Return 2nd arg or new value
-    uintptr_t (*retainKey)(CFConstBasicHashRef ht, uintptr_t stack_key);       // Return 2nd arg or new key
-    void (*releaseValue)(CFConstBasicHashRef ht, uintptr_t stack_value);
-    void (*releaseKey)(CFConstBasicHashRef ht, uintptr_t stack_key);
-    Boolean (*equateValues)(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2); // 2nd arg is in-collection value, 3rd arg is probe parameter OR in-collection value for a second collection
-    Boolean (*equateKeys)(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2); // 2nd arg is in-collection key, 3rd arg is probe parameter
-    uintptr_t (*hashKey)(CFConstBasicHashRef ht, uintptr_t stack_key);
-    uintptr_t (*getIndirectKey)(CFConstBasicHashRef ht, uintptr_t coll_value); // Return key; 2nd arg is in-collection value
-    CFStringRef (*copyValueDescription)(CFConstBasicHashRef ht, uintptr_t stack_value);
-    CFStringRef (*copyKeyDescription)(CFConstBasicHashRef ht, uintptr_t stack_key);
-    uintptr_t context[0]; // variable size; any pointers in here must remain valid as long as the CFBasicHash
+    uintptr_t (*retainValue)(CFAllocatorRef alloc, uintptr_t stack_value);     // Return 2nd arg or new value
+    uintptr_t (*retainKey)(CFAllocatorRef alloc, uintptr_t stack_key); // Return 2nd arg or new key
+    void (*releaseValue)(CFAllocatorRef alloc, uintptr_t stack_value);
+    void (*releaseKey)(CFAllocatorRef alloc, uintptr_t stack_key);
+    Boolean (*equateValues)(uintptr_t coll_value1, uintptr_t stack_value2); // 1st arg is in-collection value, 2nd arg is probe parameter OR in-collection value for a second collection
+    Boolean (*equateKeys)(uintptr_t coll_key1, uintptr_t stack_key2); // 1st arg is in-collection key, 2nd arg is probe parameter
+    CFHashCode (*hashKey)(uintptr_t stack_key);
+    uintptr_t (*getIndirectKey)(uintptr_t coll_value); // Return key; 1st arg is in-collection value
+    CFStringRef (*copyValueDescription)(uintptr_t stack_value);
+    CFStringRef (*copyKeyDescription)(uintptr_t stack_key);
 };
 
 Boolean CFBasicHashHasStrongValues(CFConstBasicHashRef ht);
 Boolean CFBasicHashHasStrongKeys(CFConstBasicHashRef ht);
 
-uint16_t CFBasicHashGetSpecialBits(CFConstBasicHashRef ht);
-uint16_t CFBasicHashSetSpecialBits(CFBasicHashRef ht, uint16_t bits);
-
 CFOptionFlags CFBasicHashGetFlags(CFConstBasicHashRef ht);
 CFIndex CFBasicHashGetNumBuckets(CFConstBasicHashRef ht);
 CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht);
 void CFBasicHashSetCapacity(CFBasicHashRef ht, CFIndex capacity);
 
-const CFBasicHashCallbacks *CFBasicHashGetCallbacks(CFConstBasicHashRef ht);
 CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht);
 CFBasicHashBucket CFBasicHashGetBucket(CFConstBasicHashRef ht, CFIndex idx);
 CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key);
@@ -144,6 +134,8 @@ Boolean CFBasicHashAddIntValueAndInc(CFBasicHashRef ht, uintptr_t stack_key, uin
 void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value);
 
 size_t CFBasicHashGetSize(CFConstBasicHashRef ht, Boolean total);
+void CFBasicHashSuppressRC(CFBasicHashRef ht);
+void CFBasicHashUnsuppressRC(CFBasicHashRef ht);
 
 CFStringRef CFBasicHashCopyDescription(CFConstBasicHashRef ht, Boolean detailed, CFStringRef linePrefix, CFStringRef entryLinePrefix, Boolean describeElements);
 
@@ -158,7 +150,6 @@ extern unsigned long __CFBasicHashFastEnumeration(CFConstBasicHashRef ht, struct
 // creation functions create mutable CFBasicHashRefs
 CFBasicHashRef CFBasicHashCreate(CFAllocatorRef allocator, CFOptionFlags flags, const CFBasicHashCallbacks *cb);
 CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashRef ht);
-void __CFBasicHashSetCallbacks(CFBasicHashRef ht, const CFBasicHashCallbacks *cb);
 
 
 CF_EXTERN_C_END
index ccbcb69431e26d35ae6f73b91b36e41a8274eaca..bbc87a9e5cd1bbfbc7833d4eedbbc687d84de4ee 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBasicHashFindBucket.m
-       Copyright (c) 2009-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2009-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -132,7 +132,7 @@ FIND_BUCKET_NAME (CFConstBasicHashRef ht, uintptr_t stack_key
             if (__CFBasicHashSubABOne == curr_key) curr_key = ~0UL;
 #if FIND_BUCKET_FOR_INDIRECT_KEY
             // curr_key holds the value coming in here
-            curr_key = ht->callbacks->getIndirectKey(ht, curr_key);
+            curr_key = __CFBasicHashGetIndirectKey(ht, curr_key);
 #endif
             if (curr_key == stack_key || ((!hashes || hashes[probe] == hash_code) && __CFBasicHashTestEqualKey(ht, curr_key, stack_key))) {
                 COCOA_HASHTABLE_PROBING_END(ht, idx + 1);
index 62ea129cdade42b221d79bd81a0f631388feb095..cfe2c77b83261a92f6ce773b501f23cdc355e3e6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBigNumber.c
-       Copyright (c) 2012-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2012-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Original author: Zhi Feng Huang
 */
 #include "CFInternal.h"
 
 
+typedef struct {
+    int64_t high;
+    uint64_t low;
+} CFSInt128Struct;
+
 #define kCFNumberSInt128Type 17
 
+CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);
+
 #if __LP64__
 
 #ifndef _INT128_T
@@ -286,11 +293,13 @@ __uint128_t _CFBigNumGetUInt128(const _CFBigNum *num) {
 
 
 void _CFBigNumInitWithCFNumber(_CFBigNum *r, CFNumberRef inNum) {
-    uint8_t bytes[128];
+    uint8_t bytes[128 + 16];
     memset(bytes, 0, sizeof(bytes));
-    CFNumberType type = CFNumberGetType(inNum);
-    CFNumberGetValue(inNum, type, (void *)bytes);
-    _CFBigNumInitWithBytes(r, (const void *)bytes, type);
+    // round bytes up to next multiple of 16; compiler attributes won't always guarantee big alignment
+    void *bytesa = (uint8_t *)(((uintptr_t)bytes / 16) * 16 + 16);
+    CFNumberType type = _CFNumberGetType2(inNum);
+    CFNumberGetValue(inNum, type, bytesa);
+    _CFBigNumInitWithBytes(r, bytesa, type);
 }
 
 void _CFBigNumInitWithBytes(_CFBigNum *r, const void *bytes, CFNumberType type) {
@@ -341,9 +350,13 @@ void _CFBigNumInitWithBytes(_CFBigNum *r, const void *bytes, CFNumberType type)
         }
         return;
 #if __LP64__
-    case kCFNumberSInt128Type:
-        _CFBigNumInitWithInt128(r, *(__int128_t *)bytes);
+    case kCFNumberSInt128Type: {
+        CFSInt128Struct s;
+        memmove(&s, bytes, sizeof(CFSInt128Struct)); // the hard way because bytes might not be aligned
+        __int128_t val = (__int128_t)s.low + ((__int128_t)s.high << 64);
+        _CFBigNumInitWithInt128(r, val);
         return;
+    }
 #endif
     default:
         return;
index 7fc0a8924ab95f4afb39963d4f0909b6423f92ba..26ec11f682b385798de7f7d184b1fab4cc390159 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBigNumber.h
-       Copyright (c) 2012-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2012-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBIGNUMBER__)
index f711b8f9db8cb3e98bde76e01d112f354d3cd6f7..06a98e749cb71cf394ad72e96406507813eb068f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryHeap.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -156,7 +156,7 @@ static CFStringRef __CFBinaryHeapCopyDescription(CFTypeRef cf) {
     const void **list, *buffer[256];
     cnt = __CFBinaryHeapCount(heap);
     result = CFStringCreateMutable(CFGetAllocator(heap), 0);
-    CFStringAppendFormat(result, NULL, CFSTR("<CFBinaryHeap %p [%p]>{count = %u, capacity = %u, objects = (\n"), cf, CFGetAllocator(heap), cnt, __CFBinaryHeapCapacity(heap));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFBinaryHeap %p [%p]>{count = %lu, capacity = %lu, objects = (\n"), cf, CFGetAllocator(heap), (unsigned long)cnt, (unsigned long)__CFBinaryHeapCapacity(heap));
     list = (cnt <= 128) ? (const void **)buffer : (const void **)CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0); // GC OK
     if (__CFOASafe && list != buffer) __CFSetLastAllocationEventName(list, "CFBinaryHeap (temp)");
     CFBinaryHeapGetValues(heap, list);
@@ -167,10 +167,10 @@ static CFStringRef __CFBinaryHeapCopyDescription(CFTypeRef cf) {
            desc = heap->_callbacks.copyDescription(item);
        }
        if (NULL != desc) {
-           CFStringAppendFormat(result, NULL, CFSTR("\t%u : %@\n"), idx, desc);
+           CFStringAppendFormat(result, NULL, CFSTR("\t%lu : %@\n"), (unsigned long)idx, desc);
            CFRelease(desc);
        } else {
-           CFStringAppendFormat(result, NULL, CFSTR("\t%u : <%p>\n"), idx, item);
+           CFStringAppendFormat(result, NULL, CFSTR("\t%lu : <%p>\n"), (unsigned long)idx, item);
        }
     }
     CFStringAppend(result, CFSTR(")}"));
@@ -207,7 +207,7 @@ static const CFRuntimeClass __CFBinaryHeapClass = {
     __CFBinaryHeapCopyDescription
 };
 
-__private_extern__ void __CFBinaryHeapInitialize(void) {
+CF_PRIVATE void __CFBinaryHeapInitialize(void) {
     __kCFBinaryHeapTypeID = _CFRuntimeRegisterClass(&__CFBinaryHeapClass);
 }
 
index da94e9adbfebae8b96e32f04d792129b3d5e26d3..ccccf55d4583145ceee63e3d6a54f72e3b32af33 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryHeap.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 /*!
         @header CFBinaryHeap
index ed1a8546a4fcc5c4144cee8367b578a3e05e83d2..8a1e56a3b6390affd67f23536fa0067cd5d87704 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryPList.c
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -128,7 +128,7 @@ static const CFRuntimeClass __CFKeyedArchiverUIDClass = {
     __CFKeyedArchiverUIDCopyDescription
 };
 
-__private_extern__ void __CFKeyedArchiverUIDInitialize(void) {
+CF_PRIVATE void __CFKeyedArchiverUIDInitialize(void) {
     __kCFKeyedArchiverUIDTypeID = _CFRuntimeRegisterClass(&__CFKeyedArchiverUIDClass);
 }
 
@@ -154,10 +154,12 @@ uint32_t _CFKeyedArchiverUIDGetValue(CFKeyedArchiverUIDRef uid) {
 #pragma mark -
 #pragma mark Writing
 
-__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
+CF_PRIVATE CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
 
 typedef struct {
     CFTypeRef stream;
+    void *databytes;
+    uint64_t datalen;
     CFErrorRef error;
     uint64_t written;
     int32_t used;
@@ -168,19 +170,26 @@ typedef struct {
 static void writeBytes(__CFBinaryPlistWriteBuffer *buf, const UInt8 *bytes, CFIndex length) {
     if (0 == length) return;
     if (buf->error) return;
+    if (buf->databytes) {
+        if (buf->datalen < buf->written + length) {
+            buf->error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Binary property list writing could not be completed because databytes is full."));
+            return;
+        }
+        memmove((char *)buf->databytes + buf->written, bytes, length);
+    }
     if (buf->streamIsData) {
-        CFDataAppendBytes((CFMutableDataRef)buf->stream, bytes, length);
+        if (buf->stream) CFDataAppendBytes((CFMutableDataRef)buf->stream, bytes, length);
         buf->written += length;
     } else {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
        while (0 < length) {
-           CFIndex ret = CFWriteStreamWrite((CFWriteStreamRef)buf->stream, bytes, length);
+           CFIndex ret = buf->stream ? CFWriteStreamWrite((CFWriteStreamRef)buf->stream, bytes, length) : length;
             if (ret == 0) {
                buf->error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Binary property list writing could not be completed because stream is full."));
                 return;
             }
             if (ret < 0) {
-                CFErrorRef err = CFWriteStreamCopyError((CFWriteStreamRef)buf->stream);
+                CFErrorRef err = buf->stream ? CFWriteStreamCopyError((CFWriteStreamRef)buf->stream) : NULL;
                 buf->error = err ? err : __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Binary property list writing could not be completed because the stream had an unknown error."));
                 return;
             }
@@ -194,47 +203,53 @@ static void writeBytes(__CFBinaryPlistWriteBuffer *buf, const UInt8 *bytes, CFIn
     }
 }
 
+static void bufferFlush(__CFBinaryPlistWriteBuffer *buf) {
+    writeBytes(buf, buf->buffer, buf->used);
+    buf->used = 0;
+}
+
 static void bufferWrite(__CFBinaryPlistWriteBuffer *buf, const uint8_t *buffer, CFIndex count) {
     if (0 == count) return;
     if ((CFIndex)sizeof(buf->buffer) <= count) {
-       writeBytes(buf, buf->buffer, buf->used);
-       buf->used = 0;
+       bufferFlush(buf);
        writeBytes(buf, buffer, count);
        return;
     }
     CFIndex copyLen = __CFMin(count, (CFIndex)sizeof(buf->buffer) - buf->used);
-    memmove(buf->buffer + buf->used, buffer, copyLen);
+    if (buf->stream || buf->databytes) {
+        switch (copyLen) {
+        case 4: buf->buffer[buf->used + 3] = buffer[3]; /* FALLTHROUGH */
+        case 3: buf->buffer[buf->used + 2] = buffer[2]; /* FALLTHROUGH */
+        case 2: buf->buffer[buf->used + 1] = buffer[1]; /* FALLTHROUGH */
+        case 1: buf->buffer[buf->used] = buffer[0]; break;
+        default: memmove(buf->buffer + buf->used, buffer, copyLen);
+        }
+    }
     buf->used += copyLen;
     if (sizeof(buf->buffer) == buf->used) {
        writeBytes(buf, buf->buffer, sizeof(buf->buffer));
-       memmove(buf->buffer, buffer + copyLen, count - copyLen);
+        if (buf->stream || buf->databytes) {
+            memmove(buf->buffer, buffer + copyLen, count - copyLen);
+        }
        buf->used = count - copyLen;
     }
 }
 
-static void bufferFlush(__CFBinaryPlistWriteBuffer *buf) {
-    writeBytes(buf, buf->buffer, buf->used);
-    buf->used = 0;
-}
-
 /*
 HEADER
        magic number ("bplist")
-       file format version
-       byte length of plist incl. header, an encoded int number object (as below) [v.2+ only]
-       32-bit CRC (ISO/IEC 8802-3:1989) of plist bytes w/o CRC, encoded always as
-            "0x12 0x__ 0x__ 0x__ 0x__", big-endian, may be 0 to indicate no CRC [v.2+ only]
+       file format version (currently "0?")
 
 OBJECT TABLE
        variable-sized objects
 
        Object Formats (marker byte followed by additional info in some cases)
-       null    0000 0000                       // null object [v1+ only]
+       null    0000 0000                       // null object [v"1?"+ only]
        bool    0000 1000                       // false
        bool    0000 1001                       // true
-       url     0000 1100       string          // URL with no base URL, recursive encoding of URL string [v1+ only]
-       url     0000 1101       base string     // URL with base URL, recursive encoding of base URL, then recursive encoding of URL string [v1+ only]
-       uuid    0000 1110                       // 16-byte UUID [v1+ only]
+       url     0000 1100       string          // URL with no base URL, recursive encoding of URL string [v"1?"+ only]
+       url     0000 1101       base string     // URL with base URL, recursive encoding of base URL, then recursive encoding of URL string [v"1?"+ only]
+       uuid    0000 1110                       // 16-byte UUID [v"1?"+ only]
        fill    0000 1111                       // fill byte
        int     0001 0nnn       ...             // # of bytes is 2^nnn, big-endian bytes
        real    0010 0nnn       ...             // # of bytes is 2^nnn, big-endian bytes
@@ -242,12 +257,12 @@ OBJECT TABLE
        data    0100 nnnn       [int]   ...     // nnnn is number of bytes unless 1111 then int count follows, followed by bytes
        string  0101 nnnn       [int]   ...     // ASCII string, nnnn is # of chars, else 1111 then int count, then bytes
        string  0110 nnnn       [int]   ...     // Unicode string, nnnn is # of chars, else 1111 then int count, then big-endian 2-byte uint16_t
-               0111 xxxx                       // unused
+       string  0111 nnnn       [int]   ...     // UTF8 string, nnnn is # of chars, else 1111 then int count, then bytes [v"1?"+ only]
        uid     1000 nnnn       ...             // nnnn+1 is # of bytes
                1001 xxxx                       // unused
        array   1010 nnnn       [int]   objref* // nnnn is count, unless '1111', then int count follows
-       ordset  1011 nnnn       [int]   objref* // nnnn is count, unless '1111', then int count follows [v1+ only]
-       set     1100 nnnn       [int]   objref* // nnnn is count, unless '1111', then int count follows [v1+ only]
+       ordset  1011 nnnn       [int]   objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only]
+       set     1100 nnnn       [int]   objref* // nnnn is count, unless '1111', then int count follows [v"1?"+ only]
        dict    1101 nnnn       [int]   keyref* objref* // nnnn is count, unless '1111', then int count follows
                1110 xxxx                       // unused
                1111 xxxx                       // unused
@@ -264,11 +279,6 @@ TRAILER
        element # in offset table which is top level object
        offset table offset
 
-Version 1.5 binary plists do not use object references (uid),
-but instead inline the object serialization itself at that point.
-It also doesn't use an offset table or a trailer.  It does have
-an extended header, and the top-level object follows the header.
-
 */
 
 
@@ -363,7 +373,7 @@ static void _appendString(__CFBinaryPlistWriteBuffer *buf, CFStringRef str) {
     CFIndex ret, count = CFStringGetLength(str);
     CFIndex needed, idx2;
     uint8_t *bytes, buffer[1024];
-    bytes = (count <= 1024) ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count, 0);
+    bytes = (count <= 1024) ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count, 0);
     // presumption, believed to be true, is that ASCII encoding may need
     // less bytes, but will not need greater, than the # of unichars
     ret = CFStringGetBytes(str, CFRangeMake(0, count), kCFStringEncodingASCII, 0, false, bytes, count, &needed);
@@ -381,15 +391,15 @@ static void _appendString(__CFBinaryPlistWriteBuffer *buf, CFStringRef str) {
         if (15 <= count) {
            _appendInt(buf, (uint64_t)count);
         }
-        chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count * sizeof(UniChar), 0);
+        chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(UniChar), 0);
         CFStringGetCharacters(str, CFRangeMake(0, count), chars);
         for (idx2 = 0; idx2 < count; idx2++) {
            chars[idx2] = CFSwapInt16HostToBig(chars[idx2]);
         }
         bufferWrite(buf, (uint8_t *)chars, count * sizeof(UniChar));
-        CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, chars);
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars);
     }
-    if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, bytes);
+    if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, bytes);
 }
 
 CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);
@@ -442,7 +452,6 @@ static void _appendNumber(__CFBinaryPlistWriteBuffer *buf, CFNumberRef num) {
     }
 }
 
-// 0 == objRefSize means version 1.5, else version 0.0 or 0.1
 static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFDictionaryRef objtable, uint32_t objRefSize) {
     uint64_t refnum;
     CFIndex idx2;
@@ -454,9 +463,6 @@ static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFD
        } else if (booltype == type) {
            uint8_t marker = CFBooleanGetValue((CFBooleanRef)obj) ? kCFBinaryPlistMarkerTrue : kCFBinaryPlistMarkerFalse;
            bufferWrite(buf, &marker, 1);
-       } else if (0 == objRefSize && nulltype == type) {
-           uint8_t marker = 0x00;
-           bufferWrite(buf, &marker, 1);
        } else if (datatype == type) {
            CFIndex count = CFDataGetLength((CFDataRef)obj);
            uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerData | (count < 15 ? count : 0xf));
@@ -479,7 +485,7 @@ static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFD
                 _appendInt(buf, (uint64_t)count);
             }
             CFPropertyListRef *list, buffer[512];
-            list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
+            list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
             CFDictionaryGetKeysAndValues((CFDictionaryRef)obj, list, list + count);
             for (idx2 = 0; idx2 < 2 * count; idx2++) {
                CFPropertyListRef value = list[idx2];
@@ -492,12 +498,12 @@ static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFD
                } else {
                    Boolean ret = _appendObject(buf, value, objtable, objRefSize);
                    if (!ret) {
-                       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
                        return false;
                    }
                }
             }
-            if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+            if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
        } else if (arraytype == type) {
            CFIndex count = CFArrayGetCount((CFArrayRef)obj);
            CFPropertyListRef *list, buffer[256];
@@ -506,7 +512,7 @@ static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFD
            if (15 <= count) {
                _appendInt(buf, (uint64_t)count);
            }
-           list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
+           list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
            CFArrayGetValues((CFArrayRef)obj, CFRangeMake(0, count), list);
            for (idx2 = 0; idx2 < count; idx2++) {
                CFPropertyListRef value = list[idx2];
@@ -519,61 +525,13 @@ static Boolean _appendObject(__CFBinaryPlistWriteBuffer *buf, CFTypeRef obj, CFD
                } else {
                    Boolean ret = _appendObject(buf, value, objtable, objRefSize);
                    if (!ret) {
-                       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
                        return false;
                    }
                }
            }
-           if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-       } else if (0 == objRefSize && settype == type) {
-           CFIndex count = CFSetGetCount((CFSetRef)obj);
-           CFPropertyListRef *list, buffer[256];
-           uint8_t marker = (uint8_t)(0xc0 | (count < 15 ? count : 0xf));
-           bufferWrite(buf, &marker, 1);
-           if (15 <= count) {
-               _appendInt(buf, (uint64_t)count);
-           }
-           list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
-           CFSetGetValues((CFSetRef)obj, list);
-           for (idx2 = 0; idx2 < count; idx2++) {
-               CFPropertyListRef value = list[idx2];
-               if (objtable) {
-                   uint32_t swapped = 0;
-                   uint8_t *source = (uint8_t *)&swapped;
-                   refnum = (uint32_t)(uintptr_t)CFDictionaryGetValue(objtable, value);
-                   swapped = CFSwapInt32HostToBig((uint32_t)refnum);
-                   bufferWrite(buf, source + sizeof(swapped) - objRefSize, objRefSize);
-               } else {
-                   Boolean ret = _appendObject(buf, value, objtable, objRefSize);
-                   if (!ret) {
-                       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-                       return false;
-                   }
-               }
-           }
-           if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-       } else if (0 == objRefSize && osettype == type) {
-               // Not actually implemented
-       } else if (0 == objRefSize && uuidtype == type) {
-           uint8_t marker = (uint8_t)(0x0e);
-           bufferWrite(buf, &marker, 1);
-           {
-               CFUUIDBytes uu = CFUUIDGetUUIDBytes((CFUUIDRef)obj);
-               bufferWrite(buf, (const uint8_t *)&uu, 16);
-           }
-       } else if (0 == objRefSize && urltype == type) {
-           CFStringRef string = CFURLGetString((CFURLRef)obj);
-            if (!string) {
-               return false;
-            }
-           CFURLRef base = CFURLGetBaseURL((CFURLRef)obj);
-           uint8_t marker = (uint8_t)(0x00 | (base ? 0xd : 0xc));
-           bufferWrite(buf, &marker, 1);
-           if (base) {
-               _appendObject(buf, base, objtable, objRefSize);
-           }
-           _appendObject(buf, string, objtable, objRefSize);
-       } else if (0 != objRefSize && _CFKeyedArchiverUIDGetTypeID() == type) {
+           if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+       } else if (_CFKeyedArchiverUIDGetTypeID() == type) {
            _appendUID(buf, (CFKeyedArchiverUIDRef)obj);
        } else {
            return false;
@@ -609,20 +567,20 @@ static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CF
     CFDictionaryAddValue(objtable, plist, (const void *)(uintptr_t)refnum);
     if (dicttype == type) {
        CFIndex count = CFDictionaryGetCount((CFDictionaryRef)plist);
-       list = (count <= 128) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
+       list = (count <= 128) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
         CFDictionaryGetKeysAndValues((CFDictionaryRef)plist, list, list + count);
         for (idx = 0; idx < 2 * count; idx++) {
             _flattenPlist(list[idx], objlist, objtable, uniquingset);
         }
-        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
     } else if (arraytype == type) {
        CFIndex count = CFArrayGetCount((CFArrayRef)plist);
-       list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
+       list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
         CFArrayGetValues((CFArrayRef)plist, CFRangeMake(0, count), list);
         for (idx = 0; idx < count; idx++) {
             _flattenPlist(list[idx], objlist, objtable, uniquingset);
         }
-        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
     }
 }
 
@@ -681,10 +639,12 @@ CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t
     CFRelease(uniquingset);
     
     cnt = CFArrayGetCount(objlist);
-    offsets = (uint64_t *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, (CFIndex)(cnt * sizeof(*offsets)), 0);
+    offsets = (uint64_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, (CFIndex)(cnt * sizeof(*offsets)), 0);
 
-    buf = (__CFBinaryPlistWriteBuffer *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, sizeof(__CFBinaryPlistWriteBuffer), 0);
+    buf = (__CFBinaryPlistWriteBuffer *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFBinaryPlistWriteBuffer), 0);
     buf->stream = stream;
+    buf->databytes = NULL;
+    buf->datalen = 0;
     buf->error = NULL;
     buf->streamIsData = (CFGetTypeID(stream) == CFDataGetTypeID());
     buf->written = 0;
@@ -709,8 +669,8 @@ CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t
                // caller is not interested in error, release it here
                CFRelease(buf->error);
            }
-           CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, buf);
-            CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, offsets);
+           CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
+            CFAllocatorDeallocate(kCFAllocatorSystemDefault, offsets);
            return 0;
        }
     }
@@ -727,7 +687,7 @@ CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t
        bufferWrite(buf, source + sizeof(*offsets) - trailer._offsetIntSize, trailer._offsetIntSize);
     }
     length_so_far += cnt * trailer._offsetIntSize;
-    CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, offsets);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, offsets);
 
     bufferWrite(buf, (uint8_t *)&trailer, sizeof(trailer));
     bufferFlush(buf);
@@ -739,10 +699,10 @@ CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t
        } else {
            CFRelease(buf->error);
        }
-        CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, buf);
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
        return 0;
     }
-    CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, buf);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
     return (CFIndex)length_so_far;
 }
 
@@ -761,43 +721,6 @@ CFIndex __CFBinaryPlistWriteToStreamWithOptions(CFPropertyListRef plist, CFTypeR
     return __CFBinaryPlistWrite(plist, stream, estimate, options, NULL);
 }
 
-// Write a version 1.5 plist to the data; extra objects + inlined objects (no references, no uniquing)
-__private_extern__ Boolean __CFBinaryPlistWrite15(CFPropertyListRef plist, CFMutableDataRef data, CFErrorRef *error) {
-    initStatics();
-
-    __CFBinaryPlistWriteBuffer *buf = (__CFBinaryPlistWriteBuffer *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFBinaryPlistWriteBuffer), 0);
-    memset(buf, 0, sizeof(__CFBinaryPlistWriteBuffer));
-    buf->stream = data;
-    buf->error = NULL;
-    buf->streamIsData = 1;
-    buf->written = 0;
-    buf->used = 0;
-
-    bufferWrite(buf, (uint8_t *)"bplist15", 8);                                // header
-    bufferWrite(buf, (uint8_t *)"\023\000\000\000\000\000\000\000\000", 9);    // header (byte length)
-    bufferWrite(buf, (uint8_t *)"\022\000\000\000\000", 5);                    // header (crc)
-
-    Boolean success = _appendObject(buf, plist, NULL, 0);
-    if (!success) {
-        if (error && buf->error) {
-            // caller will release error
-            *error = buf->error;
-        } else if (buf->error) {
-            // caller is not interested in error, release it here
-            CFRelease(buf->error);
-        }
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
-        return false;
-    }
-    bufferFlush(buf);
-
-    uint64_t swapped_len = CFSwapInt64HostToBig(buf->written);
-    CFDataReplaceBytes(data, CFRangeMake(9, 8), (uint8_t *)&swapped_len, (CFIndex)sizeof(swapped_len));
-
-    CFAllocatorDeallocate(kCFAllocatorSystemDefault, buf);
-    return true;
-}
-
 
 #pragma mark -
 #pragma mark Reading
@@ -805,7 +728,7 @@ __private_extern__ Boolean __CFBinaryPlistWrite15(CFPropertyListRef plist, CFMut
 #define FAIL_FALSE     do { return false; } while (0)
 #define FAIL_MAXOFFSET do { return UINT64_MAX; } while (0)
 
-__private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist);
+CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist);
 
 /* Grab a valSize-bytes integer out of the buffer pointed at by data and return it.
  */
@@ -843,7 +766,7 @@ bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen,
     // Leopard will parse "bplist00" or "bplist01"
     // SnowLeopard will parse "bplist0?" where ? is any one character
     if (0 != memcmp("bplist0", databytes, 7)) {
-       return false;
+       FAIL_FALSE;
     }
     memmove(&trail, databytes + datalen - sizeof(trail), sizeof(trail));
     // In Leopard, the unused bytes in the trailer must be 0 or the parse will fail
@@ -899,13 +822,11 @@ bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen,
     if (trail._offsetIntSize < 8 && (1ULL << (8 * trail._offsetIntSize)) <= trail._offsetTableOffset) FAIL_FALSE;
     
     
-    const uint8_t *objectsFirstByte;
-    objectsFirstByte = check_ptr_add(databytes, 8, &err);
+    (void)check_ptr_add(databytes, 8, &err);
     if (CF_NO_ERROR != err) FAIL_FALSE;
     const uint8_t *offsetsFirstByte = check_ptr_add(databytes, trail._offsetTableOffset, &err);
     if (CF_NO_ERROR != err) FAIL_FALSE;
-    const uint8_t *offsetsLastByte;
-    offsetsLastByte = check_ptr_add(offsetsFirstByte, offsetTableSize - 1, &err);
+    (void)check_ptr_add(offsetsFirstByte, offsetTableSize - 1, &err);
     if (CF_NO_ERROR != err) FAIL_FALSE;
 
     const uint8_t *bytesptr = databytes + trail._offsetTableOffset;
@@ -1113,7 +1034,7 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u
            keyInData = NULL;
            if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, NULL /*objects*/, NULL, 0, NULL, &keyInData) || !_plistIsPrimitive(keyInData)) {
                if (keyInData) CFRelease(keyInData);
-               return false;
+               FAIL_FALSE;
            }
            
            match = CFEqual(key, keyInData);            
@@ -1129,27 +1050,27 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u
        ptr += trailer->_objectRefSize;
     }
     
-    return false;
+    FAIL_FALSE;
 }
 
 extern CFDictionaryRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const void * *klist, const void * *vlist, CFIndex numValues);
 extern CFSetRef __CFSetCreateTransfer(CFAllocatorRef allocator, const void * *klist, CFIndex numValues);
 extern CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const void * *klist, CFIndex numValues);
-__private_extern__ void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys);
+CF_PRIVATE void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys);
 
-__private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist) {
+CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist) {
 
     if (objects) {
        *plist = CFDictionaryGetValue(objects, (const void *)(uintptr_t)startOffset);
        if (*plist) {
             // have to assume that '*plist' was previously created with same allocator that is now being passed in
-            if (!_CFAllocatorIsGCRefZero(allocator)) CFRetain(*plist);
+            CFRetain(*plist);
            return true;
        }
     }
 
     // at any one invocation of this function, set should contain the offsets in the "path" down to this object
-    if (set && CFSetContainsValue(set, (const void *)(uintptr_t)startOffset)) return false;
+    if (set && CFSetContainsValue(set, (const void *)(uintptr_t)startOffset)) FAIL_FALSE;
 
     // databytes is trusted to be at least datalen bytes long
     // *trailer contents are trusted, even for overflows -- was checked when the trailer was parsed
@@ -1167,10 +1088,10 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
            *plist = kCFNull;
            return true;
        case kCFBinaryPlistMarkerFalse:
-           *plist = !_CFAllocatorIsGCRefZero(allocator) ? CFRetain(kCFBooleanFalse) : kCFBooleanFalse;
+           *plist = !(0) ? CFRetain(kCFBooleanFalse) : kCFBooleanFalse;
            return true;
        case kCFBinaryPlistMarkerTrue:
-           *plist = !_CFAllocatorIsGCRefZero(allocator) ? CFRetain(kCFBooleanTrue) : kCFBooleanTrue;
+           *plist = !(0) ? CFRetain(kCFBooleanTrue) : kCFBooleanTrue;
            return true;
        }
        FAIL_FALSE;
@@ -1190,7 +1111,6 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        // negative 1, 2, 4-byte integers are always emitted as 8 bytes in format '00'
        // integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
        uint64_t bigint = _getSizedInt(ptr, cnt);
-       ptr += cnt;
        if (8 < cnt) {
            CFSInt128Struct val;
            val.high = 0;
@@ -1311,7 +1231,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
            CFStringRef str = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false);
            *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL;
-            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(str);
+            if (str) CFRelease(str);
        } else {
            *plist = CFStringCreateWithBytes(allocator, ptr, cnt, kCFStringEncodingASCII, false);
        }
@@ -1338,7 +1258,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
        size_t byte_cnt = check_size_t_mul(cnt, sizeof(UniChar), &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       UniChar *chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, 0);
+       UniChar *chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0);
        if (!chars) FAIL_FALSE;
        memmove(chars, ptr, byte_cnt);
        for (CFIndex idx = 0; idx < cnt; idx++) {
@@ -1347,11 +1267,11 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
            CFStringRef str = CFStringCreateWithCharacters(allocator, chars, cnt);
            *plist = str ? CFStringCreateMutableCopy(allocator, 0, str) : NULL;
-            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(str);
+            if (str) CFRelease(str);
        } else {
            *plist = CFStringCreateWithCharacters(allocator, chars, cnt);
        }
-        CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, chars);
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars);
         if (objects && *plist && (mutabilityOption != kCFPropertyListMutableContainersAndLeaves)) {
            CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
        }
@@ -1368,7 +1288,6 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
        // uids are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
        uint64_t bigint = _getSizedInt(ptr, cnt);
-       ptr += cnt;
        if (UINT32_MAX < bigint) FAIL_FALSE;
        *plist = _CFKeyedArchiverUIDCreate(allocator, (uint32_t)bigint);
        // these are always immutable
@@ -1397,7 +1316,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
        byte_cnt = check_size_t_mul(arrayCount, sizeof(CFPropertyListRef), &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       list = (arrayCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
+       list = (arrayCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, __kCFAllocatorGCScannedMemory);
        if (!list) FAIL_FALSE;
        Boolean madeSet = false;
        if (!set && 15 < curDepth) {
@@ -1446,12 +1365,12 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                 if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) {
                     // make immutable
                     *plist = CFArrayCreateCopy(allocator, array);
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(array);
+                    CFRelease(array);
                 } else {
                     *plist = array;
                 }
             } else if (array) {
-                if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(array);
+                CFRelease(array);
             }
         } else {            
             for (CFIndex idx = 0; idx < arrayCount; idx++) {            
@@ -1459,9 +1378,9 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                 off = _getOffsetOfRefAt(databytes, ptr, trailer);
                 if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, &pl)) {
                     while (idx--) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        CFRelease(list[idx]);
                     }      
-                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
                     FAIL_FALSE;
                 }
                 __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
@@ -1472,7 +1391,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                     *plist = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
                     CFArrayReplaceValues((CFMutableArrayRef)*plist, CFRangeMake(0, 0), list, arrayCount);
                     for (CFIndex idx = 0; idx < arrayCount; idx++) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        CFRelease(list[idx]);
                     }
                 } else {
                     if (!kCFUseCollectableAllocator) {
@@ -1480,7 +1399,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                     } else {
                         *plist = CFArrayCreate(allocator, list, arrayCount, &kCFTypeArrayCallBacks);
                         for (CFIndex idx = 0; idx < arrayCount; idx++) {
-                            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                            CFRelease(list[idx]);
                         }
                     }
                 }
@@ -1491,7 +1410,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                         CFSetAddValue((CFMutableSetRef)*plist, list[idx]);
                     }
                     for (CFIndex idx = 0; idx < arrayCount; idx++) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        CFRelease(list[idx]);
                     }
                 } else {
                     if (!kCFUseCollectableAllocator) {
@@ -1499,7 +1418,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                     } else {
                         *plist = CFSetCreate(allocator, list, arrayCount, &kCFTypeSetCallBacks);
                         for (CFIndex idx = 0; idx < arrayCount; idx++) {
-                            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                            CFRelease(list[idx]);
                         }
                     }
                 }
@@ -1513,7 +1432,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
            CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
        }
-       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
        return (*plist) ? true : false;
        }
     case kCFBinaryPlistMarkerDict: {
@@ -1537,7 +1456,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
        byte_cnt = check_size_t_mul(dictionaryCount, sizeof(CFPropertyListRef), &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       list = (dictionaryCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
+       list = (dictionaryCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, __kCFAllocatorGCScannedMemory);
        if (!list) FAIL_FALSE;
        Boolean madeSet = false;
        if (!set && 15 < curDepth) {
@@ -1581,23 +1500,23 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                 if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) {
                     // make immutable
                     *plist = CFDictionaryCreateCopy(allocator, dict);
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(dict);
+                    CFRelease(dict);
                 } else {
                     *plist = dict;
                 }
             } else if (dict) {
-                if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(dict);
+                CFRelease(dict);
             }
         } else {
             for (CFIndex idx = 0; idx < dictionaryCount; idx++) {
                 CFPropertyListRef pl = NULL;
                 off = _getOffsetOfRefAt(databytes, ptr, trailer);
                 if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, NULL, &pl) || (idx < dictionaryCount / 2 && !_plistIsPrimitive(pl))) {
-                    if (pl && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(pl);
+                    if (pl && !(0)) CFRelease(pl);
                     while (idx--) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        CFRelease(list[idx]);
                     }
-                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
                     FAIL_FALSE;
                 }
                 __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
@@ -1609,7 +1528,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                     CFDictionaryAddValue((CFMutableDictionaryRef)*plist, list[idx], list[idx + dictionaryCount / 2]);
                 }
                 for (CFIndex idx = 0; idx < dictionaryCount; idx++) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                    CFRelease(list[idx]);
                 }
             } else {
                 if (!kCFUseCollectableAllocator) {
@@ -1617,7 +1536,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
                 } else {
                     *plist = CFDictionaryCreate(allocator, list, list + dictionaryCount / 2, dictionaryCount / 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
                     for (CFIndex idx = 0; idx < dictionaryCount; idx++) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        CFRelease(list[idx]);
                     }
                 }
             }
@@ -1630,7 +1549,7 @@ __private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *datab
        if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
            CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
        }
-       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
        return (*plist) ? true : false;
        }
     }
@@ -1642,7 +1561,7 @@ bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uin
     return __CFBinaryPlistCreateObjectFiltered(databytes, datalen, startOffset, trailer, allocator, mutabilityOption, objects, NULL, 0, NULL, plist);
 }
 
-__private_extern__ bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString) {
+CF_PRIVATE bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString) {
     uint8_t marker;    
     CFBinaryPlistTrailer trailer;
     uint64_t offset;
@@ -1656,285 +1575,33 @@ __private_extern__ bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFData
        // be malformed and contain hash-equal keys for the same dictionary (for example)
        // and the later key will cause the previous one to be released when we set the second
        // in the dictionary.
-       CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+       CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
        _CFDictionarySetCapacity(objects, trailer._numObjects);
        CFPropertyListRef pl = NULL;
         bool result = true;
         if (__CFBinaryPlistCreateObjectFiltered(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl)) {
            if (plist) *plist = pl;
+#if 0
+// code to check the 1.5 version code against any binary plist successfully parsed above
+extern size_t __CFBinaryPlistWrite15(CFPropertyListRef plist, CFMutableDataRef data, CFErrorRef *error);
+extern CFPropertyListRef __CFBinaryPlistCreate15(const uint8_t *databytes, uint64_t datalen, CFErrorRef *error);
+
+CFMutableDataRef mdata = CFDataCreateMutable(0, 0);
+size_t s = __CFBinaryPlistWrite15(pl, mdata, NULL);
+//double ratio = (double)s / (double)datalen;
+//if (ratio < 0.75 || ratio > 4.0) CFLog(4, CFSTR("@@@ note: Binary plist of %ld bytes is %ld bytes (%f) in version 1.5"), datalen, s, ratio);
+if (s != CFDataGetLength(mdata)) CFLog(3, CFSTR("### error: returned length not equal to data length (%ld != %ld)"), s, CFDataGetLength(mdata));
+CFPropertyListRef pl2 = __CFBinaryPlistCreate15((const uint8_t *)CFDataGetBytePtr(mdata), CFDataGetLength(mdata), NULL);
+if (!CFEqual(pl, pl2)) CFLog(3, CFSTR("*** error: plists before and after are not equal\n--------\n%@\n--------\n%@\n--------"), pl, pl2);
+#endif
         } else {
            if (plist) *plist = NULL;
             if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("binary data is corrupt"));
             result = false;
        }
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(objects);
+        CFRelease(objects);
         return result;
     }
-    return false;
-}
-
-
-static CFPropertyListRef __CFBinaryPlistCreateObject15(const uint8_t *databytes, uint64_t datalen, const uint8_t **ptr) {
-    const uint8_t *objectsRangeStart = databytes + 22, *objectsRangeEnd = databytes + datalen - 1;
-    if (*ptr < objectsRangeStart || objectsRangeEnd < *ptr) return NULL;
-    uint8_t marker = **ptr;
-    int32_t err = CF_NO_ERROR;
-    *ptr = check_ptr_add(*ptr, 1, &err);
-    if (CF_NO_ERROR != err) return NULL;
-    switch (marker & 0xf0) {
-    case 0x0:
-       switch (marker) {
-       case kCFBinaryPlistMarkerNull:
-           return kCFNull;
-       case kCFBinaryPlistMarkerFalse:
-           return kCFBooleanFalse;
-       case kCFBinaryPlistMarkerTrue:
-           return kCFBooleanTrue;
-       case 0x0c: {
-            CFStringRef string = (CFStringRef)__CFBinaryPlistCreateObject15(databytes, datalen, ptr);
-            if (!string) {
-                return NULL;
-            }
-            CFURLRef result = CFURLCreateWithString(kCFAllocatorSystemDefault, string, NULL);
-            CFRelease(string);
-           return result;
-       }
-       case 0x0d: {
-            CFURLRef base = (CFURLRef)__CFBinaryPlistCreateObject15(databytes, datalen, ptr);
-            if (!base) return NULL;
-            CFStringRef string = (CFStringRef)__CFBinaryPlistCreateObject15(databytes, datalen, ptr);
-            if (!string) {
-                CFRelease(base);
-                return NULL;
-            }
-            CFURLRef result = CFURLCreateWithString(kCFAllocatorSystemDefault, string, base);
-            CFRelease(base);
-            CFRelease(string);
-           return result;
-       }
-       case 0x0e: {
-           int32_t err = CF_NO_ERROR;
-           const uint8_t *extent = check_ptr_add(*ptr, 16, &err) - 1;
-           if (CF_NO_ERROR != err) return NULL;
-           if (objectsRangeEnd < extent) return NULL;
-           CFUUIDBytes uuid;
-           memmove(&uuid, *ptr, 16);
-           *ptr = extent + 1;
-           return CFUUIDCreateFromUUIDBytes(kCFAllocatorSystemDefault, uuid);
-       }
-       case 0x0f:
-           break;
-       }
-       return NULL;
-    case kCFBinaryPlistMarkerInt: {
-       int32_t err = CF_NO_ERROR;
-       uint64_t cnt = 1 << (marker & 0x0f);
-       const uint8_t *extent = check_ptr_add(*ptr, cnt, &err) - 1;
-       if (CF_NO_ERROR != err) return NULL;
-       if (objectsRangeEnd < extent) return NULL;
-       if (16 < cnt) return NULL;
-       // in format version '15', 1, 2, and 4-byte integers have to be interpreted as unsigned,
-       // whereas 8-byte integers are signed (and 16-byte when available)
-       // negative 1, 2, 4-byte integers are always emitted as 8 bytes in format '15'
-       // integers are not required to be in the most compact possible representation, but only the last 64 bits are significant currently
-       uint64_t bigint = _getSizedInt(*ptr, cnt);
-       *ptr = extent + 1;
-        CFPropertyListRef plist = NULL;
-       if (8 < cnt) {
-           CFSInt128Struct val;
-           val.high = 0;
-           val.low = bigint;
-           plist = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt128Type, &val);
-       } else {
-           plist = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt64Type, &bigint);
-       }
-       return plist;
-        }
-    case kCFBinaryPlistMarkerReal:
-       switch (marker & 0x0f) {
-       case 2: {
-           int32_t err = CF_NO_ERROR;
-           const uint8_t *extent = check_ptr_add(*ptr, 4, &err) - 1;
-           if (CF_NO_ERROR != err) return NULL;
-           if (objectsRangeEnd < extent) return NULL;
-           CFSwappedFloat32 swapped32;
-           memmove(&swapped32, *ptr, 4);
-           *ptr = extent + 1;
-           float f = CFConvertFloat32SwappedToHost(swapped32);
-           CFPropertyListRef plist = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberFloat32Type, &f);
-           return plist;
-       }
-       case 3: {
-           int32_t err = CF_NO_ERROR;
-           const uint8_t *extent = check_ptr_add(*ptr, 8, &err) - 1;
-           if (CF_NO_ERROR != err) return NULL;
-           if (objectsRangeEnd < extent) return NULL;
-           CFSwappedFloat64 swapped64;
-           memmove(&swapped64, *ptr, 8);
-           *ptr = extent + 1;
-           double d = CFConvertFloat64SwappedToHost(swapped64);
-           CFPropertyListRef plist = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberFloat64Type, &d);
-           return plist;
-       }
-       }
-       return NULL;
-    case kCFBinaryPlistMarkerDate & 0xf0:
-       switch (marker) {
-       case kCFBinaryPlistMarkerDate: {
-           int32_t err = CF_NO_ERROR;
-           const uint8_t *extent = check_ptr_add(*ptr, 8, &err) - 1;
-           if (CF_NO_ERROR != err) return NULL;
-           if (objectsRangeEnd < extent) return NULL;
-           CFSwappedFloat64 swapped64;
-           memmove(&swapped64, *ptr, 8);
-           *ptr = extent + 1;
-           double d = CFConvertFloat64SwappedToHost(swapped64);
-           CFPropertyListRef plist = CFDateCreate(kCFAllocatorSystemDefault, d);
-           return plist;
-       }
-       }
-       return NULL;
-    case kCFBinaryPlistMarkerData: {
-       int32_t err = CF_NO_ERROR;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
-           uint64_t bigint = 0;
-           if (!_readInt(*ptr, objectsRangeEnd, &bigint, ptr)) return NULL;
-           if (LONG_MAX < bigint) return NULL;
-           cnt = (CFIndex)bigint;
-       }
-       const uint8_t *extent = check_ptr_add(*ptr, cnt, &err) - 1;
-       if (CF_NO_ERROR != err) return NULL;
-       if (objectsRangeEnd < extent) return NULL;
-       CFPropertyListRef plist = CFDataCreate(kCFAllocatorSystemDefault, *ptr, cnt);
-       *ptr = extent + 1;
-       return plist;
-       }
-    case kCFBinaryPlistMarkerASCIIString: {
-       int32_t err = CF_NO_ERROR;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
-           uint64_t bigint = 0;
-           if (!_readInt(*ptr, objectsRangeEnd, &bigint, ptr)) return NULL;
-           if (LONG_MAX < bigint) return NULL;
-           cnt = (CFIndex)bigint;
-       }
-       const uint8_t *extent = check_ptr_add(*ptr, cnt, &err) - 1;
-       if (CF_NO_ERROR != err) return NULL;
-       if (objectsRangeEnd < extent) return NULL;
-       CFPropertyListRef plist = CFStringCreateWithBytes(kCFAllocatorSystemDefault, *ptr, cnt, kCFStringEncodingASCII, false);
-       *ptr = extent + 1;
-       return plist;
-       }
-    case kCFBinaryPlistMarkerUnicode16String: {
-       int32_t err = CF_NO_ERROR;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
-           uint64_t bigint = 0;
-           if (!_readInt(*ptr, objectsRangeEnd, &bigint, ptr)) return NULL;
-           if (LONG_MAX < bigint) return NULL;
-           cnt = (CFIndex)bigint;
-       }
-       const uint8_t *extent = check_ptr_add(*ptr, cnt, &err) - 1;
-       extent = check_ptr_add(extent, cnt, &err);      // 2 bytes per character
-       if (CF_NO_ERROR != err) return NULL;
-       if (objectsRangeEnd < extent) return NULL;
-       size_t byte_cnt = check_size_t_mul(cnt, sizeof(UniChar), &err);
-       if (CF_NO_ERROR != err) return NULL;
-       UniChar *chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0);
-       if (!chars) return NULL;
-       memmove(chars, *ptr, byte_cnt);
-       for (CFIndex idx = 0; idx < cnt; idx++) {
-           chars[idx] = CFSwapInt16BigToHost(chars[idx]);
-       }
-       CFPropertyListRef plist = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, chars, cnt);
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, chars);
-       *ptr = extent + 1;
-       return plist;
-       }
-    case kCFBinaryPlistMarkerArray:
-    case 0xb0: // ordset
-    case kCFBinaryPlistMarkerSet:
-    case kCFBinaryPlistMarkerDict: {
-       int32_t err = CF_NO_ERROR;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
-           uint64_t bigint = 0;
-           if (!_readInt(*ptr, objectsRangeEnd, &bigint, ptr)) return NULL;
-           if (LONG_MAX < bigint) return NULL;
-           cnt = (CFIndex)bigint;
-       }
-       if ((marker & 0xf0) == kCFBinaryPlistMarkerDict) {
-           cnt = check_size_t_mul(cnt, 2, &err);
-           if (CF_NO_ERROR != err) return NULL;
-       }
-       size_t byte_cnt = check_size_t_mul(cnt, sizeof(CFPropertyListRef), &err); // check now for a later overflow
-       if (CF_NO_ERROR != err) return NULL;
-       CFPropertyListRef *list, buffer[256];
-       list = (cnt <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, byte_cnt, 0);
-       if (!list) return NULL;
-
-       CFMutableArrayRef tmparray = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-       for (CFIndex idx = 0; idx < cnt; idx++) {
-           CFPropertyListRef pl = __CFBinaryPlistCreateObject15(databytes, datalen, ptr);
-           if (!pl) {
-               CFRelease(tmparray);
-               return NULL;
-           }
-           if ((marker & 0xf0) == kCFBinaryPlistMarkerDict) {
-               if (idx < cnt / 2 && !_plistIsPrimitive(pl)) {
-                   CFRelease(pl);
-                   CFRelease(tmparray);
-                   return NULL;
-               }
-           }
-           CFArrayAppendValue(tmparray, pl);
-//         CFRelease(pl); // don't release pl here, we're going to transfer the retain to the ultimate collection owner
-       }
-       CFArrayGetValues(tmparray, CFRangeMake(0, cnt), list);
-       CFPropertyListRef plist = NULL;
-       if ((marker & 0xf0) == kCFBinaryPlistMarkerArray) {
-           plist = __CFArrayCreateTransfer(kCFAllocatorSystemDefault, list, cnt);
-       } else if ((marker & 0xf0) == 0xb0) {
-           plist = NULL; // Not actually implemented
-           // leaks contents of tmparray, but this path shouldn't be exercised anyway
-       } else if ((marker & 0xf0) == kCFBinaryPlistMarkerSet) {
-           plist = __CFSetCreateTransfer(kCFAllocatorSystemDefault, list, cnt);
-       } else {
-           plist = __CFDictionaryCreateTransfer(kCFAllocatorSystemDefault, list, list + cnt / 2, cnt / 2);
-       }
-       CFRelease(tmparray);
-       if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
-       return plist;
-       }
-    default:
-       break;
-    }
-    return NULL;
-}
-
-// *error is currently never set
-__private_extern__ CFPropertyListRef __CFBinaryPlistCreate15(CFDataRef data, CFErrorRef *error) {
-    initStatics();
-    const uint8_t *databytes = CFDataGetBytePtr(data);
-    uint64_t datalen = CFDataGetLength(data);
-    if (23 <= datalen) { // header is 22 bytes, plus 1 byte minimum for smallest object
-        const uint8_t *ptr = databytes;
-        if (0 != memcmp((uint8_t *)"bplist15", ptr, 8)) return NULL;
-        ptr += 8;
-        if (*ptr != (kCFBinaryPlistMarkerInt | 3)) return NULL;
-        ptr += 1;
-        uint64_t swapped_len;
-        memmove(&swapped_len, ptr, 8);
-        uint64_t bytelen = CFSwapInt64BigToHost(swapped_len);
-        if (bytelen != datalen) return NULL;
-        ptr += 8;
-        if (*ptr != (kCFBinaryPlistMarkerInt | 2)) return NULL;
-        ptr += 5; // skip crc
-        CFPropertyListRef pl = __CFBinaryPlistCreateObject15(databytes, datalen, &ptr);
-        // ptr should equal (databytes+datalen) if there is no junk at the end of top-level object
-        return pl;
-    }
-    return NULL;
+    FAIL_FALSE;
 }
 
index 6043b9f1dd48bb30da429925547712fa64e491b0..983369ea6065a4c6d8ca6241c1a8a4bb980d1ff9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBitVector.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -176,24 +176,24 @@ static CFStringRef __CFBitVectorCopyDescription(CFTypeRef cf) {
     cnt = __CFBitVectorCount(bv);
     buckets = bv->_buckets;
     result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
-    CFStringAppendFormat(result, NULL, CFSTR("<CFBitVector %p [%p]>{count = %u, capacity = %u, objects = (\n"), cf, CFGetAllocator(bv), cnt, __CFBitVectorCapacity(bv));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFBitVector %p [%p]>{count = %lu, capacity = %lu, objects = (\n"), cf, CFGetAllocator(bv), (unsigned long)cnt, __CFBitVectorCapacity(bv));
     for (idx = 0; idx < (cnt / 64); idx++) {   /* Print groups of 64 */
        CFIndex idx2;
-       CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
+       CFStringAppendFormat(result, NULL, CFSTR("\t%lu : "), (unsigned long)(idx * 64));
        for (idx2 = 0; idx2 < 64; idx2 += 4) {
            CFIndex bucketIdx = (idx << 6) + idx2;
-           CFStringAppendFormat(result, NULL, CFSTR("%d%d%d%d"),
-               __CFBitVectorBit(buckets, bucketIdx + 0),
-               __CFBitVectorBit(buckets, bucketIdx + 1),
-               __CFBitVectorBit(buckets, bucketIdx + 2),
-               __CFBitVectorBit(buckets, bucketIdx + 3));
+           CFStringAppendFormat(result, NULL, CFSTR("%u%u%u%u"),
+               (unsigned int)__CFBitVectorBit(buckets, bucketIdx + 0),
+               (unsigned int)__CFBitVectorBit(buckets, bucketIdx + 1),
+               (unsigned int)__CFBitVectorBit(buckets, bucketIdx + 2),
+               (unsigned int)__CFBitVectorBit(buckets, bucketIdx + 3));
        }
        CFStringAppend(result, CFSTR("\n"));
     }
     if (idx * 64 < cnt) {
-       CFStringAppendFormat(result, NULL, CFSTR("\t%u : "), (idx * 64));
+       CFStringAppendFormat(result, NULL, CFSTR("\t%lu : "), (unsigned long)(idx * 64));
        for (idx = (idx * 64); idx < cnt; idx++) {      /* Print remainder */
-           CFStringAppendFormat(result, NULL, CFSTR("%d"), __CFBitVectorBit(buckets, idx));
+           CFStringAppendFormat(result, NULL, CFSTR("%u"), (unsigned int)__CFBitVectorBit(buckets, idx));
        }
     }
     CFStringAppend(result, CFSTR("\n)}"));
@@ -225,7 +225,7 @@ static const CFRuntimeClass __CFBitVectorClass = {
     __CFBitVectorCopyDescription
 };
 
-__private_extern__ void __CFBitVectorInitialize(void) {
+CF_PRIVATE void __CFBitVectorInitialize(void) {
     __kCFBitVectorTypeID = _CFRuntimeRegisterClass(&__CFBitVectorClass);
 }
 
index 4b44927891849741121f6f1f4766162bc9dc2d36..c8b86148fe0723a3b17364d1c9b8cc778f1b13b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBitVector.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBITVECTOR__)
index 279f0634116e0e15bf1a5aa1e5d984975e2c02ff..cc2bdb0dcad16e1b24a53125b6c18409df2cc5ed 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBuiltinConverters.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -106,7 +106,7 @@ static bool __CFFromASCII(uint32_t flags, uint8_t byte, UniChar *character) {
 }
 
 
-__private_extern__ const CFStringEncodingConverter __CFConverterASCII = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterASCII = {
     __CFToASCII, __CFFromASCII, 1, 1, kCFStringEncodingConverterCheapEightBit,
     NULL, NULL, NULL, NULL, NULL, NULL,
 };
@@ -142,7 +142,7 @@ static CFIndex __CFToISOLatin1Precompose(uint32_t flags, const UniChar *characte
     }
 }
 
-__private_extern__ const CFStringEncodingConverter __CFConverterISOLatin1 = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterISOLatin1 = {
     __CFToISOLatin1, __CFFromISOLatin1, 1, 1, kCFStringEncodingConverterCheapEightBit,
     NULL, NULL, NULL, NULL, __CFToISOLatin1Precompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
 };
@@ -439,7 +439,7 @@ static CFIndex __CFToMacRomanPrecompose(uint32_t flags, const UniChar *character
     }
 }
 
-__private_extern__ const CFStringEncodingConverter __CFConverterMacRoman = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterMacRoman = {
     __CFToMacRoman, __CFFromMacRoman, 1, 1, kCFStringEncodingConverterCheapEightBit,
     NULL, NULL, NULL, NULL, __CFToMacRomanPrecompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
 };
@@ -537,7 +537,7 @@ static CFIndex __CFToWinLatin1Precompose(uint32_t flags, const UniChar *characte
     }
 }
 
-__private_extern__ const CFStringEncodingConverter __CFConverterWinLatin1 = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterWinLatin1 = {
     __CFToWinLatin1, __CFFromWinLatin1, 1, 1, kCFStringEncodingConverterCheapEightBit,
     NULL, NULL, NULL, NULL, __CFToWinLatin1Precompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
 };
@@ -837,7 +837,7 @@ static CFIndex __CFToNextStepLatinPrecompose(uint32_t flags, const UniChar *char
     }
 }
 
-__private_extern__ const CFStringEncodingConverter __CFConverterNextStepLatin = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterNextStepLatin = {
     __CFToNextStepLatin, __CFFromNextStepLatin, 1, 1, kCFStringEncodingConverterCheapEightBit,
     NULL, NULL, NULL, NULL, __CFToNextStepLatinPrecompose, CFStringEncodingIsValidCombiningCharacterForLatin1,
 };
@@ -1191,7 +1191,7 @@ static CFIndex __CFFromUTF8Len(uint32_t flags, const uint8_t *source, CFIndex nu
     return theUsedCharLen;
 }
 
-__private_extern__ const CFStringEncodingConverter __CFConverterUTF8 = {
+CF_PRIVATE const CFStringEncodingConverter __CFConverterUTF8 = {
     __CFToUTF8, __CFFromUTF8, 3, 2, kCFStringEncodingConverterStandard,
     __CFToUTF8Len, __CFFromUTF8Len, NULL, NULL, NULL, NULL,
 };
index 254fd923e16eca2128e36db5378ff0464a227172..a5b64b5f4af92b54cb8c1515abbefd4a7c64afdd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*      CFBundle.c
-        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
@@ -84,6 +84,7 @@
 #define stat(x,y) _NS_stat(x,y)
 #endif
 
+
 #if DEPLOYMENT_TARGET_WINDOWS
 #define statinfo _stat
 
@@ -97,11 +98,6 @@ static inline BOOL isspace(char c) {
 #define statinfo stat
 #endif
 
-__private_extern__ void _processInfoDictionary(CFMutableDictionaryRef dict, CFStringRef platformSuffix, CFStringRef productSuffix);
-CF_EXPORT CFStringRef _CFGetProductName(void);
-CF_EXPORT CFStringRef _CFGetPlatformName(void);
-CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void);
-
 static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean alreadyLocked);
 
 #define LOG_BUNDLE_LOAD 0
@@ -171,63 +167,13 @@ CONST_STRING_DECL(_kCFBundleResourcesFileMappedKey, "CSResourcesFileMapped")
 CONST_STRING_DECL(_kCFBundleCFMLoadAsBundleKey, "CFBundleCFMLoadAsBundle")
 
 // Keys used by NSBundle for loaded Info plists.
-CONST_STRING_DECL(_kCFBundleInitialPathKey, "NSBundleInitialPath")
-CONST_STRING_DECL(_kCFBundleResolvedPathKey, "NSBundleResolvedPath")
 CONST_STRING_DECL(_kCFBundlePrincipalClassKey, "NSPrincipalClass")
 
 static char __CFBundleMainID__[1026] = {0};
-__private_extern__ char *__CFBundleMainID = __CFBundleMainID__;
+CF_PRIVATE char *__CFBundleMainID = __CFBundleMainID__;
 
 static CFTypeID __kCFBundleTypeID = _kCFRuntimeNotATypeID;
 
-struct __CFBundle {
-    CFRuntimeBase _base;
-
-    CFURLRef _url;
-    CFDateRef _modDate;
-
-    __strong CFDictionaryRef _infoDict;      // the ref stored in here must always be allocated with kCFAllocatorSystemDefaultGCRefZero
-    __strong CFDictionaryRef _localInfoDict; // the ref stored in here must always be allocated with kCFAllocatorSystemDefaultGCRefZero
-    CFArrayRef _searchLanguages;
-
-    __CFPBinaryType _binaryType;
-    Boolean _isLoaded;
-    uint8_t _version;
-    Boolean _sharesStringsFiles;
-    char _padding[1];
-
-    /* CFM goop */
-    void *_connectionCookie;
-
-    /* DYLD goop */
-    const void *_imageCookie;
-    const void *_moduleCookie;
-
-    /* dlfcn goop */
-    void *_handleCookie;
-    
-    /* CFM<->DYLD glue */
-    CFMutableDictionaryRef _glueDict;
-    
-    /* Resource fork goop */
-    _CFResourceData _resourceData;
-
-    _CFPlugInData _plugInData;
-
-    pthread_mutex_t _bundleLoadingLock;
-
-    // ZFH
-    /* resouce fast lookup*/
-    CFSpinLock_t _queryLock;
-    CFMutableDictionaryRef _queryTable;
-    CFStringRef _bundleBasePath;
-    
-#if defined(BINARY_SUPPORT_DLL)
-    HMODULE _hModule;
-#endif /* BINARY_SUPPORT_DLL */
-
-};
-
 static pthread_mutex_t CFBundleGlobalDataLock = PTHREAD_MUTEX_INITIALIZER;
 
 static CFMutableDictionaryRef _bundlesByIdentifier = NULL;
@@ -243,18 +189,16 @@ static Boolean _scheduledBundlesAreUnloading = false;
 
 static Boolean _initedMainBundle = false;
 static CFBundleRef _mainBundle = NULL;
-static CFStringRef _defaultLocalization = NULL;
 
 // Forward declares functions.
 static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing);
-static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict);
 static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle);
 static void _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(CFStringRef hint);
 static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void);
 static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath);
 static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths);
 #if defined(BINARY_SUPPORT_DYLD)
-static CFMutableDictionaryRef _CFBundleGrokInfoDictFromMainExecutable(void);
+static CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable(void);
 static Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags);
 static CFStringRef _CFBundleDYLDCopyLoadedImagePathForPointer(void *p);
 #if !defined(BINARY_SUPPORT_DLFCN)
@@ -845,8 +789,8 @@ static void _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(CFStringRef
         }
 #if defined(BINARY_SUPPORT_DYLD)
         if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) {
-            if (_mainBundle->_infoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(_mainBundle->_infoDict);
-            _mainBundle->_infoDict = (CFDictionaryRef)_CFBundleGrokInfoDictFromMainExecutable();
+            if (_mainBundle->_infoDict && !(0)) CFRelease(_mainBundle->_infoDict);
+            _mainBundle->_infoDict = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable();
         }
 #endif /* BINARY_SUPPORT_DYLD */
     } else {
@@ -855,18 +799,20 @@ static void _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(CFStringRef
             // if dyld and not main executable for bundle, prefer info dictionary from executable
             CFStringRef executableName = _CFBundleCopyExecutableName(_mainBundle, NULL, NULL);
             if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) {
-                CFDictionaryRef infoDictFromExecutable = (CFDictionaryRef)_CFBundleGrokInfoDictFromMainExecutable();
+                CFDictionaryRef infoDictFromExecutable = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable();
                 if (infoDictFromExecutable && CFDictionaryGetCount(infoDictFromExecutable) > 0) {
-                    if (_mainBundle->_infoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(_mainBundle->_infoDict);
+                    if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict);
                     _mainBundle->_infoDict = infoDictFromExecutable;
+                } else if (infoDictFromExecutable) {
+                    CFRelease(infoDictFromExecutable);
                 }
             }
             if (executableName) CFRelease(executableName);
         }
 #endif /* BINARY_SUPPORT_DYLD */
     }
-    if (!_mainBundle->_infoDict) _mainBundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    if (!CFDictionaryGetValue(_mainBundle->_infoDict, _kCFBundleExecutablePathKey)) CFDictionarySetValue((CFMutableDictionaryRef)(_mainBundle->_infoDict), _kCFBundleExecutablePathKey, executablePath);
+    if (!_mainBundle->_infoDict) _mainBundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    if (!_mainBundle->_executablePath && executablePath) _mainBundle->_executablePath = (CFStringRef)CFRetain(executablePath);
     CFStringRef bundleID = (CFStringRef)CFDictionaryGetValue(_mainBundle->_infoDict, kCFBundleIdentifierKey);
     if (bundleID) {
         if (!CFStringGetCString(bundleID, __CFBundleMainID__, sizeof(__CFBundleMainID__) - 2, kCFStringEncodingUTF8)) {
@@ -879,12 +825,19 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean
     CFDictionaryRef oldInfoDict = bundle->_infoDict;
     CFTypeRef val;
     
-    _CFBundleFlushCachesForURL(bundle->_url);
     bundle->_infoDict = NULL;
     if (bundle->_localInfoDict) {
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(bundle->_localInfoDict);
+        CFRelease(bundle->_localInfoDict);
         bundle->_localInfoDict = NULL;
     }
+    if (bundle->_developmentRegion) {
+        CFRelease(bundle->_developmentRegion);
+        bundle->_developmentRegion = NULL;
+    }
+    if (bundle->_executablePath) {
+        CFRelease(bundle->_executablePath);
+        bundle->_executablePath = NULL;
+    }
     if (bundle->_searchLanguages) {
         CFRelease(bundle->_searchLanguages);
         bundle->_searchLanguages = NULL;
@@ -894,7 +847,7 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean
         bundle->_resourceData._stringTableCache = NULL;
     }
     if (bundle == _mainBundle) {
-        CFStringRef executablePath = oldInfoDict ? (CFStringRef)CFDictionaryGetValue(oldInfoDict, _kCFBundleExecutablePathKey) : NULL;
+        CFStringRef executablePath = bundle->_executablePath;
         if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
         _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(executablePath);
         if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
@@ -902,15 +855,16 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean
         CFBundleGetInfoDictionary(bundle);
     }
     if (oldInfoDict) {
-        if (!bundle->_infoDict) bundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-        val = CFDictionaryGetValue(oldInfoDict, _kCFBundleInitialPathKey);
-        if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundleInitialPathKey, val);
-        val = CFDictionaryGetValue(oldInfoDict, _kCFBundleResolvedPathKey);
-        if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundleResolvedPathKey, val);
+        if (!bundle->_infoDict) bundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
         val = CFDictionaryGetValue(oldInfoDict, _kCFBundlePrincipalClassKey);
         if (val) CFDictionarySetValue((CFMutableDictionaryRef)bundle->_infoDict, _kCFBundlePrincipalClassKey, val);
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(oldInfoDict);
+        CFRelease(oldInfoDict);
     }
+    __CFSpinLock(&bundle->_queryLock);
+    if (bundle->_queryTable) {
+        CFDictionaryRemoveAllValues(bundle->_queryTable);
+    }
+    __CFSpinUnlock(&bundle->_queryLock);
 }
 
 CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle) {
@@ -1082,23 +1036,26 @@ static void __CFBundleDeallocate(CFTypeRef cf) {
     CFBundleUnloadExecutable(bundle);
     _CFBundleDeallocatePlugIn(bundle);    
     if (bundleURL) {
-        _CFBundleFlushCachesForURL(bundleURL);
         CFRelease(bundleURL);
     }
-    if (bundle->_infoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(bundle->_infoDict);
+    if (bundle->_infoDict && !(0)) CFRelease(bundle->_infoDict);
     if (bundle->_modDate) CFRelease(bundle->_modDate);
-    if (bundle->_localInfoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(bundle->_localInfoDict);
+    if (bundle->_localInfoDict && !(0)) CFRelease(bundle->_localInfoDict);
     if (bundle->_searchLanguages) CFRelease(bundle->_searchLanguages);
+    if (bundle->_executablePath) CFRelease(bundle->_executablePath);
+    if (bundle->_developmentRegion) CFRelease(bundle->_developmentRegion);
     if (bundle->_glueDict) {
         CFDictionaryApplyFunction(bundle->_glueDict, _CFBundleDeallocateGlue, (void *)CFGetAllocator(bundle));
         CFRelease(bundle->_glueDict);
     }
     if (bundle->_resourceData._stringTableCache) CFRelease(bundle->_resourceData._stringTableCache);
     
-    // ZFH
     if (bundle->_bundleBasePath) CFRelease(bundle->_bundleBasePath);
     if (bundle->_queryTable) CFRelease(bundle->_queryTable);
     
+    if (bundle->_localizations) CFRelease(bundle->_localizations);
+    if (bundle->_resourceDirectoryContents) CFRelease(bundle->_resourceDirectoryContents);
+    
     pthread_mutex_destroy(&(bundle->_bundleLoadingLock));
 }
 
@@ -1115,9 +1072,9 @@ static const CFRuntimeClass __CFBundleClass = {
 };
 
 // From CFBundle_Resources.c
-__private_extern__ void _CFBundleResourcesInitialize();
+CF_PRIVATE void _CFBundleResourcesInitialize();
 
-__private_extern__ void __CFBundleInitialize(void) {
+CF_PRIVATE void __CFBundleInitialize(void) {
     __kCFBundleTypeID = _CFRuntimeRegisterClass(&__CFBundleClass);
     _CFBundleResourcesInitialize();
 }
@@ -1142,7 +1099,6 @@ CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL) {
 }
 
 static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing) {
-    allocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
     CFBundleRef bundle = NULL;
     char buff[CFMaxPathSize];
     CFDateRef modDate = NULL; // do not actually fetch the modDate, since that can cause something like 7609956, unless absolutely found to be necessary in the future
@@ -1161,8 +1117,8 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL,
         return bundle;
     }
     
-    if (!_CFBundleURLLooksLikeBundleVersion(newURL, &localVersion)) {
-        localVersion = 3;
+    localVersion = _CFBundleGetBundleVersionForURL(newURL);
+    if (localVersion == 3) {
         SInt32 res = _CFGetPathProperties(allocator, (char *)buff, &exists, &mode, NULL, NULL, NULL, NULL);
 #if DEPLOYMENT_TARGET_WINDOWS
         if (!(res == 0 && exists && ((mode & S_IFMT) == S_IFDIR))) {
@@ -1202,7 +1158,9 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL,
     bundle->_infoDict = NULL;
     bundle->_localInfoDict = NULL;
     bundle->_searchLanguages = NULL;
-    
+    bundle->_executablePath = NULL;
+    bundle->_developmentRegion = NULL;
+    bundle->_developmentRegionCalculated = false;
 #if defined(BINARY_SUPPORT_DYLD)
     /* We'll have to figure it out later */
     bundle->_binaryType = __CFBundleUnknownBinary;
@@ -1250,8 +1208,12 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL,
         CFLog(4, CFSTR("%s: failed to initialize bundle loading lock for bundle %@."), __PRETTY_FUNCTION__, bundle);
     }
     
-    // ZFH
-    /* resource fast look up */
+    bundle->_lock = CFSpinLockInit;
+    bundle->_resourceDirectoryContents = NULL;
+    
+    bundle->_localizations = NULL;
+    bundle->_lookedForLocalizations = false;
+    
     bundle->_queryLock = CFSpinLockInit;
     bundle->_queryTable = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     CFURLRef absoURL = CFURLCopyAbsoluteURL(bundle->_url);
@@ -1278,9 +1240,8 @@ CFBundleRef CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL) {
 }
 
 CFArrayRef CFBundleCreateBundlesFromDirectory(CFAllocatorRef alloc, CFURLRef directoryURL, CFStringRef bundleType) {
-    alloc = _CFConvertAllocatorToNonGCRefZeroEquivalent(alloc);
     CFMutableArrayRef bundles = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
-    CFArrayRef URLs = _CFContentsOfDirectory(alloc, NULL, NULL, directoryURL, bundleType);
+    CFArrayRef URLs = _CFCreateContentsOfDirectory(alloc, NULL, NULL, directoryURL, bundleType);
     if (URLs) {
         CFIndex i, c = CFArrayGetCount(URLs);
         CFURLRef curURL;
@@ -1302,141 +1263,6 @@ CFURLRef CFBundleCopyBundleURL(CFBundleRef bundle) {
     return bundle->_url;
 }
 
-void _CFBundleSetDefaultLocalization(CFStringRef localizationName) {
-    CFStringRef newLocalization = localizationName ? (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, localizationName) : NULL;
-    if (_defaultLocalization) CFRelease(_defaultLocalization);
-    _defaultLocalization = newLocalization;
-}
-
-CFArrayRef _CFBundleGetLanguageSearchList(CFBundleRef bundle) {
-    if (!bundle->_searchLanguages) {
-        CFMutableArrayRef langs = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        CFStringRef devLang = CFBundleGetDevelopmentRegion(bundle);
-
-#if DEPLOYMENT_TARGET_WINDOWS
-        if (_defaultLocalization) CFArrayAppendValue(langs, _defaultLocalization);
-#endif
-        _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, devLang);
-
-        if (CFArrayGetCount(langs) == 0) {
-            // If the user does not prefer any of our languages, and devLang is not present, try English
-            _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, CFSTR("en_US"));
-        }
-        if (CFArrayGetCount(langs) == 0) {
-            // if none of the preferred localizations are present, fall back on a random localization that is present
-            CFArrayRef localizations = CFBundleCopyBundleLocalizations(bundle);
-            if (localizations) {
-                if (CFArrayGetCount(localizations) > 0) _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, bundle->_version, bundle->_infoDict, langs, (CFStringRef)CFArrayGetValueAtIndex(localizations, 0));
-                CFRelease(localizations);
-            }
-        }
-        
-        if (devLang && !CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), devLang)) {
-            // Make sure that devLang is on the list as a fallback for individual resources that are not present
-            CFArrayAppendValue(langs, devLang);
-        } else if (!devLang) {
-            // Or if there is no devLang, try some variation of English that is present
-            CFArrayRef localizations = CFBundleCopyBundleLocalizations(bundle);
-            if (localizations) {
-                CFStringRef en_US = CFSTR("en_US"), en = CFSTR("en"), English = CFSTR("English");
-                CFRange range = CFRangeMake(0, CFArrayGetCount(localizations));
-                if (CFArrayContainsValue(localizations, range, en)) {
-                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en)) CFArrayAppendValue(langs, en);
-                } else if (CFArrayContainsValue(localizations, range, English)) {
-                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), English)) CFArrayAppendValue(langs, English);
-                } else if (CFArrayContainsValue(localizations, range, en_US)) {
-                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en_US)) CFArrayAppendValue(langs, en_US);
-                }
-                CFRelease(localizations);
-            }
-        }
-        if (CFArrayGetCount(langs) == 0) {
-            // Total backstop behavior to avoid having an empty array.
-            if (_defaultLocalization) {
-                CFArrayAppendValue(langs, _defaultLocalization);
-            } else {
-                CFArrayAppendValue(langs, CFSTR("en"));
-            }
-        }
-        if (!OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)langs, (void * volatile *)&(bundle->_searchLanguages))) CFRelease(langs);
-    }
-    return bundle->_searchLanguages;
-}
-
-CFDictionaryRef CFBundleCopyInfoDictionaryInDirectory(CFURLRef url) {
-    CFDictionaryRef dict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefaultGCRefZero, url, NULL);
-    if (dict && _CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRetain(dict); // conditionally put on a retain for a Copy function
-    return dict;
-}
-
-CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) {
-    if (!bundle->_infoDict) bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(kCFAllocatorSystemDefaultGCRefZero, bundle->_url, bundle->_version);
-    return bundle->_infoDict;
-}
-
-CFDictionaryRef _CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
-    return CFBundleGetLocalInfoDictionary(bundle);
-}
-
-CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
-    static pthread_mutex_t CFBundleLocalInfoLock = PTHREAD_MUTEX_INITIALIZER;
-    CFDictionaryRef localInfoDict = bundle->_localInfoDict;
-    if (!localInfoDict) {
-        CFURLRef url = CFBundleCopyResourceURL(bundle, _CFBundleLocalInfoName, _CFBundleStringTableType, NULL);
-        if (url) {
-            CFDataRef data;
-            SInt32 errCode;
-            CFStringRef errStr = NULL;
-            
-            if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, url, &data, NULL, NULL, &errCode)) {
-                localInfoDict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefaultGCRefZero, data, kCFPropertyListMutableContainers, &errStr);
-                if (errStr) CFRelease(errStr);
-                if (localInfoDict && CFDictionaryGetTypeID() != CFGetTypeID(localInfoDict)) {
-                    if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(localInfoDict);
-                    localInfoDict = NULL;
-                }
-                CFRelease(data);
-            }
-            CFRelease(url);
-        }
-        if (localInfoDict) _processInfoDictionary((CFMutableDictionaryRef)localInfoDict, _CFGetPlatformName(), _CFGetProductName());
-        pthread_mutex_lock(&CFBundleLocalInfoLock);
-        if (!bundle->_localInfoDict) {
-            bundle->_localInfoDict = localInfoDict;
-        } else {
-            if (localInfoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(localInfoDict);
-            localInfoDict = bundle->_localInfoDict;
-        }
-        pthread_mutex_unlock(&CFBundleLocalInfoLock);
-    }
-    return localInfoDict;
-}
-
-CFPropertyListRef _CFBundleGetValueForInfoKey(CFBundleRef bundle, CFStringRef key) {
-    return (CFPropertyListRef)CFBundleGetValueForInfoDictionaryKey(bundle, key);
-}
-
-CFTypeRef CFBundleGetValueForInfoDictionaryKey(CFBundleRef bundle, CFStringRef key) {
-    // Look in InfoPlist.strings first.  Then look in Info.plist
-    CFTypeRef result = NULL;
-    if (bundle && key) {
-        CFDictionaryRef dict = CFBundleGetLocalInfoDictionary(bundle);
-        if (dict) result = CFDictionaryGetValue(dict, key);
-        if (!result) {
-            dict = CFBundleGetInfoDictionary(bundle);
-            if (dict) result = CFDictionaryGetValue(dict, key);
-        }
-    }
-    return result;
-}
-
-CFStringRef CFBundleGetIdentifier(CFBundleRef bundle) {
-    CFStringRef bundleID = NULL;
-    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
-    if (infoDict) bundleID = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleIdentifierKey);
-    return bundleID;
-}
-
 #define DEVELOPMENT_STAGE 0x20
 #define ALPHA_STAGE 0x40
 #define BETA_STAGE 0x60
@@ -1446,7 +1272,7 @@ CFStringRef CFBundleGetIdentifier(CFBundleRef bundle) {
 
 CF_INLINE Boolean _isDigit(UniChar aChar) {return ((aChar >= (UniChar)'0' && aChar <= (UniChar)'9') ? true : false);}
 
-__private_extern__ CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef alloc, UInt32 vers) {
+CF_PRIVATE CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef alloc, UInt32 vers) {
     CFStringRef result = NULL;
     uint8_t major1, major2, minor1, minor2, stage, build;
 
@@ -1465,15 +1291,15 @@ __private_extern__ CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef a
         }
     } else {
         if (major1 > 0) {
-            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d%C%d"), major1, major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build);
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d%c%d"), major1, major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build);
         } else {
-            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d%C%d"), major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build);
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d%c%d"), major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build);
         }
     }
     return result;
 }
 
-__private_extern__ UInt32 _CFVersionNumberFromString(CFStringRef versStr) {
+CF_PRIVATE UInt32 _CFVersionNumberFromString(CFStringRef versStr) {
     // Parse version number from string.
     // String can begin with "." for major version number 0.  String can end at any point, but elements within the string cannot be skipped.
     UInt32 major1 = 0, major2 = 0, minor1 = 0, minor2 = 0, stage = RELEASE_STAGE, build = 0;
@@ -1632,40 +1458,32 @@ __private_extern__ UInt32 _CFVersionNumberFromString(CFStringRef versStr) {
 
 UInt32 CFBundleGetVersionNumber(CFBundleRef bundle) {
     CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
-    CFTypeRef unknownVersionValue = CFDictionaryGetValue(infoDict, _kCFBundleNumericVersionKey);
-    CFNumberRef versNum;
+    CFNumberRef versionValue = (CFNumberRef)CFDictionaryGetValue(infoDict, _kCFBundleNumericVersionKey);
+    if (!versionValue || CFGetTypeID(versionValue) != CFNumberGetTypeID()) return 0;
+    
     UInt32 vers = 0;
-
-    if (!unknownVersionValue) unknownVersionValue = CFDictionaryGetValue(infoDict, kCFBundleVersionKey);
-    if (unknownVersionValue) {
-        if (CFGetTypeID(unknownVersionValue) == CFStringGetTypeID()) {
-            // Convert a string version number into a numeric one.
-            vers = _CFVersionNumberFromString((CFStringRef)unknownVersionValue);
-
-            versNum = CFNumberCreate(CFGetAllocator(bundle), kCFNumberSInt32Type, &vers);
-            CFDictionarySetValue((CFMutableDictionaryRef)infoDict, _kCFBundleNumericVersionKey, versNum);
-            CFRelease(versNum);
-        } else if (CFGetTypeID(unknownVersionValue) == CFNumberGetTypeID()) {
-            CFNumberGetValue((CFNumberRef)unknownVersionValue, kCFNumberSInt32Type, &vers);
-        } else {
-            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, _kCFBundleNumericVersionKey);
-        }
-    }
+    CFNumberGetValue(versionValue, kCFNumberSInt32Type, &vers);
     return vers;
 }
 
 CFStringRef CFBundleGetDevelopmentRegion(CFBundleRef bundle) {
-    CFStringRef devLang = NULL;
-    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
-    if (infoDict) {
-        devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
-        if (devLang && (CFGetTypeID(devLang) != CFStringGetTypeID() || CFStringGetLength(devLang) == 0)) {
-            devLang = NULL;
-            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleDevelopmentRegionKey);
+    CFStringRef devRegion = NULL;
+    devRegion = bundle->_developmentRegion;
+    
+    if (!devRegion && !bundle->_developmentRegionCalculated) {
+        CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+        if (infoDict) {
+            devRegion = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
+            if (devRegion && (CFGetTypeID(devRegion) != CFStringGetTypeID() || CFStringGetLength(devRegion) == 0)) {
+                devRegion = NULL;
+            }
         }
+            
+        if (devRegion) bundle->_developmentRegion = (CFStringRef)CFRetain(devRegion);
+        bundle->_developmentRegionCalculated = true;
     }
 
-    return devLang;
+    return devRegion;
 }
 
 Boolean _CFBundleGetHasChanged(CFBundleRef bundle) {
@@ -1720,7 +1538,7 @@ static Boolean _binaryLoadable(CFURLRef url) {
     return loadable;
 }
 
-__private_extern__ CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) {
+CF_PRIVATE CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) {
     CFURLRef result = NULL;
     if (bundleURL) {
         if (1 == version) {
@@ -1738,7 +1556,7 @@ CF_EXPORT CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle) {
     return _CFBundleCopySupportFilesDirectoryURLInDirectory(bundle->_url, bundle->_version);
 }
 
-__private_extern__ CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) {
+CF_PRIVATE CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) {
     CFURLRef result = NULL;
     if (bundleURL) {
         if (0 == version) {
@@ -1758,7 +1576,7 @@ CFURLRef CFBundleCopyResourcesDirectoryURL(CFBundleRef bundle) {
     return _CFBundleCopyResourcesDirectoryURLInDirectory(bundle->_url, bundle->_version);
 }
 
-__private_extern__ CFURLRef _CFBundleCopyAppStoreReceiptURLInDirectory(CFURLRef bundleURL, uint8_t version) {
+CF_PRIVATE CFURLRef _CFBundleCopyAppStoreReceiptURLInDirectory(CFURLRef bundleURL, uint8_t version) {
     CFURLRef result = NULL;
     if (bundleURL) {
         if (0 == version) {
@@ -1852,7 +1670,7 @@ static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeN
     return executableURL;
 }
 
-static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict) {
+CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict) {
     CFStringRef executableName = NULL;
     
     if (!infoDict && bundle) infoDict = CFBundleGetInfoDictionary(bundle);
@@ -1876,16 +1694,13 @@ static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url,
         CFStringRef bundlePath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
         CFRelease(absoluteURL);
         if (bundlePath) {
-            UniChar buff[CFMaxPathSize];
             CFIndex len = CFStringGetLength(bundlePath);
-            CFIndex startOfBundleName, endOfBundleName;
-            
-            if (len > CFMaxPathSize) len = CFMaxPathSize;
-            CFStringGetCharacters(bundlePath, CFRangeMake(0, len), buff);
-            startOfBundleName = _CFStartOfLastPathComponent(buff, len);
-            endOfBundleName = _CFLengthAfterDeletingPathExtension(buff, len);
+            CFIndex startOfBundleName = _CFStartOfLastPathComponent2(bundlePath);
+            CFIndex endOfBundleName = _CFLengthAfterDeletingPathExtension2(bundlePath);
             
-            if (startOfBundleName <= len && endOfBundleName <= len && startOfBundleName < endOfBundleName) executableName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfBundleName]), endOfBundleName - startOfBundleName);
+            if (startOfBundleName <= len && endOfBundleName <= len && startOfBundleName < endOfBundleName) {
+                executableName = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, bundlePath, CFRangeMake(startOfBundleName, endOfBundleName - startOfBundleName));
+            }
             CFRelease(bundlePath);
         }
     }
@@ -1893,76 +1708,6 @@ static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url,
     return executableName;
 }
 
-__private_extern__ CFURLRef _CFBundleCopyResourceForkURLWithoutLocal(CFBundleRef bundle) {
-    CFStringRef executableName = _CFBundleCopyExecutableName(bundle, NULL, NULL);
-    CFURLRef resourceForkURL = NULL;
-    if (executableName) {
-        UniChar *path = (UniChar *) CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * CFMaxPathSize, 0);
-        CFIndex pathLen = CFStringGetLength(bundle->_bundleBasePath);
-        CFStringGetCharacters(bundle->_bundleBasePath, CFRangeMake(0, CFStringGetLength(bundle->_bundleBasePath)), path);
-        _CFBundleSetResourceDir(path, &pathLen, CFMaxPathSize, bundle->_version);
-        _CFAppendTrailingPathSlash(path, &pathLen, CFMaxPathSize);
-        CFStringGetCharacters(executableName, CFRangeMake(0, CFStringGetLength(executableName)), path+pathLen);
-        pathLen += CFStringGetLength(executableName);
-        path[pathLen++] = '.';
-        CFStringGetCharacters(CFSTR("rsrc"), CFRangeMake(0, 4), path+pathLen);
-        pathLen += 4;
-        CFStringRef pathStr = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, path, pathLen);
-        Boolean found = false;
-        found = _CFIsResourceAtPath(pathStr, NULL);
-        if (found) {
-            resourceForkURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, pathStr, PLATFORM_PATH_STYLE, false);
-        }
-        CFRelease(pathStr);
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, path);
-        CFRelease(executableName);
-    }
-    
-    return resourceForkURL;
-}
-
-__private_extern__ CFURLRef _CFBundleCopyResourceForkURLMayBeLocal(CFBundleRef bundle, Boolean mayBeLocal) {
-    CFStringRef executableName = _CFBundleCopyExecutableName(bundle, NULL, NULL);
-    CFURLRef resourceForkURL = NULL;
-    if (executableName) {
-        CFStringRef type = CFSTR("rsrc");
-#ifdef CFBUNDLE_NEWLOOKUP
-        if (mayBeLocal) {
-            resourceForkURL = (CFURLRef) _CFBundleCopyFindResourcesWithNoBlock(bundle, NULL, NULL, executableName, type, NULL, NULL, NO, NO);            
-        } else {
-            CFArrayRef languages = CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
-            resourceForkURL = (CFURLRef) _CFBundleCopyFindResourcesWithNoBlock(bundle, NULL, languages, executableName, type, NULL, NULL, NO, NO);
-            CFRelease(languages);
-        }
-#else
-        CFArrayRef types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&type, 1, &kCFTypeArrayCallBacks);
-        CFArrayRef array = NULL;
-        if (mayBeLocal) {
-            CFArrayRef languages = _CFBundleGetLanguageSearchList(bundle);
-            array = _CFFindBundleResourcesNoBlock(bundle, NULL, NULL, languages, executableName, types, 1, _CFBundleLayoutVersion(bundle));
-            if (array) {
-                if (CFArrayGetCount(array) > 0) resourceForkURL = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
-                CFRelease(array);
-            }
-        } else {
-            array = _CFFindBundleResourcesNoBlock(bundle, NULL, NULL, NULL, executableName, types, 1, _CFBundleLayoutVersion(bundle));
-            if (array) {
-                if (CFArrayGetCount(array) > 0) resourceForkURL = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
-                CFRelease(array);
-            }
-        }
-        CFRelease(types);
-#endif
-        CFRelease(executableName);
-    }
-    
-    return resourceForkURL;
-}
-
-CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle) {
-    return _CFBundleCopyResourceForkURLMayBeLocal(bundle, true);
-}
-
 static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURLRef url, CFStringRef executableName, Boolean ignoreCache, Boolean useOtherPlatform) {
     uint8_t version = 0;
     CFDictionaryRef infoDict = NULL;
@@ -1970,38 +1715,33 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
     CFURLRef executableURL = NULL;
     Boolean foundIt = false;
     Boolean lookupMainExe = (executableName ? false : true);
-    static CFSpinLock_t CFBundleExecutablePathLock = CFSpinLockInit;
     
     if (bundle) {
         infoDict = CFBundleGetInfoDictionary(bundle);
         version = bundle->_version;
     } else {
-        infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefaultGCRefZero, url, &version);
+        infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, &version);
     }
-
+    
     // If we have a bundle instance and an info dict, see if we have already cached the path
-    if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && infoDict) {
-        __CFSpinLock(&CFBundleExecutablePathLock);
-        executablePath = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleExecutablePathKey);
+    if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && bundle->_executablePath) {
+        __CFSpinLock(&bundle->_lock);
+        executablePath = bundle->_executablePath;
         if (executablePath) CFRetain(executablePath);
-        __CFSpinUnlock(&CFBundleExecutablePathLock);
+        __CFSpinUnlock(&bundle->_lock);
         if (executablePath) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLPOSIXPathStyle, false);
 #elif DEPLOYMENT_TARGET_WINDOWS
             executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLWindowsPathStyle, false);
-#endif 
+#endif
             if (executableURL) {
                 foundIt = true;
-            } else {
-                __CFSpinLock(&CFBundleExecutablePathLock);
-                CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, _kCFBundleExecutablePathKey);
-                __CFSpinUnlock(&CFBundleExecutablePathLock);
             }
             CFRelease(executablePath);
         }
     }
-
+    
     if (!foundIt) {
         if (lookupMainExe) executableName = _CFBundleCopyExecutableName(bundle, url, infoDict);
         if (executableName) {
@@ -2014,7 +1754,7 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
             if (doExecSearch && 0 != version) {
                 CFURLRef exeDirURL = NULL;
                 CFURLRef exeSubdirURL;
-
+                
                 if (1 == version) {
                     exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase1, url);
                 } else if (2 == version) {
@@ -2057,10 +1797,10 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                 CFRelease(exeDirURL);
                 CFRelease(exeSubdirURL);
             }
-
+            
             // If this was an old bundle, or we did not find the executable in the Executables subdirectory, look directly in the bundle wrapper.
             if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(url, executableName);
-
+            
 #if DEPLOYMENT_TARGET_WINDOWS
             // Windows only: If we still haven't found the exe, look in the Executables folder.
             // But only for the main bundle exe
@@ -2070,8 +1810,8 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                 CFRelease(exeDirURL);
             }
 #endif
-
-            if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && infoDict && executableURL) {
+            
+            if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && executableURL) {
                 // We found it.  Cache the path.
                 CFURLRef absURL = CFURLCopyAbsoluteURL(executableURL);
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -2080,19 +1820,20 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                 executablePath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle);
 #endif
                 CFRelease(absURL);
-                __CFSpinLock(&CFBundleExecutablePathLock);
-                CFDictionarySetValue((CFMutableDictionaryRef)infoDict, _kCFBundleExecutablePathKey, executablePath);
-                __CFSpinUnlock(&CFBundleExecutablePathLock);
+                __CFSpinLock(&bundle->_lock);
+                bundle->_executablePath = (CFStringRef)CFRetain(executablePath);
+                __CFSpinUnlock(&bundle->_lock);
                 CFRelease(executablePath);
             }
             if (lookupMainExe && !useOtherPlatform && bundle && !executableURL) bundle->_binaryType = __CFBundleNoBinary;
             if (lookupMainExe) CFRelease(executableName);
         }
     }
-    if (!bundle && infoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(infoDict);
+    if (!bundle && infoDict && !(0)) CFRelease(infoDict);
     return executableURL;
 }
 
+
 CFURLRef _CFBundleCopyExecutableURLInDirectory(CFURLRef url) {
     return _CFBundleCopyExecutableURLInDirectory2(NULL, url, NULL, true, false);
 }
@@ -2218,23 +1959,22 @@ static const char * __CFBundleODExtensionsArray = "odc\0\0" "odf\0\0" "odg\0\0"
 CF_INLINE uint32_t _CFBundleSwapInt32Conditional(uint32_t arg, Boolean swap) {return swap ? CFSwapInt32(arg) : arg;}
 CF_INLINE uint32_t _CFBundleSwapInt64Conditional(uint64_t arg, Boolean swap) {return swap ? CFSwapInt64(arg) : arg;}
 
-// returns zero-ref dictionary under GC
-static CFMutableDictionaryRef _CFBundleGrokInfoDictFromData(const char *bytes, uint32_t length) {
+static CFMutableDictionaryRef _CFBundleCreateInfoDictFromData(const char *bytes, uint32_t length) {
     CFMutableDictionaryRef result = NULL;
     CFDataRef infoData = NULL;
     if (bytes && 0 < length) {
         infoData = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, (uint8_t *)bytes, length, kCFAllocatorNull);
         if (infoData) {
-            result = (CFMutableDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefaultGCRefZero, infoData, kCFPropertyListMutableContainers, NULL);
+            result = (CFMutableDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, infoData, kCFPropertyListMutableContainers, NULL);
             if (result && CFDictionaryGetTypeID() != CFGetTypeID(result)) {
                 CFRelease(result);
                 result = NULL;
             }
             CFRelease(infoData);
         }
-        if (!result) result = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        if (!result) result = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     }
-    if (result) _processInfoDictionary((CFMutableDictionaryRef)result, _CFGetPlatformName(), _CFGetProductName());
+    if (result) _CFBundleInfoPlistProcessInfoDictionary((CFMutableDictionaryRef)result);
     return result;
 }
 
@@ -2266,12 +2006,11 @@ static char *_CFBundleGetSectData(const char *segname, const char *sectname, uns
     return retval;
 }
 
-// returns zero-ref dictionary under GC
-static CFMutableDictionaryRef _CFBundleGrokInfoDictFromMainExecutable() {
+static CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable() {
     char *bytes = NULL;
     unsigned long length = 0;
     if (getsegbyname(TEXT_SEGMENT)) bytes = _CFBundleGetSectData(TEXT_SEGMENT, PLIST_SECTION, &length);
-    return _CFBundleGrokInfoDictFromData(bytes, length);
+    return _CFBundleCreateInfoDictFromData(bytes, length);
 }
 
 static Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags) {
@@ -2344,8 +2083,7 @@ static Boolean _CFBundleGrokX11FromFile(int fd, const void *bytes, CFIndex lengt
     return result;
 }
     
-// returns zero-ref dictionary under GC
-static CFDictionaryRef _CFBundleGrokInfoDictFromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour) {
+static CFDictionaryRef _CFBundleCreateInfoDictFromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour) {
     struct statinfo statBuf;
     off_t fileLength = 0;
     char *maploc = NULL;
@@ -2379,7 +2117,7 @@ static CFDictionaryRef _CFBundleGrokInfoDictFromFile(int fd, const void *bytes,
                             uint32_t sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
                             const char *sectbytes = loc + offset + sectoffset;
                             // we don't support huge-sized plists
-                            if (sectlength64 <= 0xffffffff && loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = (CFDictionaryRef)_CFBundleGrokInfoDictFromData(sectbytes, sectlength);
+                            if (sectlength64 <= 0xffffffff && loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = (CFDictionaryRef)_CFBundleCreateInfoDictFromData(sectbytes, sectlength);
                             foundit = true;
                         }
                         sp = (struct section_64 *)((char *)sp + sizeof(struct section_64));
@@ -2403,7 +2141,7 @@ static CFDictionaryRef _CFBundleGrokInfoDictFromFile(int fd, const void *bytes,
                             uint32_t sectlength = _CFBundleSwapInt32Conditional(sp->size, swapped);
                             uint32_t sectoffset = _CFBundleSwapInt32Conditional(sp->offset, swapped);
                             const char *sectbytes = loc + offset + sectoffset;
-                            if (loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = (CFDictionaryRef)_CFBundleGrokInfoDictFromData(sectbytes, sectlength);
+                            if (loc <= sectbytes && sectbytes + sectlength <= loc + fileLength) result = (CFDictionaryRef)_CFBundleCreateInfoDictFromData(sectbytes, sectlength);
                             foundit = true;
                         }
                         sp = (struct section *)((char *)sp + sizeof(struct section));
@@ -2496,7 +2234,6 @@ static void _CFBundleGrokObjcImageInfoFromFile(int fd, const void *bytes, CFInde
     if (objcFlags) *objcFlags = localFlags;
 }
 
-// returns zero-ref dictionary in *infodict under GC
 static UInt32 _CFBundleGrokMachTypeForFatFile(int fd, const void *bytes, CFIndex length, Boolean swap, Boolean *isX11, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
     CFIndex headerLength = length;
     unsigned char headerBuffer[MAGIC_BYTES_TO_READ];
@@ -2548,22 +2285,22 @@ static UInt32 _CFBundleGrokMachTypeForFatFile(int fd, const void *bytes, CFIndex
             if (MH_MAGIC == magic) {
                 machtype = ((struct mach_header *)moreBytes)->filetype;
                 if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, false, false);
-                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, false, false);
+                if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, fat->offset, false, false);
                 if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, false, false, hasObjc, objcVersion, objcFlags);
             } else if (MH_CIGAM == magic) {
                 machtype = CFSwapInt32(((struct mach_header *)moreBytes)->filetype);
                 if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, true, false);
-                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, true, false);
+                if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, fat->offset, true, false);
                 if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, true, false, hasObjc, objcVersion, objcFlags);
             } else if (MH_MAGIC_64 == magic) {
                 machtype = ((struct mach_header_64 *)moreBytes)->filetype;
                 if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, false, true);
-                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, false, true);
+                if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, fat->offset, false, true);
                 if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, false, true, hasObjc, objcVersion, objcFlags);
             } else if (MH_CIGAM_64 == magic) {
                 machtype = CFSwapInt32(((struct mach_header_64 *)moreBytes)->filetype);
                 if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, fat->offset, true, true);
-                if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, fat->offset, true, true);
+                if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, fat->offset, true, true);
                 if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, fat->offset, true, true, hasObjc, objcVersion, objcFlags);
             }
         }
@@ -2571,7 +2308,6 @@ static UInt32 _CFBundleGrokMachTypeForFatFile(int fd, const void *bytes, CFIndex
     return machtype;
 }
 
-// returns zero-ref dictionary in *infodict under GC
 static UInt32 _CFBundleGrokMachType(int fd, const void *bytes, CFIndex length, Boolean *isX11, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
     unsigned int magic = *((UInt32 *)bytes), machtype = UNKNOWN_FILETYPE, cputype;
     CFNumberRef architecture = NULL;
@@ -2587,28 +2323,28 @@ static UInt32 _CFBundleGrokMachType(int fd, const void *bytes, CFIndex length, B
         cputype = ((struct mach_header *)bytes)->cputype;
         if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, &cputype);
         if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, false, false);
-        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, false, false);
+        if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, 0, false, false);
         if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, false, false, hasObjc, objcVersion, objcFlags);
     } else if (MH_CIGAM == magic) {
         machtype = CFSwapInt32(((struct mach_header *)bytes)->filetype);
         cputype = CFSwapInt32(((struct mach_header *)bytes)->cputype);
         if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, &cputype);
         if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, true, false);
-        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, true, false);
+        if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, 0, true, false);
         if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, true, false, hasObjc, objcVersion, objcFlags);
     } else if (MH_MAGIC_64 == magic) {
         machtype = ((struct mach_header_64 *)bytes)->filetype;
         cputype = ((struct mach_header_64 *)bytes)->cputype;
         if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, &cputype);
         if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, false, true);
-        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, false, true);
+        if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, 0, false, true);
         if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, false, true, hasObjc, objcVersion, objcFlags);
     } else if (MH_CIGAM_64 == magic) {
         machtype = CFSwapInt32(((struct mach_header_64 *)bytes)->filetype);
         cputype = CFSwapInt32(((struct mach_header_64 *)bytes)->cputype);
         if (architectures) architecture = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, &cputype);
         if (isX11 && MH_EXECUTE == machtype) *isX11 = _CFBundleGrokX11FromFile(fd, bytes, length, 0, true, true);
-        if (infodict) *infodict = _CFBundleGrokInfoDictFromFile(fd, bytes, length, 0, true, true);
+        if (infodict) *infodict = _CFBundleCreateInfoDictFromFile(fd, bytes, length, 0, true, true);
         if (hasObjc || objcVersion || objcFlags) _CFBundleGrokObjcImageInfoFromFile(fd, bytes, length, 0, true, true, hasObjc, objcVersion, objcFlags);
     } else if (FAT_MAGIC == magic) {
         machtype = _CFBundleGrokMachTypeForFatFile(fd, bytes, length, false, isX11, architectures, infodict, hasObjc, objcVersion, objcFlags);
@@ -2798,7 +2534,6 @@ static const char *_CFBundleGrokFileTypeForOLEFile(int fd, const void *bytes, CF
     return ext;
 }
 
-// returns zero-ref dictionary in *infodict under GC
 static Boolean _CFBundleGrokFileType(CFURLRef url, CFDataRef data, CFStringRef *extension, UInt32 *machtype, CFArrayRef *architectures, CFDictionaryRef *infodict, Boolean *hasObjc, uint32_t *objcVersion, uint32_t *objcFlags) {
     int fd = -1;
     const unsigned char *bytes = NULL;
@@ -3053,14 +2788,13 @@ CFStringRef _CFBundleCopyFileTypeForFileData(CFDataRef data) {
     return extension;
 }
 
-// returns zero-ref dictionary under GC
-__private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url) {
+CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url) {
     CFDictionaryRef result = NULL;
     (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, NULL, &result, NULL, NULL, NULL);
     return result;
 }
 
-__private_extern__ CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url) {
+CF_PRIVATE CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url) {
     CFArrayRef result = NULL;
     (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, &result, NULL, NULL, NULL, NULL);
     return result;
@@ -3076,7 +2810,7 @@ static Boolean _CFBundleGetObjCImageInfoForExecutable(CFURLRef url, uint32_t *ob
 
 #if defined(BINARY_SUPPORT_DYLD)
 
-__private_extern__ __CFPBinaryType _CFBundleGrokBinaryType(CFURLRef executableURL) {
+CF_PRIVATE __CFPBinaryType _CFBundleGrokBinaryType(CFURLRef executableURL) {
     // Attempt to grok the type of the binary by looking for DYLD magic numbers.  If one of the DYLD magic numbers is found, find out what type of Mach-o file it is.  Otherwise, look for the PEF magic numbers to see if it is CFM.
     __CFPBinaryType result = executableURL ? __CFBundleUnreadableBinary : __CFBundleNoBinary;
     UInt32 machtype = UNKNOWN_FILETYPE;
@@ -3108,6 +2842,9 @@ void _CFBundleSetCFMConnectionID(CFBundleRef bundle, void *connectionID) {
 
 static CFStringRef _CFBundleCopyLastPathComponent(CFBundleRef bundle) {
     CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
+    if (!bundleURL) {
+        return CFSTR("<unknown>");
+    }
     CFStringRef str = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
     UniChar buff[CFMaxPathSize];
     CFIndex buffLen = CFStringGetLength(str), startOfLastDir = 0;
@@ -3204,7 +2941,6 @@ static CFErrorRef _CFBundleCreateErrorDebug(CFAllocatorRef allocator, CFBundleRe
 }
 
 CFErrorRef _CFBundleCreateError(CFAllocatorRef allocator, CFBundleRef bundle, CFIndex code) {
-    allocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
     return _CFBundleCreateErrorDebug(allocator, bundle, code, NULL);
 }
 
@@ -3213,6 +2949,7 @@ Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceG
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
 
+
     pthread_mutex_lock(&(bundle->_bundleLoadingLock));
     if (!executableURL) bundle->_binaryType = __CFBundleNoBinary;
     // make sure we know whether bundle is already loaded or not
@@ -3493,7 +3230,7 @@ void CFBundleUnloadExecutable(CFBundleRef bundle) {
 
 #if AVOID_WEAK_COLLECTIONS
 
-__private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (!_bundlesToUnload) {
         CFSetCallBacks nonRetainingCallbacks = kCFTypeSetCallBacks;
@@ -3505,13 +3242,13 @@ __private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
     pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
-__private_extern__ void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle);
     pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
-__private_extern__ void _CFBundleUnloadScheduledBundles(void) {
+CF_PRIVATE void _CFBundleUnloadScheduledBundles(void) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) {
         CFIndex i, c = CFSetGetCount(_bundlesToUnload);
@@ -3532,20 +3269,20 @@ __private_extern__ void _CFBundleUnloadScheduledBundles(void) {
 
 #else /* AVOID_WEAK_COLLECTIONS */
 
-__private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (!_bundlesToUnload) _bundlesToUnload = [[__CFHashTable alloc] initWithOptions:CFPointerFunctionsZeroingWeakMemory capacity:0];
     [_bundlesToUnload addObject:(id)bundle];
     pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
-__private_extern__ void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) [_bundlesToUnload removeObject:(id)bundle];
     pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
-__private_extern__ void _CFBundleUnloadScheduledBundles(void) {
+CF_PRIVATE void _CFBundleUnloadScheduledBundles(void) {
     pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload && [_bundlesToUnload count] > 0) {
         CFIndex i, c;
@@ -3687,7 +3424,7 @@ void CFBundleGetDataPointersForNames(CFBundleRef bundle, CFArrayRef symbolNames,
     for (i = 0; i < c; i++) stbl[i] = CFBundleGetDataPointerForName(bundle, (CFStringRef)CFArrayGetValueAtIndex(symbolNames, i));
 }
 
-__private_extern__ _CFResourceData *__CFBundleGetResourceData(CFBundleRef bundle) {
+CF_PRIVATE _CFResourceData *__CFBundleGetResourceData(CFBundleRef bundle) {
     return &(bundle->_resourceData);
 }
 
@@ -3695,11 +3432,11 @@ CFPlugInRef CFBundleGetPlugIn(CFBundleRef bundle) {
     return (bundle->_plugInData._isPlugIn) ? (CFPlugInRef)bundle : NULL;
 }
 
-__private_extern__ _CFPlugInData *__CFBundleGetPlugInData(CFBundleRef bundle) {
+CF_PRIVATE _CFPlugInData *__CFBundleGetPlugInData(CFBundleRef bundle) {
     return &(bundle->_plugInData);
 }
 
-__private_extern__ Boolean _CFBundleCouldBeBundle(CFURLRef url) {
+CF_PRIVATE Boolean _CFBundleCouldBeBundle(CFURLRef url) {
     Boolean result = false;
     Boolean exists;
     SInt32 mode;
@@ -3941,7 +3678,7 @@ CF_EXPORT CFArrayRef _CFBundleCopyAllBundles(void) {
     return bundles;
 }
 
-uint8_t _CFBundleLayoutVersion(CFBundleRef bundle) {
+CF_PRIVATE uint8_t _CFBundleLayoutVersion(CFBundleRef bundle) {
     return bundle->_version;
 }
 
@@ -3979,7 +3716,7 @@ static void __addPlatformAndProductNamesToKeys(const void *value, void *context)
 }
 
 // from CFUtilities.c
-__private_extern__ Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map, Boolean uncached, void **outBytes, CFIndex *outLength, CFErrorRef *errorPtr);
+CF_PRIVATE Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map, Boolean uncached, void **outBytes, CFIndex *outLength, CFErrorRef *errorPtr);
 
 // implementation of below functions - takes URL as parameter
 static CFPropertyListRef _CFBundleCreateFilteredInfoPlistWithURL(CFURLRef infoPlistURL, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) {
@@ -4014,7 +3751,7 @@ static CFPropertyListRef _CFBundleCreateFilteredInfoPlistWithURL(CFURLRef infoPl
     if (!success) {
         result = CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     } else {
-        _processInfoDictionary((CFMutableDictionaryRef)result, _CFGetPlatformName(), _CFGetProductName());
+        _CFBundleInfoPlistProcessInfoDictionary((CFMutableDictionaryRef)result);
     }
     
     CFRelease(newKeyPaths);
@@ -4103,7 +3840,7 @@ CF_EXPORT CFURLRef CFBundleCopySharedSupportURL(CFBundleRef bundle) {
     return result;
 }
 
-__private_extern__ CFURLRef _CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle) {
+CF_PRIVATE CFURLRef _CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle) {
     return CFBundleCopyBuiltInPlugInsURL(bundle);
 }
 
@@ -4138,7 +3875,7 @@ CF_EXPORT CFURLRef CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle) {
 
 #if defined(BINARY_SUPPORT_DYLD)
 
-__private_extern__ CFArrayRef _CFBundleDYLDCopyLoadedImagePathsForHint(CFStringRef hint) {
+CF_PRIVATE CFArrayRef _CFBundleDYLDCopyLoadedImagePathsForHint(CFStringRef hint) {
     uint32_t i, numImages = _dyld_image_count();
     CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     CFRange range = CFRangeMake(0, CFStringGetLength(hint)), altRange = CFRangeMake(0, 0), testRange = CFRangeMake(0, 0);
@@ -4194,7 +3931,7 @@ static char *_cleanedPathForPath(const char *curName) {
     return thePath;
 }
 
-__private_extern__ CFArrayRef _CFBundleDYLDCopyLoadedImagePathsIfChanged(void) {
+CF_PRIVATE CFArrayRef _CFBundleDYLDCopyLoadedImagePathsIfChanged(void) {
     // This returns an array of the paths of all the dyld images in the process.  These paths may not be absolute, they may point at things that are not bundles, they may be staticly linked bundles or dynamically loaded bundles, they may be NULL.
     uint32_t i, numImages = _dyld_image_count();
     CFMutableArrayRef result = NULL;
@@ -4306,7 +4043,7 @@ static const void *__CFBundleDYLDFindImage(char *buff) {
     return (numMatches == 1) ? header : NULL;
 }
 
-__private_extern__ Boolean _CFBundleDYLDCheckLoaded(CFBundleRef bundle) {
+CF_PRIVATE Boolean _CFBundleDYLDCheckLoaded(CFBundleRef bundle) {
     if (!bundle->_isLoaded) {
         CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
         char buff[CFMaxPathSize];
@@ -4333,7 +4070,7 @@ __private_extern__ Boolean _CFBundleDYLDCheckLoaded(CFBundleRef bundle) {
     return bundle->_isLoaded;
 }
 
-__private_extern__ Boolean _CFBundleDYLDLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) {
+CF_PRIVATE Boolean _CFBundleDYLDLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) {
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     NSLinkEditErrors c = NSLinkEditUndefinedError;
     int errorNumber = 0;
@@ -4422,7 +4159,7 @@ __private_extern__ Boolean _CFBundleDYLDLoadBundle(CFBundleRef bundle, Boolean f
     return bundle->_isLoaded;
 }
 
-__private_extern__ Boolean _CFBundleDYLDLoadFramework(CFBundleRef bundle, CFErrorRef *error) {
+CF_PRIVATE Boolean _CFBundleDYLDLoadFramework(CFBundleRef bundle, CFErrorRef *error) {
     // !!! Framework loading should be better.  Can't unload frameworks.
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     NSLinkEditErrors c = NSLinkEditUndefinedError;
@@ -4474,7 +4211,7 @@ __private_extern__ Boolean _CFBundleDYLDLoadFramework(CFBundleRef bundle, CFErro
     return bundle->_isLoaded;
 }
 
-__private_extern__ void _CFBundleDYLDUnloadBundle(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleDYLDUnloadBundle(CFBundleRef bundle) {
     if (bundle->_isLoaded) {
 #if LOG_BUNDLE_LOAD
         printf("dyld unload bundle %p, handle %p module %p image %p\n", bundle, bundle->_handleCookie, bundle->_moduleCookie, bundle->_imageCookie);
@@ -4490,7 +4227,7 @@ __private_extern__ void _CFBundleDYLDUnloadBundle(CFBundleRef bundle) {
     }
 }
 
-__private_extern__ void *_CFBundleDYLDGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
+CF_PRIVATE void *_CFBundleDYLDGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
     return _CFBundleDYLDGetSymbolByNameWithSearch(bundle, symbolName, false);
 }
 
@@ -4536,7 +4273,7 @@ static void *_CFBundleDYLDGetSymbolByNameWithSearch(CFBundleRef bundle, CFString
 
 #if defined(BINARY_SUPPORT_DLFCN)
 
-__private_extern__ Boolean _CFBundleDlfcnCheckLoaded(CFBundleRef bundle) {
+CF_PRIVATE Boolean _CFBundleDlfcnCheckLoaded(CFBundleRef bundle) {
     if (!bundle->_isLoaded) {
         CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
         char buff[CFMaxPathSize];
@@ -4618,7 +4355,7 @@ CF_EXPORT Boolean _CFBundleDlfcnPreflight(CFBundleRef bundle, CFErrorRef *error)
     return retval;
 }
 
-__private_extern__ Boolean _CFBundleDlfcnLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) {
+CF_PRIVATE Boolean _CFBundleDlfcnLoadBundle(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error) {
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     if (!bundle->_isLoaded) {
         CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
@@ -4673,7 +4410,7 @@ __private_extern__ Boolean _CFBundleDlfcnLoadBundle(CFBundleRef bundle, Boolean
     return bundle->_isLoaded;
 }
 
-__private_extern__ Boolean _CFBundleDlfcnLoadFramework(CFBundleRef bundle, CFErrorRef *error) {
+CF_PRIVATE Boolean _CFBundleDlfcnLoadFramework(CFBundleRef bundle, CFErrorRef *error) {
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     if (!bundle->_isLoaded) {
         CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
@@ -4728,7 +4465,7 @@ __private_extern__ Boolean _CFBundleDlfcnLoadFramework(CFBundleRef bundle, CFErr
     return bundle->_isLoaded;
 }
 
-__private_extern__ void _CFBundleDlfcnUnload(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleDlfcnUnload(CFBundleRef bundle) {
     if (bundle->_isLoaded) {
 #if LOG_BUNDLE_LOAD
         printf("dlfcn unload bundle %p, handle %p module %p image %p\n", bundle, bundle->_handleCookie, bundle->_moduleCookie, bundle->_imageCookie);
@@ -4743,7 +4480,7 @@ __private_extern__ void _CFBundleDlfcnUnload(CFBundleRef bundle) {
     }
 }
 
-__private_extern__ void *_CFBundleDlfcnGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
+CF_PRIVATE void *_CFBundleDlfcnGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
     return _CFBundleDlfcnGetSymbolByNameWithSearch(bundle, symbolName, false);
 }
 
@@ -4781,7 +4518,7 @@ static CFStringRef _CFBundleDlfcnCopyLoadedImagePathForPointer(void *p) {
 
 #if defined(BINARY_SUPPORT_DLL)
 
-__private_extern__ Boolean _CFBundleDLLLoad(CFBundleRef bundle, CFErrorRef *error) {
+CF_PRIVATE Boolean _CFBundleDLLLoad(CFBundleRef bundle, CFErrorRef *error) {
     CFErrorRef localError = NULL;
     if (!bundle->_isLoaded) {
         CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
@@ -4811,7 +4548,7 @@ __private_extern__ Boolean _CFBundleDLLLoad(CFBundleRef bundle, CFErrorRef *erro
     return bundle->_isLoaded;
 }
 
-__private_extern__ void _CFBundleDLLUnload(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleDLLUnload(CFBundleRef bundle) {
     if (bundle->_isLoaded) {
        FreeLibrary(bundle->_hModule);
        bundle->_hModule = NULL;
@@ -4819,7 +4556,7 @@ __private_extern__ void _CFBundleDLLUnload(CFBundleRef bundle) {
     }
 }
 
-__private_extern__ void *_CFBundleDLLGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
+CF_PRIVATE void *_CFBundleDLLGetSymbolByName(CFBundleRef bundle, CFStringRef symbolName) {
     void *result = NULL;
     char buff[1024];
     if (CFStringGetCString(symbolName, buff, 1024, kCFStringEncodingWindowsLatin1)) result = GetProcAddress(bundle->_hModule, buff);
@@ -4830,50 +4567,6 @@ __private_extern__ void *_CFBundleDLLGetSymbolByName(CFBundleRef bundle, CFStrin
 
 /* Workarounds to be applied in the presence of certain bundles can go here. This is called on every bundle creation.
 */
-        
-// ZFH
-__private_extern__ CFStringRef _CFBundleGetBundlePath(CFBundleRef bundle){
-    return bundle->_bundleBasePath;
-}
-
-// caller need to release the table
-__private_extern__ CFDictionaryRef _CFBundleCopyQueryTable(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDirBuffer, CFIndex subDirLen)
-{
-    CFDictionaryRef subTable = NULL;
-    CFIndex savedResDirLen = resDirLen;
-    Boolean appendSucc = true;
-    
-    if (subDirLen > 0) {
-        appendSucc = _CFAppendPathComponent(resDir, &resDirLen, CFMaxPathSize, subDirBuffer, subDirLen);
-    }
-    
-    if (appendSucc) {
-        CFStringRef argDirStr = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, resDir, resDirLen, CFMaxPathSize, kCFAllocatorNull);
-        // take the lock 
-        if (bundle) {
-            __CFSpinLock(&bundle->_queryLock);
-            
-            // check if the query table for the given sub dir has been created
-            subTable = (CFDictionaryRef) CFDictionaryGetValue(bundle->_queryTable, argDirStr);
-            
-            if (!subTable) {
-                // create the query table for the given sub dir
-                subTable = _CFBundleCreateQueryTableAtPath(bundle, bundleURL, languages, resDir, savedResDirLen, subDirBuffer, subDirLen);
-                
-                CFDictionarySetValue(bundle->_queryTable, argDirStr, subTable);
-            } else {
-                CFRetain(subTable);
-            }
-            __CFSpinUnlock(&bundle->_queryLock);    
-        } else {
-            subTable = _CFBundleCreateQueryTableAtPath(NULL, bundleURL, languages, resDir, savedResDirLen, subDirBuffer, subDirLen);
-        }
-        CFRelease(argDirStr);
-    }
-    
-    return subTable;
-}
-
 
 
 
index 304ab6a1f9d45e3c0b640f3d9c38065fc21c31f5..99d33e2ad719e7b7d330a92ee9715fe1c82c1e84 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE__)
index 97b5402e4db42f37009b4583cbf44a2c8abf641b..b989e7aa8f3c56eeb1629fc2607b603d21e43966 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundlePriv.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLEPRIV__)
@@ -163,7 +163,7 @@ CFBundleRef _CFBundleCreateWithExecutableURLIfMightBeBundle(CFAllocatorRef alloc
 /* Functions for examining the structure of a bundle */
 
 CF_EXPORT
-CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle);
+CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle) CF_AVAILABLE_MAC(10_0);
 
 CF_EXPORT
 CFURLRef _CFBundleCopyInfoPlistURL(CFBundleRef bundle);
@@ -228,10 +228,10 @@ CF_EXPORT
 Boolean _CFBundleGetHasChanged(CFBundleRef bundle);
 
 CF_EXPORT
-void _CFBundleFlushCaches(void);
+void _CFBundleFlushCaches(void) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-void _CFBundleFlushCachesForURL(CFURLRef url);
+void _CFBundleFlushCachesForURL(CFURLRef url) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
 void _CFBundleFlushBundleCaches(CFBundleRef bundle);    // The previous two functions flush cached resource paths; this one also flushes bundle-specific caches such as the info dictionary and strings files
@@ -275,9 +275,6 @@ CFURLRef _CFBundleCopySharedSupportURL(CFBundleRef bundle);         // deprecated in fa
 CF_EXPORT
 CFURLRef _CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle);           // deprecated in favor of CFBundleCopyBuiltInPlugInsURL
 
-CF_EXPORT
-CFArrayRef _CFBundleCopyBundleRegionsArray(CFBundleRef bundle);                // deprecated in favor of CFBundleCopyBundleLocalizations
-
 CF_EXPORT
 CFURLRef _CFBundleCopyResourceURLForLanguage(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language);     // deprecated in favor of CFBundleCopyResourceURLForLocalization
 
index a85bae679ee9b5189cd4f37559e79c7acd0f3bdc..b1cc2383b5fa070bc6160130af8ae3b68dff7e3c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle_BinaryTypes.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE_BINARYTYPES__)
diff --git a/CFBundle_InfoPlist.c b/CFBundle_InfoPlist.c
new file mode 100644 (file)
index 0000000..f7d51a7
--- /dev/null
@@ -0,0 +1,822 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+//
+//  CFBundle_InfoPlist.c
+//  CoreFoundation
+//
+//  Created by Tony Parker on 5/30/12.
+//
+//
+
+#include <CoreFoundation/CFBundle.h>
+#include <CoreFoundation/CFNumber.h>
+#include "CFBundle_Internal.h"
+#include "CFByteOrder.h"
+#include "CFURLAccess.h"
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#include <dirent.h>
+#include <sys/sysctl.h>
+#endif
+
+// The following strings are initialized 'later' (i.e., not at static initialization time) because static init time is too early for CFSTR to work, on platforms without constant CF strings
+#if !__CONSTANT_STRINGS__
+
+#define _CFBundleNumberOfPlatforms 7
+static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
+static const char *_CFBundleSupportedPlatformStrings[_CFBundleNumberOfPlatforms] = { "iphoneos", "macos", "windows", "linux", "freebsd", "solaris", "hpux" };
+
+#define _CFBundleNumberOfProducts 3
+static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { NULL, NULL, NULL };
+static const char *_CFBundleSupportedProductStrings[_CFBundleNumberOfProducts] = { "iphone", "ipod", "ipad" };
+
+#define _CFBundleNumberOfiPhoneOSPlatformProducts 3
+static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { NULL, NULL, NULL };
+static const char *_CFBundleSupportediPhoneOSPlatformProductStrings[_CFBundleNumberOfiPhoneOSPlatformProducts] = { "iphone", "ipod", "ipad" };
+
+CF_PRIVATE void _CFBundleResourcesInitialize() {
+    for (unsigned int i = 0; i < _CFBundleNumberOfPlatforms; i++) _CFBundleSupportedPlatforms[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedPlatformStrings[i], kCFStringEncodingUTF8);
+    
+    for (unsigned int i = 0; i < _CFBundleNumberOfProducts; i++) _CFBundleSupportedProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedProductStrings[i], kCFStringEncodingUTF8);
+    
+    for (unsigned int i = 0; i < _CFBundleNumberOfiPhoneOSPlatformProducts; i++) _CFBundleSupportediPhoneOSPlatformProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportediPhoneOSPlatformProductStrings[i], kCFStringEncodingUTF8);
+}
+
+#else
+
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+// On iOS, we only support one platform
+#define _CFBundleNumberOfPlatforms 1
+static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { CFSTR("iphoneos") };
+#else
+// On other platforms, we support the following platforms
+#define _CFBundleNumberOfPlatforms 7
+static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { CFSTR("iphoneos"), CFSTR("macos"), CFSTR("windows"), CFSTR("linux"), CFSTR("freebsd"), CFSTR("solaris"), CFSTR("hpux") };
+#endif
+
+#define _CFBundleNumberOfProducts 3
+static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { CFSTR("iphone"), CFSTR("ipod"), CFSTR("ipad") };
+
+#define _CFBundleNumberOfiPhoneOSPlatformProducts 3
+static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { CFSTR("iphone"), CFSTR("ipod"), CFSTR("ipad") };
+
+CF_PRIVATE void _CFBundleResourcesInitialize() { }
+#endif
+
+#pragma mark -
+#pragma mark Product and Platform Getters - Exported
+
+static CFStringRef _cfBundlePlatform = NULL;
+CF_EXPORT void _CFSetProductName(CFStringRef str) {
+    // TODO: This should be removed. The "CLASSIC" check below removes the need to set the product name manually.
+    if (str) CFRetain(str);
+    _cfBundlePlatform = str;
+    // Note that the previous value is leaked, which is fine normally
+    // because the initial values would tend to be the constant strings
+    // below. That is required for thread-safety value due to the Get
+    // function [not being Copy]. It is also fine because people
+    // shouldn't be screwing around with this value casually.
+}
+
+CF_EXPORT CFStringRef _CFGetProductName(void) {
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    if (!_cfBundlePlatform) {
+        const char *isClassic = __CFgetenv("CLASSIC");
+        if (isClassic && strnlen(isClassic, 1) >= 1 && isClassic[0] == '1') {
+            _cfBundlePlatform = CFSTR("iphone");
+        } else {
+            char buffer[256];
+            memset(buffer, 0, sizeof(buffer));
+            size_t buflen = sizeof(buffer);
+            int ret = sysctlbyname("hw.machine", buffer, &buflen, NULL, 0);
+            if (0 == ret || (-1 == ret && ENOMEM == errno)) {
+                if (6 <= buflen && 0 == memcmp(buffer, "iPhone", 6)) {
+                    _cfBundlePlatform = CFSTR("iphone");
+                } else if (4 <= buflen && 0 == memcmp(buffer, "iPod", 4)) {
+                    _cfBundlePlatform = CFSTR("ipod");
+                } else if (4 <= buflen && 0 == memcmp(buffer, "iPad", 4)) {
+                    _cfBundlePlatform = CFSTR("ipad");
+                } else {
+                    const char *env = __CFgetenv("IPHONE_SIMULATOR_DEVICE");
+                    if (env) {
+                        if (0 == strcmp(env, "iPhone")) {
+                            _cfBundlePlatform = CFSTR("iphone");
+                        } else if (0 == strcmp(env, "iPad")) {
+                            _cfBundlePlatform = CFSTR("ipad");
+                        } else {
+                            // fallback, unrecognized IPHONE_SIMULATOR_DEVICE
+                        }
+                    } else {
+                        // fallback, unrecognized hw.machine and no IPHONE_SIMULATOR_DEVICE
+                    }
+                }
+            }
+        }
+        if (!_cfBundlePlatform) _cfBundlePlatform = CFSTR("iphone"); // fallback
+    }
+    return _cfBundlePlatform;
+#endif
+    return CFSTR("");
+}
+
+// All new-style bundles will have these extensions.
+CF_EXPORT CFStringRef _CFGetPlatformName(void) {
+#if DEPLOYMENT_TARGET_MACOSX 
+    return _CFBundleMacOSXPlatformName;
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    return _CFBundleiPhoneOSPlatformName;
+#elif DEPLOYMENT_TARGET_WINDOWS
+    return _CFBundleWindowsPlatformName;
+#elif DEPLOYMENT_TARGET_SOLARIS
+    return _CFBundleSolarisPlatformName;
+#elif DEPLOYMENT_TARGET_HPUX
+    return _CFBundleHPUXPlatformName;
+#elif DEPLOYMENT_TARGET_LINUX
+    return _CFBundleLinuxPlatformName;
+#elif DEPLOYMENT_TARGET_FREEBSD
+    return _CFBundleFreeBSDPlatformName;
+#else
+#error Unknown or unspecified DEPLOYMENT_TARGET
+#endif
+}
+
+CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return _CFBundleAlternateMacOSXPlatformName;
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    return _CFBundleMacOSXPlatformName;
+#elif DEPLOYMENT_TARGET_WINDOWS
+    return CFSTR("");
+#else
+#error Unknown or unspecified DEPLOYMENT_TARGET
+#endif
+}
+
+#pragma mark -
+#pragma mark Product and Platform Suffix Processing - Internal
+
+// TODO: Merge with below function, they do the same thing
+static Boolean _isValidPlatformSuffix(CFStringRef suffix) {
+    for (CFIndex idx = 0; idx < _CFBundleNumberOfPlatforms; idx++) {
+        if (CFEqual(suffix, _CFBundleSupportedPlatforms[idx])) return true;
+    }
+    return false;
+}
+
+// Returns true if the searchRange of the fileName is equal to a valid platform name (e.g., macos, iphoneos)
+CF_PRIVATE Boolean _CFBundleSupportedPlatformName(CFStringRef fileName, CFRange searchRange) {
+    for (CFIndex i = 0; i < _CFBundleNumberOfPlatforms; i++) {
+        if (CFStringFindWithOptions(fileName, _CFBundleSupportedPlatforms[i], searchRange, kCFCompareAnchored, NULL)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+// TODO: Merge with below function, they do the same thing
+static Boolean _isValidProductSuffix(CFStringRef suffix) {
+    for (CFIndex idx = 0; idx < _CFBundleNumberOfProducts; idx++) {
+        if (CFEqual(suffix, _CFBundleSupportedProducts[idx])) return true;
+    }
+    return false;
+}
+
+// Returns true if the searchRange of the fileName is equal to a a valid product name (e.g., ipod, ipad)
+CF_PRIVATE Boolean _CFBundleSupportedProductName(CFStringRef fileName, CFRange searchRange) {
+    for (CFIndex i = 0; i < _CFBundleNumberOfProducts; i++) {
+        if (CFStringFindWithOptions(fileName, _CFBundleSupportedProducts[i], searchRange, kCFCompareAnchored, NULL)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static Boolean _isValidiPhoneOSPlatformProductSuffix(CFStringRef suffix) {
+    for (CFIndex idx = 0; idx < _CFBundleNumberOfiPhoneOSPlatformProducts; idx++) {
+        if (CFEqual(suffix, _CFBundleSupportediPhoneOSPlatformProducts[idx])) return true;
+    }
+    return false;
+}
+
+static Boolean _isValidPlatformAndProductSuffixPair(CFStringRef platform, CFStringRef product) {
+    if (!platform && !product) return true;
+    if (!platform) {
+        return _isValidProductSuffix(product);
+    }
+    if (!product) {
+        return _isValidPlatformSuffix(platform);
+    }
+    if (CFEqual(platform, _CFBundleiPhoneOSPlatformName)) {
+        return _isValidiPhoneOSPlatformProductSuffix(product);
+    }
+    return false;
+}
+
+static Boolean _isBlacklistedKey(CFStringRef keyName) {
+#if __CONSTANT_STRINGS__
+#define _CFBundleNumberOfBlacklistedInfoDictionaryKeys 2
+    static const CFStringRef _CFBundleBlacklistedInfoDictionaryKeys[_CFBundleNumberOfBlacklistedInfoDictionaryKeys] = { CFSTR("CFBundleExecutable"), CFSTR("CFBundleIdentifier") };
+    
+    for (CFIndex idx = 0; idx < _CFBundleNumberOfBlacklistedInfoDictionaryKeys; idx++) {
+        if (CFEqual(keyName, _CFBundleBlacklistedInfoDictionaryKeys[idx])) return true;
+    }
+#endif
+    return false;
+}
+
+static Boolean _isOverrideKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFStringRef *outPlatformSuffix, CFStringRef *outProductSuffix) {
+    if (outBaseKey) {
+        *outBaseKey = NULL;
+    }
+    if (outPlatformSuffix) {
+        *outPlatformSuffix = NULL;
+    }
+    if (outProductSuffix) {
+        *outProductSuffix = NULL;
+    }
+    if (!fullKey)
+        return false;
+    CFRange minusRange = CFStringFind(fullKey, CFSTR("-"), kCFCompareBackwards);
+    CFRange tildeRange = CFStringFind(fullKey, CFSTR("~"), kCFCompareBackwards);
+    if (minusRange.location == kCFNotFound && tildeRange.location == kCFNotFound) return false;
+    // minus must come before tilde if both are present
+    if (minusRange.location != kCFNotFound && tildeRange.location != kCFNotFound && tildeRange.location <= minusRange.location) return false;
+    
+    CFIndex strLen = CFStringGetLength(fullKey);
+    CFRange baseKeyRange = (minusRange.location != kCFNotFound) ? CFRangeMake(0, minusRange.location) : CFRangeMake(0, tildeRange.location);
+    CFRange platformRange = CFRangeMake(kCFNotFound, 0);
+    CFRange productRange = CFRangeMake(kCFNotFound, 0);
+    if (minusRange.location != kCFNotFound) {
+        platformRange.location = minusRange.location + minusRange.length;
+        platformRange.length = ((tildeRange.location != kCFNotFound) ? tildeRange.location : strLen) - platformRange.location;
+    }
+    if (tildeRange.location != kCFNotFound) {
+        productRange.location = tildeRange.location + tildeRange.length;
+        productRange.length = strLen - productRange.location;
+    }
+    if (baseKeyRange.length < 1) return false;
+    if (platformRange.location != kCFNotFound && platformRange.length < 1) return false;
+    if (productRange.location != kCFNotFound && productRange.length < 1) return false;
+    
+    CFStringRef platform = (platformRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, platformRange) : NULL;
+    CFStringRef product = (productRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, productRange) : NULL;
+    Boolean result = _isValidPlatformAndProductSuffixPair(platform, product);
+    
+    if (result) {
+        if (outBaseKey) {
+            *outBaseKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fullKey, baseKeyRange);
+        }
+        if (outPlatformSuffix) {
+            *outPlatformSuffix = platform;
+        } else {
+            if (platform && !(0)) CFRelease(platform);
+        }
+        if (outProductSuffix) {
+            *outProductSuffix = product;
+        } else {
+            if (product && !(0)) CFRelease(product);
+        }
+    } else {
+        if (platform && !(0)) CFRelease(platform);
+        if (product && !(0)) CFRelease(product);
+    }
+    return result;
+}
+
+static Boolean _isCurrentPlatformAndProduct(CFStringRef platform, CFStringRef product) {
+    if (!platform && !product) return true;
+    if (!platform) {
+        return CFEqual(_CFGetProductName(), product);
+    }
+    if (!product) {
+        return CFEqual(_CFGetPlatformName(), platform);
+    }
+    
+    return CFEqual(_CFGetProductName(), product) && CFEqual(_CFGetPlatformName(), platform);
+}
+
+static CFArrayRef _CopySortedOverridesForBaseKey(CFStringRef keyName, CFDictionaryRef dict) {
+    CFMutableArrayRef overrides = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+    CFStringRef keyNameWithBoth = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@-%@~%@"), keyName, _CFGetPlatformName(), _CFGetProductName());
+    CFStringRef keyNameWithProduct = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@~%@"), keyName, _CFGetProductName());
+    CFStringRef keyNameWithPlatform = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@-%@"), keyName, _CFGetPlatformName());
+    
+    CFIndex count = CFDictionaryGetCount(dict);
+    
+    if (count > 0) {
+        CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), 0);
+        CFTypeRef *values = &(keys[count]);
+        
+        CFDictionaryGetKeysAndValues(dict, keys, values);
+        for (CFIndex idx = 0; idx < count; idx++) {
+            if (CFEqual(keys[idx], keyNameWithBoth)) {
+                CFArrayAppendValue(overrides, keys[idx]);
+                break;
+            }
+        }
+        for (CFIndex idx = 0; idx < count; idx++) {
+            if (CFEqual(keys[idx], keyNameWithProduct)) {
+                CFArrayAppendValue(overrides, keys[idx]);
+                break;
+            }
+        }
+        for (CFIndex idx = 0; idx < count; idx++) {
+            if (CFEqual(keys[idx], keyNameWithPlatform)) {
+                CFArrayAppendValue(overrides, keys[idx]);
+                break;
+            }
+        }
+        for (CFIndex idx = 0; idx < count; idx++) {
+            if (CFEqual(keys[idx], keyName)) {
+                CFArrayAppendValue(overrides, keys[idx]);
+                break;
+            }
+        }
+        
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, keys);
+    }
+    
+    CFRelease(keyNameWithProduct);
+    CFRelease(keyNameWithPlatform);
+    CFRelease(keyNameWithBoth);
+    
+    return overrides;
+}
+
+CF_PRIVATE void _CFBundleInfoPlistProcessInfoDictionary(CFMutableDictionaryRef dict) {    
+    CFIndex count = CFDictionaryGetCount(dict);
+    
+    if (count > 0) {
+        CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2 * count * sizeof(CFTypeRef), 0);
+        CFTypeRef *values = &(keys[count]);
+        CFMutableArrayRef guard = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+        
+        CFDictionaryGetKeysAndValues(dict, keys, values);
+        for (CFIndex idx = 0; idx < count; idx++) {
+            CFStringRef keyPlatformSuffix, keyProductSuffix, keyName;
+            if (_isOverrideKey((CFStringRef)keys[idx], &keyName, &keyPlatformSuffix, &keyProductSuffix)) {
+                CFArrayRef keysForBaseKey = NULL;
+                if (_isCurrentPlatformAndProduct(keyPlatformSuffix, keyProductSuffix) && !_isBlacklistedKey(keyName) && CFDictionaryContainsKey(dict, keys[idx])) {
+                    keysForBaseKey = _CopySortedOverridesForBaseKey(keyName, dict);
+                    CFIndex keysForBaseKeyCount = CFArrayGetCount(keysForBaseKey);
+                    
+                    //make sure the other keys for this base key don't get released out from under us until we're done
+                    CFArrayAppendValue(guard, keysForBaseKey); 
+                    
+                    //the winner for this base key will be sorted to the front, do the override with it
+                    CFTypeRef highestPriorityKey = CFArrayGetValueAtIndex(keysForBaseKey, 0);
+                    CFDictionarySetValue(dict, keyName, CFDictionaryGetValue(dict, highestPriorityKey));
+                    
+                    //remove everything except the now-overridden key; this will cause them to fail the CFDictionaryContainsKey(dict, keys[idx]) check in the enclosing if() and not be reprocessed
+                    for (CFIndex presentKeysIdx = 0; presentKeysIdx < keysForBaseKeyCount; presentKeysIdx++) {
+                        CFStringRef currentKey = (CFStringRef)CFArrayGetValueAtIndex(keysForBaseKey, presentKeysIdx);
+                        if (!CFEqual(currentKey, keyName))
+                            CFDictionaryRemoveValue(dict, currentKey);
+                    }
+                } else {
+                    CFDictionaryRemoveValue(dict, keys[idx]);
+                }
+                
+                
+                if (keyPlatformSuffix) CFRelease(keyPlatformSuffix);
+                if (keyProductSuffix) CFRelease(keyProductSuffix);
+                CFRelease(keyName);
+                if (keysForBaseKey) CFRelease(keysForBaseKey);
+            }
+        }
+        
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, keys);
+        CFRelease(guard);
+    }
+}
+
+#pragma mark -
+#pragma mark Info Plist Functions
+
+CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) {
+    CFDictionaryRef dict = NULL;
+    unsigned char buff[CFMaxPathSize];
+    uint8_t localVersion = 0;
+    
+    if (CFURLGetFileSystemRepresentation(url, true, buff, CFMaxPathSize)) {
+        CFURLRef newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true);
+        if (!newURL) newURL = (CFURLRef)CFRetain(url);
+
+        localVersion = _CFBundleGetBundleVersionForURL(newURL);
+        
+        dict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(alloc, newURL, localVersion);
+        CFRelease(newURL);
+    }
+    if (version) *version = localVersion;
+    return dict;
+}
+
+CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, uint8_t version) {
+    // We only return NULL for a bad URL, otherwise we create a dummy dictionary
+    if (!url) return NULL;
+
+    CFDictionaryRef result = NULL;    
+
+    // We're going to search for two files here - Info.plist and Info-macos.plist (platform specific). The platform-specific one takes precedence.
+    // First, construct the URL to the directory we'll search by using the passed in URL as a base
+    CFStringRef platformInfoURLFromBase = _CFBundlePlatformInfoURLFromBase0;
+    CFStringRef infoURLFromBase = _CFBundleInfoURLFromBase0;
+    CFURLRef directoryURL = NULL;
+    
+    if (0 == version) {
+        directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleResourcesURLFromBase0, url);
+        platformInfoURLFromBase = _CFBundlePlatformInfoURLFromBase0;
+        infoURLFromBase = _CFBundleInfoURLFromBase0;
+    } else if (1 == version) {
+        directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase1, url);
+        platformInfoURLFromBase = _CFBundlePlatformInfoURLFromBase1;
+        infoURLFromBase = _CFBundleInfoURLFromBase1;
+    } else if (2 == version) {
+        directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase2, url);
+        platformInfoURLFromBase = _CFBundlePlatformInfoURLFromBase2;
+        infoURLFromBase = _CFBundleInfoURLFromBase2;
+    } else if (3 == version) {
+        CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+        // this test is necessary to exclude the case where a bundle is spuriously created from the innards of another bundle
+        if (path) {
+            if (!(CFStringHasSuffix(path, _CFBundleSupportFilesDirectoryName1) || CFStringHasSuffix(path, _CFBundleSupportFilesDirectoryName2) || CFStringHasSuffix(path, _CFBundleResourcesDirectoryName))) {
+                directoryURL = (CFURLRef)CFRetain(url);
+                platformInfoURLFromBase = _CFBundlePlatformInfoURLFromBase3;
+                infoURLFromBase = _CFBundleInfoURLFromBase3;
+            }
+            CFRelease(path);
+        }
+    }
+    
+    CFURLRef absoluteURL;
+    if (directoryURL) {
+        absoluteURL = CFURLCopyAbsoluteURL(directoryURL);
+        CFStringRef directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+        CFRelease(absoluteURL);
+
+        __block CFURLRef infoPlistURL = NULL;
+        __block CFURLRef platformInfoPlistURL = NULL;
+
+        CFIndex infoPlistLength = CFStringGetLength(_CFBundleInfoPlistName);
+        CFIndex platformInfoPlistLength = CFStringGetLength(_CFBundlePlatformInfoPlistName);
+        
+        // Look inside this directory for the platform-specific and global Info.plist
+        // For compatability reasons, we support case-insensitive versions of Info.plist. That means that we must do a search of all the file names in the directory so we can compare. Otherwise, perhaps a couple of stats would be more efficient than the readdir.
+        _CFIterateDirectory(directoryPath, ^Boolean(CFStringRef fileName, uint8_t fileType) {            
+            // Only do the platform check on platforms where the string is different than the normal one
+            if (_CFBundlePlatformInfoPlistName != _CFBundleInfoPlistName) {
+                if (!platformInfoPlistURL && CFStringGetLength(fileName) == platformInfoPlistLength && CFStringCompareWithOptions(fileName, _CFBundlePlatformInfoPlistName, CFRangeMake(0, platformInfoPlistLength), kCFCompareCaseInsensitive | kCFCompareAnchored) == kCFCompareEqualTo) {
+                    // Make a URL out of this file
+                    platformInfoPlistURL = CFURLCreateWithString(kCFAllocatorSystemDefault, platformInfoURLFromBase, url);
+                }
+            }
+            
+            if (!infoPlistURL && CFStringGetLength(fileName) == infoPlistLength && CFStringCompareWithOptions(fileName, _CFBundleInfoPlistName, CFRangeMake(0, infoPlistLength), kCFCompareCaseInsensitive | kCFCompareAnchored) == kCFCompareEqualTo) {
+                // Make a URL out of this file
+                infoPlistURL = CFURLCreateWithString(kCFAllocatorSystemDefault, infoURLFromBase, url);
+            }
+            
+            // If by some chance we have both URLs, just bail early (or just the infoPlistURL on platforms that have no platform-specific name)
+            if (_CFBundlePlatformInfoPlistName != _CFBundleInfoPlistName) {
+                if (infoPlistURL && platformInfoPlistURL) return false;
+            } else {
+                if (infoPlistURL) return false;
+            }
+            
+            return true;
+        });
+        
+        CFRelease(directoryPath);
+        CFRelease(directoryURL);
+        
+        // Attempt to read in the data from the Info.plist we found - first the platform-specific one.
+        CFDataRef infoData = NULL;
+        CFURLRef finalInfoPlistURL = NULL;
+        if (platformInfoPlistURL) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+            CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, platformInfoPlistURL, &infoData, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
+            if (infoData) finalInfoPlistURL = platformInfoPlistURL;
+        }
+        
+        if (!infoData && infoPlistURL) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+            CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, infoPlistURL, &infoData, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
+            if (infoData) finalInfoPlistURL = infoPlistURL;
+        }
+        
+        if (infoData) {
+            CFErrorRef error = NULL;
+            result = (CFDictionaryRef)CFPropertyListCreateWithData(alloc, infoData, kCFPropertyListMutableContainers, NULL, &error);
+            if (result) {
+                if (CFDictionaryGetTypeID() == CFGetTypeID(result)) {
+                    CFDictionarySetValue((CFMutableDictionaryRef)result, _kCFBundleInfoPlistURLKey, finalInfoPlistURL);
+                } else {
+                    CFRelease(result);
+                    result = NULL;
+                }
+            } else if (error) {
+                CFDictionaryRef userInfo = CFErrorCopyUserInfo(error);
+                CFLog(kCFLogLevelError, CFSTR("There was an error parsing the Info.plist for the bundle at URL %@\n %@\n %@"), infoPlistURL, error, userInfo);
+                if (userInfo) CFRelease(userInfo);
+                CFRelease(error);
+            }
+            
+            if (!result) {
+                result = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                CFDictionarySetValue((CFMutableDictionaryRef)result, _kCFBundleRawInfoPlistURLKey, finalInfoPlistURL);
+            }
+            
+            CFRelease(infoData);
+        }
+        
+        if (platformInfoPlistURL) CFRelease(platformInfoPlistURL);
+        if (infoPlistURL) CFRelease(infoPlistURL);
+    }
+    
+    if (!result) {
+        result = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    }
+
+    // process ~ipad, ~iphone, etc.
+    _CFBundleInfoPlistProcessInfoDictionary((CFMutableDictionaryRef)result);
+        
+    return result;
+}
+
+CF_EXPORT CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url) {
+    CFDictionaryRef result = NULL;
+    Boolean isDir = false;
+    if (_CFIsResourceAtURL(url, &isDir)) {
+        if (isDir) {
+            result = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, NULL);
+        } else {
+            result = _CFBundleCopyInfoDictionaryInExecutable(url);
+        }
+    }
+    if (result && (0)) CFRetain(result); // conditionally put on a retain for a Copy function
+    return result;
+}
+
+static Boolean _CFBundleGetPackageInfoInDirectoryWithInfoDictionary(CFAllocatorRef alloc, CFURLRef url, CFDictionaryRef infoDict, UInt32 *packageType, UInt32 *packageCreator) {
+    Boolean retVal = false, hasType = false, hasCreator = false, releaseInfoDict = false;
+    CFURLRef tempURL;
+    CFDataRef pkgInfoData = NULL;
+    
+    // Check for a "real" new bundle
+    tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePkgInfoURLFromBase2, url);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+    CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
+    CFRelease(tempURL);
+    if (!pkgInfoData) {
+        tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePkgInfoURLFromBase1, url);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+        CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
+        CFRelease(tempURL);
+    }
+    if (!pkgInfoData) {
+        // Check for a "pseudo" new bundle
+        tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePseudoPkgInfoURLFromBase, url);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+        CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
+#pragma GCC diagnostic pop
+        CFRelease(tempURL);
+    }
+    
+    // Now, either we have a pkgInfoData or not.  If not, then is it because this is a new bundle without one (do we allow this?), or is it dbecause it is an old bundle.
+    // If we allow new bundles to not have a PkgInfo (because they already have the same data in the Info.plist), then we have to go read the info plist which makes failure expensive.
+    // drd: So we assume that a new bundle _must_ have a PkgInfo if they have this data at all, otherwise we manufacture it from the extension.
+    
+    if (pkgInfoData && CFDataGetLength(pkgInfoData) >= (int)(sizeof(UInt32) * 2)) {
+        UInt32 *pkgInfo = (UInt32 *)CFDataGetBytePtr(pkgInfoData);
+        if (packageType) *packageType = CFSwapInt32BigToHost(pkgInfo[0]);
+        if (packageCreator) *packageCreator = CFSwapInt32BigToHost(pkgInfo[1]);
+        retVal = hasType = hasCreator = true;
+    }
+    if (pkgInfoData) CFRelease(pkgInfoData);
+    if (!retVal) {
+        if (!infoDict) {
+            infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, NULL);
+            releaseInfoDict = true;
+        }
+        if (infoDict) {
+            CFStringRef typeString = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundlePackageTypeKey), creatorString = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleSignatureKey);
+            UInt32 tmp;
+            CFIndex usedBufLen = 0;
+            if (typeString && CFGetTypeID(typeString) == CFStringGetTypeID() && CFStringGetLength(typeString) == 4 && 4 == CFStringGetBytes(typeString, CFRangeMake(0, 4), kCFStringEncodingMacRoman, 0, false, (UInt8 *)&tmp, 4, &usedBufLen) && 4 == usedBufLen) {
+                if (packageType) *packageType = CFSwapInt32BigToHost(tmp);
+                retVal = hasType = true;
+            }
+            if (creatorString && CFGetTypeID(creatorString) == CFStringGetTypeID() && CFStringGetLength(creatorString) == 4 && 4 == CFStringGetBytes(creatorString, CFRangeMake(0, 4), kCFStringEncodingMacRoman, 0, false, (UInt8 *)&tmp, 4, &usedBufLen) && 4 == usedBufLen) {
+                if (packageCreator) *packageCreator = CFSwapInt32BigToHost(tmp);
+                retVal = hasCreator = true;
+            }
+            if (releaseInfoDict && !(0)) CFRelease(infoDict);
+        }
+    }
+    if (!hasType || !hasCreator) {
+        // If this looks like a bundle then manufacture the type and creator.
+        if (retVal || _CFBundleURLLooksLikeBundle(url)) {
+            if (packageCreator && !hasCreator) *packageCreator = 0x3f3f3f3f;  // '????'
+            if (packageType && !hasType) {
+                CFStringRef urlStr;
+                UniChar buff[CFMaxPathSize];
+                CFIndex strLen, startOfExtension;
+                CFURLRef absoluteURL;
+                
+                // Detect "app", "debug", "profile", or "framework" extensions
+                absoluteURL = CFURLCopyAbsoluteURL(url);
+                urlStr = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+                CFRelease(absoluteURL);
+                strLen = CFStringGetLength(urlStr);
+                if (strLen > CFMaxPathSize) strLen = CFMaxPathSize;
+                CFStringGetCharacters(urlStr, CFRangeMake(0, strLen), buff);
+                CFRelease(urlStr);
+                startOfExtension = _CFStartOfPathExtension(buff, strLen);
+                if ((strLen - startOfExtension == 4 || strLen - startOfExtension == 5) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'a' && buff[startOfExtension+2] == (UniChar)'p' && buff[startOfExtension+3] == (UniChar)'p' && (strLen - startOfExtension == 4 || buff[startOfExtension+4] == (UniChar)PATH_SEP)) {
+                    // This is an app
+                    *packageType = 0x4150504c;  // 'APPL'
+                } else if ((strLen - startOfExtension == 6 || strLen - startOfExtension == 7) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'d' && buff[startOfExtension+2] == (UniChar)'e' && buff[startOfExtension+3] == (UniChar)'b' && buff[startOfExtension+4] == (UniChar)'u' && buff[startOfExtension+5] == (UniChar)'g' && (strLen - startOfExtension == 6 || buff[startOfExtension+6] == (UniChar)PATH_SEP)) {
+                    // This is an app (debug version)
+                    *packageType = 0x4150504c;  // 'APPL'
+                } else if ((strLen - startOfExtension == 8 || strLen - startOfExtension == 9) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'p' && buff[startOfExtension+2] == (UniChar)'r' && buff[startOfExtension+3] == (UniChar)'o' && buff[startOfExtension+4] == (UniChar)'f' && buff[startOfExtension+5] == (UniChar)'i' && buff[startOfExtension+6] == (UniChar)'l' && buff[startOfExtension+7] == (UniChar)'e' && (strLen - startOfExtension == 8 || buff[startOfExtension+8] == (UniChar)PATH_SEP)) {
+                    // This is an app (profile version)
+                    *packageType = 0x4150504c;  // 'APPL'
+                } else if ((strLen - startOfExtension == 8 || strLen - startOfExtension == 9) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'s' && buff[startOfExtension+2] == (UniChar)'e' && buff[startOfExtension+3] == (UniChar)'r' && buff[startOfExtension+4] == (UniChar)'v' && buff[startOfExtension+5] == (UniChar)'i' && buff[startOfExtension+6] == (UniChar)'c' && buff[startOfExtension+7] == (UniChar)'e' && (strLen - startOfExtension == 8 || buff[startOfExtension+8] == (UniChar)PATH_SEP)) {
+                    // This is a service
+                    *packageType = 0x4150504c;  // 'APPL'
+                } else if ((strLen - startOfExtension == 10 || strLen - startOfExtension == 11) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'f' && buff[startOfExtension+2] == (UniChar)'r' && buff[startOfExtension+3] == (UniChar)'a' && buff[startOfExtension+4] == (UniChar)'m' && buff[startOfExtension+5] == (UniChar)'e' && buff[startOfExtension+6] == (UniChar)'w' && buff[startOfExtension+7] == (UniChar)'o' && buff[startOfExtension+8] == (UniChar)'r' && buff[startOfExtension+9] == (UniChar)'k' && (strLen - startOfExtension == 10 || buff[startOfExtension+10] == (UniChar)PATH_SEP)) {
+                    // This is a framework
+                    *packageType = 0x464d574b;  // 'FMWK'
+                } else {
+                    // Default to BNDL for generic bundle
+                    *packageType = 0x424e444c;  // 'BNDL'
+                }
+            }
+            retVal = true;
+        }
+    }
+    return retVal;
+}
+
+CF_EXPORT Boolean _CFBundleGetPackageInfoInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt32 *packageType, UInt32 *packageCreator) {
+    return _CFBundleGetPackageInfoInDirectoryWithInfoDictionary(alloc, url, NULL, packageType, packageCreator);
+}
+
+CF_EXPORT void CFBundleGetPackageInfo(CFBundleRef bundle, UInt32 *packageType, UInt32 *packageCreator) {
+    CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
+    if (!_CFBundleGetPackageInfoInDirectoryWithInfoDictionary(kCFAllocatorSystemDefault, bundleURL, CFBundleGetInfoDictionary(bundle), packageType, packageCreator)) {
+        if (packageType) *packageType = 0x424e444c;  // 'BNDL'
+        if (packageCreator) *packageCreator = 0x3f3f3f3f;  // '????'
+    }
+    if (bundleURL) CFRelease(bundleURL);
+}
+
+CF_EXPORT Boolean CFBundleGetPackageInfoInDirectory(CFURLRef url, UInt32 *packageType, UInt32 *packageCreator) {
+    return _CFBundleGetPackageInfoInDirectory(kCFAllocatorSystemDefault, url, packageType, packageCreator);
+}
+
+CFDictionaryRef CFBundleCopyInfoDictionaryInDirectory(CFURLRef url) {
+    CFDictionaryRef dict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, NULL);
+    return dict;
+}
+
+// The Info.plist should NOT be mutated after being created. If there is any fixing up of the info dictionary to do, do it here.
+// Call with bundle lock
+static void _CFBundleInfoPlistFixupInfoDictionary(CFBundleRef bundle, CFMutableDictionaryRef infoDict) {
+    // Version number
+    CFTypeRef unknownVersionValue = CFDictionaryGetValue(infoDict, _kCFBundleNumericVersionKey);
+    CFNumberRef versNum;
+    UInt32 vers = 0;
+    
+    if (!unknownVersionValue) unknownVersionValue = CFDictionaryGetValue(infoDict, kCFBundleVersionKey);
+    if (unknownVersionValue) {
+        if (CFGetTypeID(unknownVersionValue) == CFStringGetTypeID()) {
+            // Convert a string version number into a numeric one.
+            vers = _CFVersionNumberFromString((CFStringRef)unknownVersionValue);
+            
+            versNum = CFNumberCreate(CFGetAllocator(bundle), kCFNumberSInt32Type, &vers);
+            CFDictionarySetValue(infoDict, _kCFBundleNumericVersionKey, versNum);
+            CFRelease(versNum);
+        } else if (CFGetTypeID(unknownVersionValue) == CFNumberGetTypeID()) {
+            // Nothing to do here
+        } else {
+            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, _kCFBundleNumericVersionKey);
+        }
+    }    
+}
+
+CFDictionaryRef CFBundleGetInfoDictionary(CFBundleRef bundle) {
+    __CFSpinLock(&bundle->_lock);
+    if (!bundle->_infoDict) {
+        bundle->_infoDict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(kCFAllocatorSystemDefault, bundle->_url, bundle->_version);
+
+        // Add or fixup any keys that will be expected later
+        if (bundle->_infoDict) _CFBundleInfoPlistFixupInfoDictionary(bundle, (CFMutableDictionaryRef)bundle->_infoDict);
+    }
+    __CFSpinUnlock(&bundle->_lock);
+    
+    return bundle->_infoDict;
+}
+
+CFDictionaryRef _CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
+    return CFBundleGetLocalInfoDictionary(bundle);
+}
+
+CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
+    CFDictionaryRef localInfoDict = NULL;
+    __CFSpinLock(&bundle->_lock);
+    localInfoDict = bundle->_localInfoDict;    
+    if (!localInfoDict) {
+        // To avoid keeping the spin lock for too long, let go of it here while we create a new dictionary. We'll relock later to set the value. If it turns out that we have already created another local info dictionary in the meantime, then we'll take care of it then.
+        __CFSpinUnlock(&bundle->_lock);
+        CFURLRef url = CFBundleCopyResourceURL(bundle, _CFBundleLocalInfoName, _CFBundleStringTableType, NULL);
+        if (url) {
+            CFDataRef data;
+            SInt32 errCode;
+            CFStringRef errStr = NULL;
+            
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+            if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, url, &data, NULL, NULL, &errCode)) {
+                localInfoDict = (CFDictionaryRef)CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListMutableContainers, &errStr);
+                if (errStr) CFRelease(errStr);
+                if (localInfoDict && CFDictionaryGetTypeID() != CFGetTypeID(localInfoDict)) {
+                    CFRelease(localInfoDict);
+                    localInfoDict = NULL;
+                }
+                CFRelease(data);
+            }
+#pragma GCC diagnostic pop
+            CFRelease(url);
+        }
+        if (localInfoDict) _CFBundleInfoPlistProcessInfoDictionary((CFMutableDictionaryRef)localInfoDict);
+        // remain locked here until we exit the if statement.
+        __CFSpinLock(&bundle->_lock);
+        if (!bundle->_localInfoDict) {
+            // Still have no info dictionary, so set it
+            bundle->_localInfoDict = localInfoDict;
+        } else {
+            // Oops, some other thread created an info dictionary too. We'll just release this one and use that one.
+            if (localInfoDict) CFRelease(localInfoDict);
+            localInfoDict = bundle->_localInfoDict;
+        }
+    }
+    __CFSpinUnlock(&bundle->_lock);
+
+    return localInfoDict;
+}
+
+CFPropertyListRef _CFBundleGetValueForInfoKey(CFBundleRef bundle, CFStringRef key) {
+    return (CFPropertyListRef)CFBundleGetValueForInfoDictionaryKey(bundle, key);
+}
+
+CFTypeRef CFBundleGetValueForInfoDictionaryKey(CFBundleRef bundle, CFStringRef key) {
+    // Look in InfoPlist.strings first.  Then look in Info.plist
+    CFTypeRef result = NULL;
+    if (bundle && key) {
+        CFDictionaryRef dict = CFBundleGetLocalInfoDictionary(bundle);
+        if (dict) result = CFDictionaryGetValue(dict, key);
+        if (!result) {
+            dict = CFBundleGetInfoDictionary(bundle);
+            if (dict) result = CFDictionaryGetValue(dict, key);
+        }
+    }
+    return result;
+}
+
+CFStringRef CFBundleGetIdentifier(CFBundleRef bundle) {
+    CFStringRef bundleID = NULL;
+    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+    if (infoDict) bundleID = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleIdentifierKey);
+    return bundleID;
+}
index b612fd9eacdcf5e301789393cdb74fe926d699f4..1d1ca84d30e5209175f20a1585cf136fdbabeef9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle_Internal.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE_INTERNAL__)
@@ -54,9 +54,6 @@ CF_EXTERN_C_BEGIN
 #define CFBundleExecutableLoadError                 3587
 #define CFBundleExecutableLinkError                 3588
 
-// uncomment this to enable the new look up algorithm
-#define CFBUNDLE_NEWLOOKUP
-
 // uncomment this to enable the checking for 8302591
 //#define CFBUNDLE_NO_TRAVERSE_OUTSIDE
 
@@ -78,30 +75,93 @@ typedef struct __CFPlugInData {
     CFMutableArrayRef _factories;
 } _CFPlugInData;
 
+struct __CFBundle {
+    CFRuntimeBase _base;
+    
+    CFURLRef _url;
+    CFDateRef _modDate;
+    
+    __strong CFDictionaryRef _infoDict;
+    __strong CFDictionaryRef _localInfoDict;
+    CFArrayRef _searchLanguages;
+    
+    __CFPBinaryType _binaryType;
+    Boolean _isLoaded;
+    uint8_t _version;
+    Boolean _sharesStringsFiles;
+    char _padding[1];
+    
+    /* CFM goop */
+    void *_connectionCookie;
+    
+    /* DYLD goop */
+    const void *_imageCookie;
+    const void *_moduleCookie;
+    
+    /* dlfcn goop */
+    void *_handleCookie;
+    
+    /* CFM<->DYLD glue */
+    CFMutableDictionaryRef _glueDict;
+    
+    /* Resource fork goop */
+    _CFResourceData _resourceData;
+    
+    _CFPlugInData _plugInData;
+    
+    pthread_mutex_t _bundleLoadingLock;
+    
+    CFStringRef _executablePath; // Calculated and cached here
+    CFStringRef _developmentRegion; // Calculated and cached here
+    Boolean _developmentRegionCalculated;
+    
+    CFSpinLock_t _lock;
+    
+    CFArrayRef _localizations; // List of localizations, including the development language fallback if required
+    Boolean _lookedForLocalizations;
+    
+    CFMutableDictionaryRef _resourceDirectoryContents;
+    
+    CFSpinLock_t _queryLock;
+    CFMutableDictionaryRef _queryTable;
+    CFStringRef _bundleBasePath;
+    
+#if defined(BINARY_SUPPORT_DLL)
+    HMODULE _hModule;
+#endif /* BINARY_SUPPORT_DLL */
+    
+};
+
 extern _CFPlugInData *__CFBundleGetPlugInData(CFBundleRef bundle);
 
 /* Private CFBundle API */
 
+CF_PRIVATE void _CFBundleInfoPlistProcessInfoDictionary(CFMutableDictionaryRef dict);
+CF_PRIVATE Boolean _CFBundleSupportedProductName(CFStringRef fileName, CFRange searchRange);
+CF_PRIVATE Boolean _CFBundleSupportedPlatformName(CFStringRef fileName, CFRange searchRange);
+
+CF_EXPORT CFStringRef _CFGetProductName(void);
+CF_EXPORT CFStringRef _CFGetPlatformName(void);
+CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void);
+
 extern Boolean _CFIsResourceAtURL(CFURLRef url, Boolean *isDir);
 extern Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir);
 
-extern Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, UInt8 *version);
+CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url);
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt8 *version);
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, UInt8 version);
 extern CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFURLRef bundleURL, UInt8 version);
 extern CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, UInt8 version);
 
 extern Boolean _CFBundleCouldBeBundle(CFURLRef url);
-extern CFURLRef _CFBundleCopyResourceForkURLMayBeLocal(CFBundleRef bundle, Boolean mayBeLocal);
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInResourceForkWithAllocator(CFAllocatorRef alloc, CFURLRef url);
+CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict);
 #if DEPLOYMENT_TARGET_MACOSX
-__private_extern__ CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBundleRef bundle);
+CF_PRIVATE CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBundleRef bundle);
 #endif
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url);
 extern CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url);
 
-extern void _CFBundleAddPreferredLprojNamesInDirectory(CFAllocatorRef alloc, CFURLRef bundleURL, UInt8 version, CFDictionaryRef infoDict, CFMutableArrayRef lprojNames, CFStringRef devLang);
-
 extern CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void);
 extern CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void);
 extern CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void);
@@ -114,13 +174,9 @@ extern void _CFBundleScheduleForUnloading(CFBundleRef bundle);
 extern void _CFBundleUnscheduleForUnloading(CFBundleRef bundle);
 extern void _CFBundleUnloadScheduledBundles(void);
 
-__private_extern__ CFStringRef _CFBundleGetBundlePath(CFBundleRef bundle);
-__private_extern__ void _CFBundleSetResourceDir(UniChar *buffer, CFIndex *currLen, CFIndex maxLen, uint8_t version);
-__private_extern__ CFURLRef _CFBundleCopyResourceForkURLWithoutLocal(CFBundleRef bundle);
-__private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDir, CFIndex subDirLen);
-__private_extern__ CFDictionaryRef _CFBundleCopyQueryTable(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDirBuffer, CFIndex subDirLen);
-__private_extern__ CFArrayRef _CFFindBundleResourcesNoBlock(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef subDirName, CFArrayRef searchLanguages, CFStringRef resName, CFArrayRef resTypes, CFIndex limit, uint8_t version);
-__private_extern__ CFTypeRef _CFBundleCopyFindResourcesWithNoBlock(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized);
+CF_PRIVATE void _CFBundleAppendResourceDir(CFMutableStringRef path, uint8_t version);
+
+CF_PRIVATE UInt8 _CFBundleLayoutVersion(CFBundleRef bundle);
 
 #if defined(BINARY_SUPPORT_DYLD)
 // DYLD API
@@ -176,6 +232,14 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory);
 #define _CFBundleExecutablesDirectoryName CFSTR("Executables")
 #define _CFBundleNonLocalizedResourcesDirectoryName CFSTR("Non-localized Resources")
 
+#if DEPLOYMENT_TARGET_WINDOWS
+#define _CFBundleSupportFilesDirectoryName1WithResources CFSTR("Support Files\\Resources")
+#define _CFBundleSupportFilesDirectoryName2WithResources CFSTR("Contents\\Resources")
+#else
+#define _CFBundleSupportFilesDirectoryName1WithResources CFSTR("Support Files/Resources")
+#define _CFBundleSupportFilesDirectoryName2WithResources CFSTR("Contents/Resources")
+#endif
+
 #define _CFBundleSupportFilesURLFromBase1 CFSTR("Support%20Files/")
 #define _CFBundleSupportFilesURLFromBase2 CFSTR("Contents/")
 #define _CFBundleResourcesURLFromBase0 CFSTR("Resources/")
@@ -186,15 +250,42 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory);
 #define _CFBundleAppStoreReceiptURLFromBase2 CFSTR("Contents/_MASReceipt/receipt")
 #define _CFBundleExecutablesURLFromBase1 CFSTR("Support%20Files/Executables/")
 #define _CFBundleExecutablesURLFromBase2 CFSTR("Contents/")
+
 #define _CFBundleInfoURLFromBase0 CFSTR("Resources/Info.plist")
 #define _CFBundleInfoURLFromBase1 CFSTR("Support%20Files/Info.plist")
 #define _CFBundleInfoURLFromBase2 CFSTR("Contents/Info.plist")
 #define _CFBundleInfoURLFromBase3 CFSTR("Info.plist")
-#define _CFBundleInfoFileName CFSTR("Info.plist")
-#define _CFBundleInfoURLFromBaseNoExtension0 CFSTR("Resources/Info")
-#define _CFBundleInfoURLFromBaseNoExtension1 CFSTR("Support%20Files/Info")
-#define _CFBundleInfoURLFromBaseNoExtension2 CFSTR("Contents/Info")
 #define _CFBundleInfoURLFromBaseNoExtension3 CFSTR("Info")
+
+#if DEPLOYMENT_TARGET_MACOSX
+#define _CFBundlePlatformInfoURLFromBase0 CFSTR("Resources/Info-macos.plist")
+#define _CFBundlePlatformInfoURLFromBase1 CFSTR("Support%20Files/Info-macos.plist")
+#define _CFBundlePlatformInfoURLFromBase2 CFSTR("Contents/Info-macos.plist")
+#define _CFBundlePlatformInfoURLFromBase3 CFSTR("Info-macos.plist")
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#define _CFBundlePlatformInfoURLFromBase0 CFSTR("Resources/Info-iphoneos.plist")
+#define _CFBundlePlatformInfoURLFromBase1 CFSTR("Support%20Files/Info-iphoneos.plist")
+#define _CFBundlePlatformInfoURLFromBase2 CFSTR("Contents/Info-iphoneos.plist")
+#define _CFBundlePlatformInfoURLFromBase3 CFSTR("Info-iphoneos.plist")
+#else
+// No platform-specific variants in these cases
+#define _CFBundlePlatformInfoURLFromBase0 _CFBundleInfoURLFromBase0
+#define _CFBundlePlatformInfoURLFromBase1 _CFBundleInfoURLFromBase1
+#define _CFBundlePlatformInfoURLFromBase2 _CFBundleInfoURLFromBase2
+#define _CFBundlePlatformInfoURLFromBase3 _CFBundleInfoURLFromBase3
+#endif
+
+#define _CFBundleInfoPlistName CFSTR("Info.plist")
+
+#if DEPLOYMENT_TARGET_MACOSX
+#define _CFBundlePlatformInfoPlistName CFSTR("Info-macos.plist")
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#define _CFBundlePlatformInfoPlistName CFSTR("Info-iphoneos.plist")
+#else
+// No platform-specific Info.plist for these
+#define _CFBundlePlatformInfoPlistName _CFBundleInfoPlistName
+#endif
+
 #define _CFBundleInfoExtension CFSTR("plist")
 #define _CFBundleLocalInfoName CFSTR("InfoPlist")
 #define _CFBundlePkgInfoURLFromBase1 CFSTR("Support%20Files/PkgInfo")
@@ -246,12 +337,6 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory);
 
 #define _CFBundleWindowsResourceDirectoryExtension CFSTR("resources")
 
-/* Old platform names (no longer used) */
-#define _CFBundleMacOSXPlatformName_OLD CFSTR("macintosh")
-#define _CFBundleAlternateMacOSXPlatformName_OLD CFSTR("nextstep")
-#define _CFBundleWindowsPlatformName_OLD CFSTR("windows")
-#define _CFBundleAlternateWindowsPlatformName_OLD CFSTR("winnt")
-
 #define _CFBundleMacOSXInfoPlistPlatformName_OLD CFSTR("macos")
 #define _CFBundleWindowsInfoPlistPlatformName_OLD CFSTR("win32")
 
index 903cff6b92de7415690623acb7f06decf20e64a4..4bc74f5103792f8019ab56c07c3578088b2c2274 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 
 /*      CFBundle_Resources.c
-        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
-#define READ_DIRECTORIES_CACHE_CAPACITY 128
-
 #include "CFBundle_Internal.h"
 #include <CoreFoundation/CFURLAccess.h>
 #include <CoreFoundation/CFPropertyList.h>
 
 #endif
 
-CF_EXPORT bool CFDictionaryGetKeyIfPresent(CFDictionaryRef dict, const void *key, const void **actualkey);
-
-extern void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len);
-
-
-static inline Boolean _CFBundleSortedArrayContains(CFArrayRef arr, CFStringRef target) {
-    CFRange arrRange = CFRangeMake(0, CFArrayGetCount(arr));
-    CFIndex itemIdx = CFArrayBSearchValues(arr, arrRange, target, (CFComparatorFunction)CFStringCompare, NULL);
-    return itemIdx < arrRange.length && CFEqual(CFArrayGetValueAtIndex(arr, itemIdx), target);
-}
-
-// The following strings are initialized 'later' (i.e., not at static initialization time) because static init time is too early for CFSTR to work, on platforms without constant CF strings
-#if !__CONSTANT_STRINGS__
-
-#define _CFBundleNumberOfPlatforms 7
-static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static const char *_CFBundleSupportedPlatformStrings[_CFBundleNumberOfPlatforms] = { "iphoneos", "macos", "windows", "linux", "freebsd", "solaris", "hpux" };
-
-#define _CFBundleNumberOfProducts 3
-static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { NULL, NULL, NULL };
-static const char *_CFBundleSupportedProductStrings[_CFBundleNumberOfProducts] = { "iphone", "ipod", "ipad" };
-
-#define _CFBundleNumberOfiPhoneOSPlatformProducts 3
-static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { NULL, NULL, NULL };
-static const char *_CFBundleSupportediPhoneOSPlatformProductStrings[_CFBundleNumberOfiPhoneOSPlatformProducts] = { "iphone", "ipod", "ipad" };
-
-__private_extern__ void _CFBundleResourcesInitialize() {
-    for (unsigned int i = 0; i < _CFBundleNumberOfPlatforms; i++) _CFBundleSupportedPlatforms[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedPlatformStrings[i], kCFStringEncodingUTF8);
-    
-    for (unsigned int i = 0; i < _CFBundleNumberOfProducts; i++) _CFBundleSupportedProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportedProductStrings[i], kCFStringEncodingUTF8);
-    
-    for (unsigned int i = 0; i < _CFBundleNumberOfiPhoneOSPlatformProducts; i++) _CFBundleSupportediPhoneOSPlatformProducts[i] = CFStringCreateWithCString(kCFAllocatorSystemDefault, _CFBundleSupportediPhoneOSPlatformProductStrings[i], kCFStringEncodingUTF8);
-}
-
-#else
-
-#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-// On iOS, we only support one platform
-#define _CFBundleNumberOfPlatforms 1
-static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { CFSTR("iphoneos") };
-#else
-// On other platforms, we support the following platforms
-#define _CFBundleNumberOfPlatforms 7
-static CFStringRef _CFBundleSupportedPlatforms[_CFBundleNumberOfPlatforms] = { CFSTR("iphoneos"), CFSTR("macos"), CFSTR("windows"), CFSTR("linux"), CFSTR("freebsd"), CFSTR("solaris"), CFSTR("hpux") };
-#endif
-
-#define _CFBundleNumberOfProducts 3
-static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { CFSTR("iphone"), CFSTR("ipod"), CFSTR("ipad") };
-
-#define _CFBundleNumberOfiPhoneOSPlatformProducts 3
-static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { CFSTR("iphone"), CFSTR("ipod"), CFSTR("ipad") };
-
-__private_extern__ void _CFBundleResourcesInitialize() { }
-#endif
-
-static CFStringRef platform = NULL;
-
-void _CFSetProductName(CFStringRef str) {
-    if (str) CFRetain(str);
-    platform = str;
-    // Note that the previous value is leaked, which is fine normally
-    // because the initial values would tend to be the constant strings
-    // below. That is required for thread-safety value due to the Get
-    // function [not being Copy]. It is also fine because people
-    // shouldn't be screwing around with this value casually.
-}
-
-CF_EXPORT CFStringRef _CFGetProductName(void) {
-#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-   if (!platform) {
-      char buffer[256];
-      memset(buffer, 0, sizeof(buffer));
-      size_t buflen = sizeof(buffer);
-      int ret = sysctlbyname("hw.machine", buffer, &buflen, NULL, 0);
-      if (0 == ret || (-1 == ret && ENOMEM == errno)) {
-          if (6 <= buflen && 0 == memcmp(buffer, "iPhone", 6)) {
-              platform = CFSTR("iphone");
-          } else if (4 <= buflen && 0 == memcmp(buffer, "iPod", 4)) {
-              platform = CFSTR("ipod");
-          } else if (4 <= buflen && 0 == memcmp(buffer, "iPad", 4)) {
-              platform = CFSTR("ipad");
-          } else {
-              const char *env = __CFgetenv("IPHONE_SIMULATOR_DEVICE");
-              if (env) {
-                  if (0 == strcmp(env, "iPhone")) {
-                      platform = CFSTR("iphone");
-                  } else if (0 == strcmp(env, "iPad")) {
-                      platform = CFSTR("ipad");
-                  } else {
-                      // fallback, unrecognized IPHONE_SIMULATOR_DEVICE
-                  }
-              } else {
-                  // fallback, unrecognized hw.machine and no IPHONE_SIMULATOR_DEVICE
-              }
-          }
-      }
-      if (!platform) platform = CFSTR("iphone"); // fallback
-   }
-   return platform;
-#endif
-    return CFSTR("");
-}
-
-// All new-style bundles will have these extensions.
-CF_EXPORT CFStringRef _CFGetPlatformName(void) {
-#if DEPLOYMENT_TARGET_MACOSX 
-    return _CFBundleMacOSXPlatformName;
-#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    return _CFBundleiPhoneOSPlatformName;
-#elif DEPLOYMENT_TARGET_WINDOWS
-    return _CFBundleWindowsPlatformName;
-#elif DEPLOYMENT_TARGET_SOLARIS
-    return _CFBundleSolarisPlatformName;
-#elif DEPLOYMENT_TARGET_HPUX
-    return _CFBundleHPUXPlatformName;
-#elif DEPLOYMENT_TARGET_LINUX
-    return _CFBundleLinuxPlatformName;
-#elif DEPLOYMENT_TARGET_FREEBSD
-    return _CFBundleFreeBSDPlatformName;
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
-}
-
-CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void) {
-#if DEPLOYMENT_TARGET_MACOSX
-    return _CFBundleAlternateMacOSXPlatformName;
-#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    return _CFBundleMacOSXPlatformName;
-#elif DEPLOYMENT_TARGET_WINDOWS
-    return CFSTR("");
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
-}
-
-static UniChar *_AppSupportUniChars1 = NULL;
-static CFIndex _AppSupportLen1 = 0;
-static UniChar *_AppSupportUniChars2 = NULL;
-static CFIndex _AppSupportLen2 = 0;
-static UniChar *_ResourcesUniChars = NULL;
-static CFIndex _ResourcesLen = 0;
-static UniChar *_PlatformUniChars = NULL;
-static CFIndex _PlatformLen = 0;
-static UniChar *_AlternatePlatformUniChars = NULL;
-static CFIndex _AlternatePlatformLen = 0;
-static UniChar *_LprojUniChars = NULL;
-static CFIndex _LprojLen = 0;
-static UniChar *_BaseUniChars = NULL;
-static CFIndex _BaseLen;
-static UniChar *_GlobalResourcesUniChars = NULL;
-static CFIndex _GlobalResourcesLen = 0;
-static UniChar *_InfoExtensionUniChars = NULL;
-static CFIndex _InfoExtensionLen = 0;
-
-#if 0
-static UniChar _ResourceSuffix3[32];
-static CFIndex _ResourceSuffix3Len = 0;
-#endif
-static UniChar _ResourceSuffix2[16];
-static CFIndex _ResourceSuffix2Len = 0;
-static UniChar _ResourceSuffix1[16];
-static CFIndex _ResourceSuffix1Len = 0;
-
-static void _CFBundleInitStaticUniCharBuffers(void) {
-    CFStringRef appSupportStr1 = _CFBundleSupportFilesDirectoryName1;
-    CFStringRef appSupportStr2 = _CFBundleSupportFilesDirectoryName2;
-    CFStringRef resourcesStr = _CFBundleResourcesDirectoryName;
-    CFStringRef platformStr = _CFGetPlatformName();
-    CFStringRef alternatePlatformStr = _CFGetAlternatePlatformName();
-    CFStringRef lprojStr = _CFBundleLprojExtension;
-    CFStringRef globalResourcesStr = _CFBundleNonLocalizedResourcesDirectoryName;
-    CFStringRef infoExtensionStr = _CFBundleInfoExtension;
-    CFStringRef baseStr = _CFBundleBaseDirectory;
-
-    _AppSupportLen1 = CFStringGetLength(appSupportStr1);
-    _AppSupportLen2 = CFStringGetLength(appSupportStr2);
-    _ResourcesLen = CFStringGetLength(resourcesStr);
-    _PlatformLen = CFStringGetLength(platformStr);
-    _AlternatePlatformLen = CFStringGetLength(alternatePlatformStr);
-    _LprojLen = CFStringGetLength(lprojStr);
-    _GlobalResourcesLen = CFStringGetLength(globalResourcesStr);
-    _InfoExtensionLen = CFStringGetLength(infoExtensionStr);
-    _BaseLen = CFStringGetLength(baseStr);
-
-    _AppSupportUniChars1 = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * (_AppSupportLen1 + _AppSupportLen2 + _ResourcesLen + _PlatformLen + _AlternatePlatformLen + _LprojLen + _GlobalResourcesLen + _InfoExtensionLen + _BaseLen), 0);
-    _AppSupportUniChars2 = _AppSupportUniChars1 + _AppSupportLen1;
-    _ResourcesUniChars = _AppSupportUniChars2 + _AppSupportLen2;
-    _PlatformUniChars = _ResourcesUniChars + _ResourcesLen;
-    _AlternatePlatformUniChars = _PlatformUniChars + _PlatformLen;
-    _LprojUniChars = _AlternatePlatformUniChars + _AlternatePlatformLen;
-    _GlobalResourcesUniChars = _LprojUniChars + _LprojLen;
-    _InfoExtensionUniChars = _GlobalResourcesUniChars + _GlobalResourcesLen;
-    _BaseUniChars = _InfoExtensionUniChars + _InfoExtensionLen;
-    
-    if (_AppSupportLen1 > 0) CFStringGetCharacters(appSupportStr1, CFRangeMake(0, _AppSupportLen1), _AppSupportUniChars1);
-    if (_AppSupportLen2 > 0) CFStringGetCharacters(appSupportStr2, CFRangeMake(0, _AppSupportLen2), _AppSupportUniChars2);
-    if (_ResourcesLen > 0) CFStringGetCharacters(resourcesStr, CFRangeMake(0, _ResourcesLen), _ResourcesUniChars);
-    if (_PlatformLen > 0) CFStringGetCharacters(platformStr, CFRangeMake(0, _PlatformLen), _PlatformUniChars);
-    if (_AlternatePlatformLen > 0) CFStringGetCharacters(alternatePlatformStr, CFRangeMake(0, _AlternatePlatformLen), _AlternatePlatformUniChars);
-    if (_LprojLen > 0) CFStringGetCharacters(lprojStr, CFRangeMake(0, _LprojLen), _LprojUniChars);
-    if (_GlobalResourcesLen > 0) CFStringGetCharacters(globalResourcesStr, CFRangeMake(0, _GlobalResourcesLen), _GlobalResourcesUniChars);
-    if (_InfoExtensionLen > 0) CFStringGetCharacters(infoExtensionStr, CFRangeMake(0, _InfoExtensionLen), _InfoExtensionUniChars);
-    if (_BaseLen > 0) CFStringGetCharacters(baseStr, CFRangeMake(0, _BaseLen), _BaseUniChars);
-
-    _ResourceSuffix1Len = CFStringGetLength(platformStr);
-    if (_ResourceSuffix1Len > 0) _ResourceSuffix1[0] = '-';
-    if (_ResourceSuffix1Len > 0) CFStringGetCharacters(platformStr, CFRangeMake(0, _ResourceSuffix1Len), _ResourceSuffix1 + 1);
-    if (_ResourceSuffix1Len > 0) _ResourceSuffix1Len++;
-    CFStringRef productStr = _CFGetProductName();
-    if (CFEqual(productStr, CFSTR("ipod"))) { // For now, for resource lookups, hide ipod distinction and make it look for iphone resources
-        productStr = CFSTR("iphone");
-    }
-    _ResourceSuffix2Len = CFStringGetLength(productStr);
-    if (_ResourceSuffix2Len > 0) _ResourceSuffix2[0] = '~';
-    if (_ResourceSuffix2Len > 0) CFStringGetCharacters(productStr, CFRangeMake(0, _ResourceSuffix2Len), _ResourceSuffix2 + 1);
-    if (_ResourceSuffix2Len > 0) _ResourceSuffix2Len++;
-#if 0
-    if (_ResourceSuffix1Len > 1 && _ResourceSuffix2Len > 1) {
-        _ResourceSuffix3Len = _ResourceSuffix1Len + _ResourceSuffix2Len;
-        memmove(_ResourceSuffix3, _ResourceSuffix1, sizeof(UniChar) * _ResourceSuffix1Len);
-        memmove(_ResourceSuffix3 + _ResourceSuffix1Len, _ResourceSuffix2, sizeof(UniChar) * _ResourceSuffix2Len);
-    }
-#endif
-}
-
-CF_INLINE void _CFEnsureStaticBuffersInited(void) {
-    static dispatch_once_t once = 0;
-    dispatch_once(&once, ^{
-        _CFBundleInitStaticUniCharBuffers();
-    });
-}
-
-static CFSpinLock_t _cacheLock = CFSpinLockInit;
-static CFMutableDictionaryRef _contentsCache = NULL;
-static CFMutableDictionaryRef _directoryContentsCache = NULL;
-static CFMutableDictionaryRef _unknownContentsCache = NULL;
-
-typedef enum {
-    _CFBundleAllContents = 0,
-    _CFBundleDirectoryContents = 1,
-    _CFBundleUnknownContents = 2
-} _CFBundleDirectoryContentsType;
-
-extern void _CFArraySortValues(CFMutableArrayRef array, CFComparatorFunction comparator, void *context);
-
-static CFArrayRef _CFBundleCopySortedDirectoryContentsAtPath(CFStringRef path, _CFBundleDirectoryContentsType contentsType) {
-    CFArrayRef result = NULL;
-    
-    if (!path) {
-        // Return an empty result. It's mutable because the other arrays returned from this function are mutable, so may as well go for maximum compatibility.
-        result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        return result;
-    }
-
-    __CFSpinLock(&_cacheLock);
-    if (contentsType == _CFBundleUnknownContents) {
-        if (_unknownContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_unknownContentsCache, path);
-    } else if (contentsType == _CFBundleDirectoryContents) {
-        if (_directoryContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_directoryContentsCache, path);
-    } else {
-        if (_contentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_contentsCache, path);
-    }
-    if (result) CFRetain(result);
-    __CFSpinUnlock(&_cacheLock);
-
-    if (!result) {
-        Boolean tryToOpen = false, allDots = true;
-        char cpathBuff[CFMaxPathSize];
-        CFIndex cpathLen = 0, idx, lastSlashIdx = 0;
-        CFMutableArrayRef contents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks), directoryContents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks), unknownContents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        CFStringRef dirName, name;
-        
-        cpathBuff[0] = '\0';
-        if (CFStringGetFileSystemRepresentation(path, cpathBuff, CFMaxPathSize)) {
-            tryToOpen = true;
-            cpathLen = strlen(cpathBuff);
-            
-            // First see whether we already know that the directory doesn't exist
-            for (idx = cpathLen; lastSlashIdx == 0 && idx-- > 0;) {
-                if (cpathBuff[idx] == PATH_SEP) lastSlashIdx = idx;
-                else if (cpathBuff[idx] != '.') allDots = false;
-            }
-            if (lastSlashIdx > 0 && lastSlashIdx + 1 < cpathLen && !allDots) {
-                cpathBuff[lastSlashIdx] = '\0';
-                dirName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, cpathBuff);
-                if (dirName) {
-                    name = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, cpathBuff + lastSlashIdx + 1);
-                    if (name) {
-                        // ??? we might like to use _directoryContentsCache rather than _contentsCache here, but we cannot unless we resolve DT_LNKs below
-                        CFArrayRef dirDirContents = NULL;
-                        
-                        __CFSpinLock(&_cacheLock);
-                        if (_contentsCache) dirDirContents = (CFArrayRef)CFDictionaryGetValue(_contentsCache, dirName);
-                        if (dirDirContents) {
-                            Boolean foundIt = false;
-                            CFIndex dirDirIdx, dirDirLength = CFArrayGetCount(dirDirContents);
-                            for (dirDirIdx = 0; !foundIt && dirDirIdx < dirDirLength; dirDirIdx++) if (kCFCompareEqualTo == CFStringCompare(name, (CFStringRef)CFArrayGetValueAtIndex(dirDirContents, dirDirIdx), kCFCompareCaseInsensitive)) foundIt = true;
-                            if (!foundIt) tryToOpen = false;
-                        }
-                        __CFSpinUnlock(&_cacheLock);
-                        CFRelease(name);
-                    }
-                    CFRelease(dirName);
-                }
-                cpathBuff[lastSlashIdx] = PATH_SEP;
-            }
-        }
-#if DEPLOYMENT_TARGET_WINDOWS
-        // Make sure there is room for the additional space we need in the win32 api
-        if (tryToOpen && cpathLen + 2 < CFMaxPathSize) {
-            WIN32_FIND_DATAW file;
-            HANDLE handle;
-            
-            cpathBuff[cpathLen++] = '\\';
-            cpathBuff[cpathLen++] = '*';
-            cpathBuff[cpathLen] = '\0';
-            
-            // Convert UTF8 buffer to windows appropriate UTF-16LE
-            // Get the real length of the string in UTF16 characters
-            CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, cpathBuff, kCFStringEncodingUTF8);
-            cpathLen = CFStringGetLength(cfStr);
-            // Allocate a wide buffer to hold the converted string, including space for a NULL terminator
-            wchar_t *wideBuf = (wchar_t *)malloc((cpathLen + 1) * sizeof(wchar_t));
-            // Copy the string into the buffer and terminate
-            CFStringGetCharacters(cfStr, CFRangeMake(0, cpathLen), (UniChar *)wideBuf);
-            wideBuf[cpathLen] = 0;
-            CFRelease(cfStr);
-            
-            handle = FindFirstFileW(wideBuf, (LPWIN32_FIND_DATAW)&file);
-            if (handle != INVALID_HANDLE_VALUE) {
-                do {
-                    CFIndex nameLen = wcslen(file.cFileName);
-                    if (0 == nameLen || ('.' == file.cFileName[0] && (1 == nameLen || (2 == nameLen && '.' == file.cFileName[1]) || '_' == file.cFileName[1]))) continue;
-                    name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)file.cFileName, nameLen * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
-                    if (name) {
-                        CFArrayAppendValue(contents, name);
-                        if (file.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY) {
-                            CFArrayAppendValue(directoryContents, name);
-                        } /* else if (file.dwFileAttributes == DT_UNKNOWN) {
-                            CFArrayAppendValue(unknownContents, name);
-                        } */
-                        CFRelease(name);
-                    }
-                } while (FindNextFileW(handle, &file));
-                
-                FindClose(handle);
-            }
-            free(wideBuf);
-        }
-#else
-        DIR *dirp = NULL;
-        struct dirent *dent;
-        if (tryToOpen && (dirp = opendir(cpathBuff))) {
-            while ((dent = readdir(dirp))) {
-                CFIndex nameLen = dent->d_namlen;
-                if (0 == nameLen || 0 == dent->d_fileno || ('.' == dent->d_name[0] && (1 == nameLen || (2 == nameLen && '.' == dent->d_name[1]) || '_' == dent->d_name[1]))) continue;
-                name = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, dent->d_name);
-                if (name) {
-                    // ??? should we follow links for DT_LNK?  unless we do, results are approximate, but for performance reasons we do not
-                    // ??? likewise for DT_UNKNOWN
-                    // ??? the utility of distinguishing directories from other contents is somewhat doubtful anyway
-                    CFArrayAppendValue(contents, name);
-                    if (dent->d_type == DT_DIR) {
-                        CFArrayAppendValue(directoryContents, name);
-                    } else if (dent->d_type == DT_UNKNOWN) {
-                        CFArrayAppendValue(unknownContents, name);
-                    }
-                    CFRelease(name);
-                }
-            }
-            (void)closedir(dirp);
-        }
-#endif
-        
-        _CFArraySortValues(contents, (CFComparatorFunction)CFStringCompare, NULL);
-        _CFArraySortValues(directoryContents, (CFComparatorFunction)CFStringCompare, NULL);
-        _CFArraySortValues(unknownContents, (CFComparatorFunction)CFStringCompare, NULL);
-        
-        __CFSpinLock(&_cacheLock);
-        if (!_contentsCache) _contentsCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, READ_DIRECTORIES_CACHE_CAPACITY, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-        if (READ_DIRECTORIES_CACHE_CAPACITY <= CFDictionaryGetCount(_contentsCache)) CFDictionaryRemoveAllValues(_contentsCache);
-        CFDictionaryAddValue(_contentsCache, path, contents);
-
-        if (!_directoryContentsCache) _directoryContentsCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, READ_DIRECTORIES_CACHE_CAPACITY, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-        if (READ_DIRECTORIES_CACHE_CAPACITY <= CFDictionaryGetCount(_directoryContentsCache)) CFDictionaryRemoveAllValues(_directoryContentsCache);
-        CFDictionaryAddValue(_directoryContentsCache, path, directoryContents);
-
-        if (!_unknownContentsCache) _unknownContentsCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, READ_DIRECTORIES_CACHE_CAPACITY, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-        if (READ_DIRECTORIES_CACHE_CAPACITY <= CFDictionaryGetCount(_unknownContentsCache)) CFDictionaryRemoveAllValues(_unknownContentsCache);
-        CFDictionaryAddValue(_unknownContentsCache, path, unknownContents);
-
-        if (contentsType == _CFBundleUnknownContents) {
-            result = (CFArrayRef)CFRetain(unknownContents);
-        } else if (contentsType == _CFBundleDirectoryContents) {
-            result = (CFArrayRef)CFRetain(directoryContents);
-        } else {
-            result = (CFArrayRef)CFRetain(contents);
-        }
-        
-        CFRelease(contents);
-        CFRelease(directoryContents);
-        CFRelease(unknownContents);
-        __CFSpinUnlock(&_cacheLock);
-    }
-    return result;
-}
-
-static void _CFBundleFlushContentsCaches(void) {
-    __CFSpinLock(&_cacheLock);
-    if (_contentsCache) CFDictionaryRemoveAllValues(_contentsCache);
-    if (_directoryContentsCache) CFDictionaryRemoveAllValues(_directoryContentsCache);
-    if (_unknownContentsCache) CFDictionaryRemoveAllValues(_unknownContentsCache);
-    __CFSpinUnlock(&_cacheLock);
-}
-
-static void _CFBundleFlushContentsCacheForPath(CFMutableDictionaryRef cache, CFStringRef path) {
-    CFStringRef keys[READ_DIRECTORIES_CACHE_CAPACITY];
-    unsigned i, count = CFDictionaryGetCount(cache);
-    if (count <= READ_DIRECTORIES_CACHE_CAPACITY) {
-        CFDictionaryGetKeysAndValues(cache, (const void **)keys, NULL);
-        for (i = 0; i < count; i++) {
-            if (CFStringFindWithOptions(keys[i], path, CFRangeMake(0, CFStringGetLength(keys[i])), kCFCompareAnchored|kCFCompareCaseInsensitive, NULL)) CFDictionaryRemoveValue(cache, keys[i]);
-        }
-    }
-}
-
-static void _CFBundleFlushContentsCachesForPath(CFStringRef path) {
-    __CFSpinLock(&_cacheLock);
-    if (_contentsCache) _CFBundleFlushContentsCacheForPath(_contentsCache, path);
-    if (_directoryContentsCache) _CFBundleFlushContentsCacheForPath(_directoryContentsCache, path);
-    if (_unknownContentsCache) _CFBundleFlushContentsCacheForPath(_unknownContentsCache, path);
-    __CFSpinUnlock(&_cacheLock);
-}
+#pragma mark -
+#pragma mark Directory Contents and Caches
 
-CF_EXPORT void _CFBundleFlushCachesForURL(CFURLRef url) {
-    CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
-    CFStringRef path = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-    _CFBundleFlushContentsCachesForPath(path);
-    CFRelease(path);
-    CFRelease(absoluteURL);
-}
+// These are here for compatibility, but they do nothing anymore
+CF_EXPORT void _CFBundleFlushCachesForURL(CFURLRef url) { }
+CF_EXPORT void _CFBundleFlushCaches(void) { }
 
-CF_EXPORT void _CFBundleFlushCaches(void) {
-    _CFBundleFlushContentsCaches();
-}
+#pragma mark -
+#pragma mark Resource URL Lookup
 
 static inline Boolean _CFIsResourceCommon(char *path, Boolean *isDir) {
     Boolean exists;
@@ -531,608 +92,58 @@ static inline Boolean _CFIsResourceCommon(char *path, Boolean *isDir) {
     return false;
 }
 
-__private_extern__ Boolean _CFIsResourceAtURL(CFURLRef url, Boolean *isDir) {
+CF_PRIVATE Boolean _CFIsResourceAtURL(CFURLRef url, Boolean *isDir) {
     char path[CFMaxPathSize];
     if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathLength)) return false;
     
     return _CFIsResourceCommon(path, isDir);
 }
 
-__private_extern__ Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir) {
+CF_PRIVATE Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir) {
     char pathBuf[CFMaxPathSize];
     if (!CFStringGetFileSystemRepresentation(path, pathBuf, CFMaxPathSize)) return false;
     
     return _CFIsResourceCommon(pathBuf, isDir);
 }
 
-__private_extern__ void _CFBundleSetResourceDir(UniChar *buffer, CFIndex *currLen, CFIndex maxLen, uint8_t version){
+
+static CFStringRef _CFBundleGetResourceDirForVersion(uint8_t version) {
     if (1 == version) {
-        _CFAppendPathComponent(buffer, currLen, maxLen, _AppSupportUniChars1, _AppSupportLen1);
+        return _CFBundleSupportFilesDirectoryName1WithResources;
     } else if (2 == version) {
-        _CFAppendPathComponent(buffer, currLen, maxLen, _AppSupportUniChars2, _AppSupportLen2);
-    }
-    if (0 == version || 1 == version || 2 == version) _CFAppendPathComponent(buffer, currLen, maxLen, _ResourcesUniChars, _ResourcesLen);
-}
-
-static CFArrayRef _CFCopyTypesForSearchBundleDirectory(CFAllocatorRef alloc, UniChar *pathUniChars, CFIndex pathLen, UniChar *nameUniChars, CFIndex nameLen, CFArrayRef resTypes, CFMutableStringRef cheapStr, CFMutableStringRef tmpString, uint8_t version) {
-    CFMutableArrayRef result = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
-    CFArrayRef contents;
-    CFRange contentsRange, resultRange = CFRangeMake(0, 0);
-    CFIndex dirPathLen = pathLen, numResTypes = CFArrayGetCount(resTypes), i, j;
-    
-    CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, dirPathLen, dirPathLen);
-    CFStringReplaceAll(cheapStr, tmpString);
-    //fprintf(stderr, "looking in ");CFShow(cheapStr);
-    contents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleAllContents);
-    contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-    
-    CFStringSetExternalCharactersNoCopy(tmpString, nameUniChars, nameLen, nameLen);
-    CFStringReplaceAll(cheapStr, tmpString);
-    for (i = 0; i < contentsRange.length; i++) {
-        CFStringRef content = (CFStringRef)CFArrayGetValueAtIndex(contents, i);
-        if (CFStringHasPrefix(content, cheapStr)) {
-            //fprintf(stderr, "found ");CFShow(content);
-            for (j = 0; j < numResTypes; j++) {
-                CFStringRef resType = (CFStringRef)CFArrayGetValueAtIndex(resTypes, j);
-                if (!CFArrayContainsValue(result, resultRange, resType) && CFStringHasSuffix(content, resType)) {
-                    CFArrayAppendValue(result, resType);
-                    resultRange.length = CFArrayGetCount(result);
-                }
-            }
-        }
-    }
-    //fprintf(stderr, "result ");CFShow(result);
-    CFRelease(contents);
-    return result;
-}
-
-#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-static void _CFSearchBundleDirectory2(CFAllocatorRef alloc, CFMutableArrayRef result, UniChar *pathUniChars, CFIndex pathLen, UniChar *nameUniChars, CFIndex nameLen, UniChar *typeUniChars, CFIndex typeLen, CFMutableStringRef cheapStr, CFMutableStringRef tmpString, uint8_t version) {
-    // pathUniChars is the full path to the directory we are searching.
-    // nameUniChars is what we are looking for.
-    // typeUniChars is the type we are looking for.
-    // platformUniChars is the platform name.
-    // cheapStr is available for our use for whatever we want.
-    // URLs for found resources get added to result.
-
-    Boolean appendSucceeded = true;
-    if (nameLen > 0) appendSucceeded = _CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, nameUniChars, nameLen);
-    if (! appendSucceeded) return;
-    CFIndex savedPathLen = pathLen;
-
-    // Try in order:
-    // NAME-PLATFORM~PRODUCT.TYPE (disabled for now)
-    // NAME~PRODUCT.TYPE
-    // NAME-PLATFORM.TYPE (disabled for now)
-    // NAME.TYPE
-
-#if 0
-    appendSucceeded = (pathLen + _ResourceSuffix3Len < CFMaxPathSize);
-    if (appendSucceeded) {
-        memmove(pathUniChars + pathLen, _ResourceSuffix3, _ResourceSuffix3Len * sizeof(UniChar));
-        pathLen += _ResourceSuffix3Len;
-    }
-    if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-    if (appendSucceeded) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        Boolean Found = false, IsDir = false;
-        Found = _CFIsResourceAtPath(cheapStr, &IsDir);
-        if (Found) {
-            CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, IsDir);
-            CFArrayAppendValue(result, url);
-            CFRelease(url);
-            return;
-        }
-    }
-#endif
-
-    pathLen = savedPathLen;
-    appendSucceeded = (pathLen + _ResourceSuffix2Len < CFMaxPathSize);
-    if (appendSucceeded) {
-        memmove(pathUniChars + pathLen, _ResourceSuffix2, _ResourceSuffix2Len * sizeof(UniChar));
-        pathLen += _ResourceSuffix2Len;
-    }
-    if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-    if (appendSucceeded) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        Boolean Found = false, IsDir = false;
-        Found = _CFIsResourceAtPath(cheapStr, &IsDir);
-        if (Found) {
-            CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, IsDir);
-            CFArrayAppendValue(result, url);
-            CFRelease(url);
-            return;
-        }
-    }
-
-#if 0
-    pathLen = savedPathLen;
-    appendSucceeded = (pathLen + _ResourceSuffix1Len < CFMaxPathSize);
-    if (appendSucceeded) {
-        memmove(pathUniChars + pathLen, _ResourceSuffix1, _ResourceSuffix1Len * sizeof(UniChar));
-        pathLen += _ResourceSuffix1Len;
-    }
-    if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-    if (appendSucceeded) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        Boolean Found = false, IsDir = false;
-        Found = _CFIsResourceAtPath(cheapStr, &IsDir);
-        if (Found) {
-            CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, IsDir);
-            CFArrayAppendValue(result, url);
-            CFRelease(url);
-            return;
-        }
-    }
-#endif
-
-    pathLen = savedPathLen;
-    appendSucceeded = true;
-    if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-    if (appendSucceeded) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        Boolean Found = false, IsDir = false;
-        Found = _CFIsResourceAtPath(cheapStr, &IsDir);
-        if (Found) {
-            CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, IsDir);
-            CFArrayAppendValue(result, url);
-            CFRelease(url);
-            return;
-        }
-    }
-}
-#endif
-
-static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef result, UniChar *pathUniChars, CFIndex pathLen, UniChar *nameUniChars, CFIndex nameLen, UniChar *typeUniChars, CFIndex typeLen, CFMutableStringRef cheapStr, CFMutableStringRef tmpString, uint8_t version) {
-
-#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    _CFSearchBundleDirectory2(alloc, result, pathUniChars, pathLen, nameUniChars, nameLen, typeUniChars, typeLen, cheapStr, tmpString, version);
-#else
-    // pathUniChars is the full path to the directory we are searching.
-    // nameUniChars is what we are looking for.
-    // typeUniChars is the type we are looking for.
-    // platformUniChars is the platform name.
-    // cheapStr is available for our use for whatever we want.
-    // URLs for found resources get added to result.
-    CFIndex savedPathLen;
-    Boolean appendSucceeded = true, platformGenericFound = false, platformSpecificFound = false, platformGenericIsDir = false, platformSpecificIsDir = false;
-    Boolean platformGenericIsUnknown = false, platformSpecificIsUnknown = false; 
-    CFStringRef platformGenericStr = NULL;
-
-    CFIndex dirPathLen = pathLen;
-    CFArrayRef contents, directoryContents, unknownContents;
-    CFRange contentsRange, directoryContentsRange, unknownContentsRange;
-    
-    CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, dirPathLen, dirPathLen);
-    CFStringReplaceAll(cheapStr, tmpString);
-    //fprintf(stderr, "looking in ");CFShow(cheapStr);
-    contents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleAllContents);
-    contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-    directoryContents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleDirectoryContents);
-    directoryContentsRange = CFRangeMake(0, CFArrayGetCount(directoryContents));
-    unknownContents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleUnknownContents);
-    unknownContentsRange = CFRangeMake(0, CFArrayGetCount(unknownContents));
-    
-    if (nameLen > 0) appendSucceeded = _CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, nameUniChars, nameLen);
-    savedPathLen = pathLen;
-    if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-    if (appendSucceeded) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + dirPathLen + 1, pathLen - dirPathLen - 1, pathLen - dirPathLen - 1);
-        CFStringReplaceAll(cheapStr, tmpString);
-        platformGenericFound = _CFBundleSortedArrayContains(contents, cheapStr);
-        platformGenericIsDir = _CFBundleSortedArrayContains(directoryContents, cheapStr);
-        platformGenericIsUnknown =  _CFBundleSortedArrayContains(unknownContents, cheapStr);
-        //fprintf(stderr, "looking for ");CFShow(cheapStr);if (platformGenericFound) fprintf(stderr, "found it\n"); if (platformGenericIsDir) fprintf(stderr, "a directory\n");
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        if (platformGenericFound && platformGenericIsUnknown) {
-            (void)_CFIsResourceAtPath(cheapStr, &platformGenericIsDir);
-            //if (platformGenericIsDir) fprintf(stderr, "a directory after all\n"); else fprintf(stderr, "not a directory after all\n"); 
-        }
-    }
-    
-    // Check for platform specific.
-    if (platformGenericFound) {
-        platformGenericStr = (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, cheapStr);
-        if (!platformSpecificFound && (_PlatformLen > 0)) {
-            pathLen = savedPathLen;
-            pathUniChars[pathLen++] = (UniChar)'-';
-            memmove(pathUniChars + pathLen, _PlatformUniChars, _PlatformLen * sizeof(UniChar));
-            pathLen += _PlatformLen;
-            if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
-            if (appendSucceeded) {
-                CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + dirPathLen + 1, pathLen - dirPathLen - 1, pathLen - dirPathLen - 1);
-                CFStringReplaceAll(cheapStr, tmpString);
-                platformSpecificFound = _CFBundleSortedArrayContains(contents, cheapStr);
-                platformSpecificIsDir = _CFBundleSortedArrayContains(directoryContents, cheapStr);
-                platformSpecificIsUnknown = _CFBundleSortedArrayContains(unknownContents, cheapStr);
-                //fprintf(stderr, "looking for ");CFShow(cheapStr);if (platformSpecificFound) fprintf(stderr, "found it\n"); if (platformSpecificIsDir) fprintf(stderr, "a directory\n");
-                CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-                CFStringReplaceAll(cheapStr, tmpString);
-                if (platformSpecificFound && platformSpecificIsUnknown) {
-                    (void)_CFIsResourceAtPath(cheapStr, &platformSpecificIsDir);
-                    //if (platformSpecificIsDir) fprintf(stderr, "a directory after all\n"); else fprintf(stderr, "not a directory after all\n"); 
-                }
-            }
-        }
-    }
-    if (platformSpecificFound) {
-        CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, platformSpecificIsDir);
-        CFArrayAppendValue(result, url);
-        CFRelease(url);
-    } else if (platformGenericFound) {
-        CFURLRef url = CFURLCreateWithFileSystemPath(alloc, platformGenericStr ? platformGenericStr : cheapStr, PLATFORM_PATH_STYLE, platformGenericIsDir);
-        CFArrayAppendValue(result, url);
-        CFRelease(url);
-    }
-    if (platformGenericStr) CFRelease(platformGenericStr);
-    CFRelease(contents);
-    CFRelease(directoryContents);
-    CFRelease(unknownContents);
-#endif
-}
-
-static void _CFSearchBundleDirectoryWithPredicate(CFAllocatorRef alloc, CFMutableArrayRef result, UniChar *pathUniChars, CFIndex dirPathLen, Boolean (^predicate)(CFStringRef filename, Boolean *stop), CFMutableStringRef cheapStr, CFMutableStringRef tmpString, Boolean *stopLooking, uint8_t version) {
-
-    // pathUniChars is the full path to the directory we are searching.
-    // platformUniChars is the platform name.
-    // predicate is a block that evaluates a given filename to see if it's a match.
-    // cheapStr is available for our use for whatever we want.
-    // URLs for found resources get added to result.
-    
-    // get the contents of the directory
-    CFArrayRef contents, directoryContents, unknownContents;
-    CFRange contentsRange;
-    
-    CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, dirPathLen, dirPathLen);
-    CFStringReplaceAll(cheapStr, tmpString);
-    
-    if (!_CFAppendTrailingPathSlash(pathUniChars, &dirPathLen, CFMaxPathSize)) {
-        return;
-    }
-    
-    //fprintf(stderr, "looking in ");CFShow(cheapStr);
-    contents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleAllContents);
-    contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-    directoryContents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleDirectoryContents);
-    unknownContents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleUnknownContents);
-        
-    // scan directory contents for matches against predicate
-    for (int i = 0; i < contentsRange.length; i++) {
-        CFStringRef candidateFilename = (CFStringRef)CFArrayGetValueAtIndex(contents, i);
-        if (predicate(candidateFilename, stopLooking)) {
-            // we want this resource, though possibly a platform specific version of it
-            // unpack candidateFilename string into pathUniChars after verifying that we have enough space in the buffer
-            CFIndex candidateFilenameLength = CFStringGetLength(candidateFilename);
-            if ((dirPathLen + candidateFilenameLength < CFMaxPathSize)) {
-                CFStringGetCharacters(candidateFilename, CFRangeMake(0, candidateFilenameLength), pathUniChars + dirPathLen);
-                
-                // is there a platform specific version available? if so update pathUniChars to contain it and candidateFilenameLength to describe its length.
-                static const int platformSeparatorLen = 1; // the length of '-', as appears in foo-macos.tiff.  sugar to make the following easier to read.
-                if (_PlatformLen && (dirPathLen + candidateFilenameLength + platformSeparatorLen + _PlatformLen < CFMaxPathSize)) {
-                    CFIndex candidateFilenameWithoutExtensionLen = _CFLengthAfterDeletingPathExtension(pathUniChars + dirPathLen, candidateFilenameLength);
-                    CFIndex extensionLen = candidateFilenameLength - candidateFilenameWithoutExtensionLen;
-                    // shift the extension over to make space for the platform
-                    memmove(pathUniChars + dirPathLen + candidateFilenameWithoutExtensionLen + platformSeparatorLen + _PlatformLen, pathUniChars + dirPathLen + candidateFilenameWithoutExtensionLen, extensionLen * sizeof(UniChar));
-                    // write the platform into the middle of the string
-                    pathUniChars[dirPathLen + candidateFilenameWithoutExtensionLen] = (UniChar)'-';
-                    memcpy(pathUniChars + dirPathLen + candidateFilenameWithoutExtensionLen + platformSeparatorLen, _PlatformUniChars, _PlatformLen * sizeof(UniChar));
-                    // pack it up as a CFStringRef
-                    CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + dirPathLen, candidateFilenameLength + platformSeparatorLen + _PlatformLen, candidateFilenameLength + _PlatformLen);
-                    CFStringReplaceAll(cheapStr, tmpString);
-                    // is the platform specialized version there?
-                    if (_CFBundleSortedArrayContains(contents, cheapStr)) {
-                        // woo. update the candidateFilenameLength.  we'll update the candidateFilename too for consistency, but we don't actually use it again.  
-                        // the pathUniChars now contains the full path to the file
-                        candidateFilename = cheapStr;
-                        candidateFilenameLength = candidateFilenameLength + _PlatformLen + platformSeparatorLen;
-                    } else {
-                        // nope, no platform specific resource.  Put the pathUniChars back how they were before, without the platform.
-                        memmove(pathUniChars + dirPathLen + candidateFilenameWithoutExtensionLen, pathUniChars + dirPathLen + candidateFilenameWithoutExtensionLen + platformSeparatorLen + _PlatformLen, extensionLen * sizeof(UniChar));
-                    }
-                }
-                
-                // get the full path into cheapStr
-                CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, dirPathLen + candidateFilenameLength, dirPathLen + candidateFilenameLength);
-                CFStringReplaceAll(cheapStr, tmpString);
-                
-                // is the resource a directory?  we need to know so that we can avoid file access when making a URL.
-                Boolean isDir = 0;
-                if (_CFBundleSortedArrayContains(directoryContents, cheapStr)) {
-                    isDir = 1;
-                } else if (_CFBundleSortedArrayContains(unknownContents, cheapStr)) {
-                    _CFIsResourceAtPath(cheapStr, &isDir);
-                }
-                
-                CFURLRef url = CFURLCreateWithFileSystemPath(alloc, cheapStr, PLATFORM_PATH_STYLE, isDir);
-                CFArrayAppendValue(result, url);
-                CFRelease(url);
-            }
-        }
-        
-        if (*stopLooking) break;
-    }
-    
-    CFRelease(contents);
-    CFRelease(directoryContents);
-    CFRelease(unknownContents);
-}
-
-
-static void _CFFindBundleResourcesInRawDir(CFAllocatorRef alloc, UniChar *workingUniChars, CFIndex workingLen, UniChar *nameUniChars, CFIndex nameLen, CFArrayRef resTypes, CFIndex limit, Boolean *stopLooking, Boolean (^predicate)(CFStringRef filename, Boolean *stop), uint8_t version, CFMutableStringRef cheapStr, CFMutableStringRef tmpString, CFMutableArrayRef result) {
-    if (predicate) {
-        _CFSearchBundleDirectoryWithPredicate(alloc, result, workingUniChars, workingLen, predicate, cheapStr, tmpString, stopLooking, version);
-        return;
-    }
-    if (nameLen > 0) {
-        // If we have a resName, just call the search API.  We may have to loop over the resTypes.
-        if (!resTypes) {
-            _CFSearchBundleDirectory(alloc, result, workingUniChars, workingLen, nameUniChars, nameLen, NULL, 0, cheapStr, tmpString, version);
-        } else {
-            CFArrayRef subResTypes = resTypes;
-            Boolean releaseSubResTypes = false;
-            CFIndex i, c = CFArrayGetCount(resTypes);
-            if (c > 2) {
-                // this is an optimization we employ when searching for large numbers of types, if the directory contents are available
-                // we scan the directory contents and restrict the list of resTypes to the types that might actually occur with the specified name
-                subResTypes = _CFCopyTypesForSearchBundleDirectory(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, cheapStr, tmpString, version);
-                c = CFArrayGetCount(subResTypes);
-                releaseSubResTypes = true;
-            }
-            for (i = 0; i < c; i++) {
-                CFStringRef curType = (CFStringRef)CFArrayGetValueAtIndex(subResTypes, i);
-                CFIndex typeLen = CFStringGetLength(curType);
-                STACK_BUFFER_DECL(UniChar, typeChars, typeLen);
-                CFStringGetCharacters(curType, CFRangeMake(0, typeLen), typeChars);
-                _CFSearchBundleDirectory(alloc, result, workingUniChars, workingLen, nameUniChars, nameLen, typeChars, typeLen, cheapStr, tmpString, version);
-                if (limit <= CFArrayGetCount(result)) break;
-            }
-            if (releaseSubResTypes) CFRelease(subResTypes);
-        }
-    } else {
-        // If we have no resName, do it by hand. We may have to loop over the resTypes.
-        char cpathBuff[CFMaxPathSize];
-        CFIndex cpathLen;
-        CFMutableArrayRef children;
-
-        CFStringSetExternalCharactersNoCopy(tmpString, workingUniChars, workingLen, workingLen);
-        if (!CFStringGetFileSystemRepresentation(tmpString, cpathBuff, CFMaxPathSize)) return;
-        cpathLen = strlen(cpathBuff);
-
-        if (!resTypes) {
-            // ??? should this use _CFBundleCopyDirectoryContentsAtPath?
-            children = _CFContentsOfDirectory(alloc, cpathBuff, NULL, NULL, NULL);
-            if (children) {
-                CFIndex childIndex, childCount = CFArrayGetCount(children);
-                for (childIndex = 0; childIndex < childCount; childIndex++) CFArrayAppendValue(result, CFArrayGetValueAtIndex(children, childIndex));
-                CFRelease(children);
-            }
-        } else {
-            CFIndex i, c = CFArrayGetCount(resTypes);
-            for (i = 0; i < c; i++) {
-                CFStringRef curType = (CFStringRef)CFArrayGetValueAtIndex(resTypes, i);
-
-                // ??? should this use _CFBundleCopyDirectoryContentsAtPath?
-                children = _CFContentsOfDirectory(alloc, cpathBuff, NULL, NULL, curType);
-                if (children) {
-                    CFIndex childIndex, childCount = CFArrayGetCount(children);
-                    for (childIndex = 0; childIndex < childCount; childIndex++) CFArrayAppendValue(result, CFArrayGetValueAtIndex(children, childIndex));
-                    CFRelease(children);
-                }
-                if (limit <= CFArrayGetCount(result)) break;
-            }
-        }
+        return _CFBundleSupportFilesDirectoryName2WithResources;
+    } else if (0 == version) {
+        return _CFBundleResourcesDirectoryName;
     }
+    return CFSTR("");
 }
 
-
-static void _CFFindBundleResourcesInResourcesDir(CFAllocatorRef alloc, UniChar *workingUniChars, CFIndex workingLen, UniChar *subDirUniChars, CFIndex subDirLen, CFArrayRef searchLanguages, UniChar *nameUniChars, CFIndex nameLen, CFArrayRef resTypes, CFIndex limit, Boolean (^predicate)(CFStringRef filename, Boolean *stop), uint8_t version, CFMutableStringRef cheapStr, CFMutableStringRef tmpString, CFMutableArrayRef result) {
-    CFIndex savedWorkingLen = workingLen;
-    Boolean stopLooking = false; // for predicate based-queries, we set stopLooking instead of using a limit
-    // Look directly in the directory specified in workingUniChars. as if it is a Resources directory.
+CF_PRIVATE void _CFBundleAppendResourceDir(CFMutableStringRef path, uint8_t version) {
     if (1 == version) {
-        // Add the non-localized resource directory.
-        Boolean appendSucceeded = _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, _GlobalResourcesUniChars, _GlobalResourcesLen);
-        if (appendSucceeded && subDirLen > 0) appendSucceeded = _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, subDirUniChars, subDirLen);
-        if (appendSucceeded) _CFFindBundleResourcesInRawDir(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, limit, &stopLooking, predicate, version, cheapStr, tmpString, result);
-        // Strip the non-localized resource directory.
-        workingLen = savedWorkingLen;
-    }
-    
-    if (CFArrayGetCount(result) < limit && !stopLooking) {
-        Boolean appendSucceeded = true;
-        if (subDirLen > 0) appendSucceeded = _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, subDirUniChars, subDirLen);
-        if (appendSucceeded) _CFFindBundleResourcesInRawDir(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, limit, &stopLooking, predicate, version, cheapStr, tmpString, result);
-    }
-    
-    // Now search the first localized resources (user language).
-    CFIndex langCount = (searchLanguages ? CFArrayGetCount(searchLanguages) : 0);
-    UniChar curLangUniChars[255];
-    
-    workingLen = savedWorkingLen;
-    if (CFArrayGetCount(result) < limit && !stopLooking && langCount >= 1) {
-        CFIndex numResults = CFArrayGetCount(result);
-        CFStringRef curLangStr = (CFStringRef)CFArrayGetValueAtIndex(searchLanguages, 0);
-        CFIndex curLangLen = MIN(CFStringGetLength(curLangStr), 255);
-        CFStringGetCharacters(curLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
-         
-        savedWorkingLen = workingLen;
-        if (_CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, curLangUniChars, curLangLen) &&
-            _CFAppendPathExtension(workingUniChars, &workingLen, CFMaxPathSize, _LprojUniChars, _LprojLen) &&
-            (subDirLen == 0 || (subDirLen > 0 && _CFAppendPathExtension(workingUniChars, &workingLen, CFMaxPathSize, subDirUniChars, subDirLen)))) {
-            
-            _CFFindBundleResourcesInRawDir(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, limit, &stopLooking, predicate, version, cheapStr, tmpString, result);
-            
-            if (CFArrayGetCount(result) != numResults) {
-                // We found resources in a language we already searched.  Don't look any farther.
-                // We also don't need to check the limit, since if the count changed at all, we are bailing.
-                return;
-            }
-        }
-    }
-    
-    workingLen = savedWorkingLen;
-    // Now search the Base.lproj directory
-    if (CFArrayGetCount(result) < limit && !stopLooking) {
-        CFIndex numResults = CFArrayGetCount(result);
-        savedWorkingLen = workingLen;
-        if (_CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, _BaseUniChars, _BaseLen) &&
-            _CFAppendPathExtension(workingUniChars, &workingLen, CFMaxPathSize, _LprojUniChars, _LprojLen) &&
-            (subDirLen == 0 || (subDirLen > 0 && _CFAppendPathExtension(workingUniChars, &workingLen, CFMaxPathSize, subDirUniChars, subDirLen)))) {
-            
-            _CFFindBundleResourcesInRawDir(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, limit, &stopLooking, predicate, version, cheapStr, tmpString, result);
-            
-            if (CFArrayGetCount(result) != numResults) {
-                // We found resources in a language we already searched.  Don't look any farther.
-                // We also don't need to check the limit, since if the count changed at all, we are bailing.
-                return;
-            }
-        }
-    }
-
-    // Now search remaining localized resources (developer language)
-    workingLen = savedWorkingLen;
-    if (CFArrayGetCount(result) < limit && !stopLooking && langCount >= 2) {
-        // MF:??? OK to hard-wire this length?
-        CFIndex numResults = CFArrayGetCount(result);
-        
-        // start after 1st language
-        for (CFIndex langIndex = 1; langIndex < langCount; langIndex++) {
-            CFStringRef curLangStr = (CFStringRef)CFArrayGetValueAtIndex(searchLanguages, langIndex);
-            CFIndex curLangLen = MIN(CFStringGetLength(curLangStr), 255);
-            CFStringGetCharacters(curLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
-            savedWorkingLen = workingLen;
-            if (!_CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, curLangUniChars, curLangLen)) {
-                workingLen = savedWorkingLen;
-                continue;
-            }
-            if (!_CFAppendPathExtension(workingUniChars, &workingLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-                workingLen = savedWorkingLen;
-                continue;
-            }
-            if (subDirLen > 0) {
-                if (!_CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, subDirUniChars, subDirLen)) {
-                    workingLen = savedWorkingLen;
-                    continue;
-                }
-            }
-            _CFFindBundleResourcesInRawDir(alloc, workingUniChars, workingLen, nameUniChars, nameLen, resTypes, limit, &stopLooking, predicate, version, cheapStr, tmpString, result);
-            
-            // Back off this lproj component
-            workingLen = savedWorkingLen;
-            if (CFArrayGetCount(result) != numResults) {
-                // We found resources in a language we already searched.  Don't look any farther.
-                // We also don't need to check the limit, since if the count changed at all, we are bailing.
-                break;
-            }
-        }
-    }
-}
-
-CFArrayRef _CFFindBundleResources(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef subDirName, CFArrayRef searchLanguages, CFStringRef resName, CFArrayRef resTypes, CFIndex limit, Boolean (^predicate)(CFStringRef filename, Boolean *stop), uint8_t version) {
-    CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-
-    // Build an absolute path to the base directory.
-    // If no URL was passed, we get it from the bundle.
-    CFURLRef baseURL = bundleURL ? (CFURLRef)CFRetain(bundleURL) : (bundle ? CFBundleCopyBundleURL(bundle) : NULL);
-    CFURLRef absoluteURL = baseURL ? CFURLCopyAbsoluteURL(baseURL) : NULL;
-    CFStringRef basePath = absoluteURL ? CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE) : NULL;
-    if (absoluteURL) CFRelease(absoluteURL);
-    if (baseURL) CFRelease(baseURL);
-    baseURL = absoluteURL = bundleURL = NULL;
-    bundle = NULL;
-    // bundle and bundleURL arguments are not used any further
-
-    if (!basePath) return result;
-
-
-    UniChar *workingUniChars, *nameUniChars, *subDirUniChars;
-    CFIndex nameLen = 0;
-    CFIndex workingLen, savedWorkingLen;
-    CFMutableStringRef cheapStr, tmpString;
-
-    if (resName) {  
-        char buff[CFMaxPathSize];
-        CFStringRef newResName = NULL;
-        if (CFStringGetFileSystemRepresentation(resName, buff, CFMaxPathSize)) newResName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, buff);
-        resName = newResName ? newResName : (CFStringRef)CFRetain(resName);
-        nameLen = CFStringGetLength(resName);
+        // /path/to/bundle/Support Files/
+        CFStringAppend(path, _CFBundleSupportFilesDirectoryName1);
+        _CFAppendTrailingPathSlash2(path);
+    } else if (2 == version) {
+        // /path/to/bundle/Contents/
+        CFStringAppend(path, _CFBundleSupportFilesDirectoryName2);
+        _CFAppendTrailingPathSlash2(path);
     }
-
-    // Init the one-time-only unichar buffers.
-    _CFEnsureStaticBuffersInited();
-
-    // Build UniChar buffers for some of the string pieces we need.
-    CFIndex subDirLen = (subDirName ? CFStringGetLength(subDirName) : 0);
-    nameUniChars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * (nameLen + subDirLen + CFMaxPathSize), 0);
-    if (nameUniChars) {
-        subDirUniChars = nameUniChars + nameLen;
-        workingUniChars = subDirUniChars + subDirLen;
-
-        if (nameLen > 0) CFStringGetCharacters(resName, CFRangeMake(0, nameLen), nameUniChars);
-        if (subDirLen > 0) CFStringGetCharacters(subDirName, CFRangeMake(0, subDirLen), subDirUniChars);
-
-        if ((workingLen = CFStringGetLength(basePath)) > 0) CFStringGetCharacters(basePath, CFRangeMake(0, workingLen), workingUniChars);
-        savedWorkingLen = workingLen;
-        _CFBundleSetResourceDir(workingUniChars, &workingLen, CFMaxPathSize, version);
-
-        // both of these used for temp string operations, for slightly different purposes, where each type is appropriate
-        cheapStr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
-        _CFStrSetDesiredCapacity(cheapStr, CFMaxPathSize);
-        tmpString = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull);
-
-        _CFFindBundleResourcesInResourcesDir(kCFAllocatorSystemDefault, workingUniChars, workingLen, subDirUniChars, subDirLen, searchLanguages, nameUniChars, nameLen, resTypes, limit, predicate, version, cheapStr, tmpString, result);
-        
-        CFRelease(cheapStr);
-        CFRelease(tmpString);
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, nameUniChars);
+    if (0 == version || 1 == version || 2 == version) {
+        // /path/to/bundle/<above>/Resources
+        CFStringAppend(path, _CFBundleResourcesDirectoryName);
     }
-    if (resName) CFRelease(resName);
-    if (basePath) CFRelease(basePath);
-    return result;
-}
-
-__private_extern__ CFArrayRef _CFFindBundleResourcesNoBlock(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef subDirName, CFArrayRef searchLanguages, CFStringRef resName, CFArrayRef resTypes, CFIndex limit, uint8_t version){
-    return _CFFindBundleResources(bundle, bundleURL, subDirName, searchLanguages, resName, resTypes, limit, NULL, version);
 }
 
 CF_EXPORT CFURLRef CFBundleCopyResourceURL(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName) {
     if (!bundle) return NULL;
-#ifdef CFBUNDLE_NEWLOOKUP
     CFURLRef result = (CFURLRef) _CFBundleCopyFindResources(bundle, NULL, NULL, resourceName, resourceType, subDirName, NULL, NO, NO, NULL);
     return result;
-#else
-    CFURLRef result = NULL;
-    CFArrayRef languages = _CFBundleGetLanguageSearchList(bundle), types = NULL, array;
-    if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-    array = _CFFindBundleResources(bundle, NULL, subDirName, languages, resourceName, types, 1, NULL, _CFBundleLayoutVersion(bundle));
-    if (types) CFRelease(types);
-    if (array) {
-        if (CFArrayGetCount(array) > 0) result = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
-        CFRelease(array);
-    }
-    return result;
-#endif
 }
 
 CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfType(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName) {
-#ifdef CFBUNDLE_NEWLOOKUP
     if (!bundle) return CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     CFArrayRef result = (CFArrayRef) _CFBundleCopyFindResources(bundle, NULL, NULL, NULL, resourceType, subDirName, NULL, YES, NO, NULL);
     return result;
-#else
-    CFArrayRef languages = _CFBundleGetLanguageSearchList(bundle), types = NULL, array;
-    if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-    // MF:!!! Better "limit" than 1,000,000?
-    array = _CFFindBundleResources(bundle, NULL, subDirName, languages, NULL, types, 1000000, NULL, _CFBundleLayoutVersion(bundle));
-    if (types) CFRelease(types);
-    
-    return array;
-#endif
 }
 
 CF_EXPORT CFURLRef _CFBundleCopyResourceURLForLanguage(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language) {
@@ -1140,25 +151,9 @@ CF_EXPORT CFURLRef _CFBundleCopyResourceURLForLanguage(CFBundleRef bundle, CFStr
 }
 
 CF_EXPORT CFURLRef CFBundleCopyResourceURLForLocalization(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef localizationName) {
-#ifdef CFBUNDLE_NEWLOOKUP
     if (!bundle) return NULL;
     CFURLRef result = (CFURLRef) _CFBundleCopyFindResources(bundle, NULL, NULL, resourceName, resourceType, subDirName, localizationName, NO, YES, NULL);
     return result;
-#else
-    CFURLRef result = NULL;
-    CFArrayRef languages = NULL, types = NULL, array;
-
-    if (localizationName) languages = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&localizationName, 1, &kCFTypeArrayCallBacks);
-    if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-    array = _CFFindBundleResources(bundle, NULL, subDirName, languages, resourceName, types, 1, NULL, _CFBundleLayoutVersion(bundle));
-    if (array) {
-        if (CFArrayGetCount(array) > 0) result = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
-        CFRelease(array);
-    }
-    if (types) CFRelease(types);
-    if (languages) CFRelease(languages);
-    return result;
-#endif
 }
 
 CF_EXPORT CFArrayRef _CFBundleCopyResourceURLsOfTypeForLanguage(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language) {
@@ -1166,129 +161,22 @@ CF_EXPORT CFArrayRef _CFBundleCopyResourceURLsOfTypeForLanguage(CFBundleRef bund
 }
 
 CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeForLocalization(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName, CFStringRef localizationName) {
-#ifdef CFBUNDLE_NEWLOOKUP
     if (!bundle) return CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     CFArrayRef result = (CFArrayRef) _CFBundleCopyFindResources(bundle, NULL, NULL, NULL, resourceType, subDirName, localizationName, YES, YES, NULL);
     return result;
-#else
-    CFArrayRef languages = NULL, types = NULL, array;
-
-    if (localizationName) languages = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&localizationName, 1, &kCFTypeArrayCallBacks);
-    if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-    // MF:!!! Better "limit" than 1,000,000?
-    array = _CFFindBundleResources(bundle, NULL, subDirName, languages, NULL, types, 1000000, NULL, _CFBundleLayoutVersion(bundle));
-    if (types) CFRelease(types);
-    if (languages) CFRelease(languages);
-    return array;
-#endif
-}
-
-
-static Boolean CFBundleAllowMixedLocalizations(void);
-
-CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName) {
-    CFStringRef result = NULL;
-    CFDictionaryRef stringTable = NULL;
-    static CFSpinLock_t CFBundleLocalizedStringLock = CFSpinLockInit;
-
-    if (!key) return (value ? (CFStringRef)CFRetain(value) : (CFStringRef)CFRetain(CFSTR("")));
-
-    // Make sure to check the mixed localizations key early -- if the main bundle has not yet been cached, then we need to create the cache of the Info.plist before we start asking for resources (11172381)
-    (void)CFBundleAllowMixedLocalizations();
-    
-    if (!tableName || CFEqual(tableName, CFSTR(""))) tableName = _CFBundleDefaultStringTableName;
-
-    __CFSpinLock(&CFBundleLocalizedStringLock);
-    if (__CFBundleGetResourceData(bundle)->_stringTableCache) {
-        stringTable = (CFDictionaryRef)CFDictionaryGetValue(__CFBundleGetResourceData(bundle)->_stringTableCache, tableName);
-        if (stringTable) CFRetain(stringTable);
-    }
-    __CFSpinUnlock(&CFBundleLocalizedStringLock);
-
-    if (!stringTable) {
-        // Go load the table.
-        CFURLRef tableURL = CFBundleCopyResourceURL(bundle, tableName, _CFBundleStringTableType, NULL);
-        if (tableURL) {
-            CFStringRef nameForSharing = NULL;
-            if (!stringTable) {
-                CFDataRef tableData = NULL;
-                SInt32 errCode;
-                CFStringRef errStr;
-                if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tableURL, &tableData, NULL, NULL, &errCode)) {
-                    stringTable = (CFDictionaryRef)CFPropertyListCreateFromXMLData(CFGetAllocator(bundle), tableData, kCFPropertyListImmutable, &errStr);
-                    if (errStr) {
-                        CFRelease(errStr);
-                        errStr = NULL;
-                    }
-                    if (stringTable && CFDictionaryGetTypeID() != CFGetTypeID(stringTable)) {
-                        CFRelease(stringTable);
-                        stringTable = NULL;
-                    }
-                    CFRelease(tableData);
-
-                }
-            }
-            if (nameForSharing) CFRelease(nameForSharing);
-            if (tableURL) CFRelease(tableURL);
-        }
-        if (!stringTable) stringTable = CFDictionaryCreate(CFGetAllocator(bundle), NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-
-        if (!CFStringHasSuffix(tableName, CFSTR(".nocache")) || !_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) {
-            __CFSpinLock(&CFBundleLocalizedStringLock);
-            if (!__CFBundleGetResourceData(bundle)->_stringTableCache) __CFBundleGetResourceData(bundle)->_stringTableCache = CFDictionaryCreateMutable(CFGetAllocator(bundle), 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-            CFDictionarySetValue(__CFBundleGetResourceData(bundle)->_stringTableCache, tableName, stringTable);
-            __CFSpinUnlock(&CFBundleLocalizedStringLock);
-        }
-    }
-
-    result = (CFStringRef)CFDictionaryGetValue(stringTable, key);
-    if (!result) {
-        if (!value) {
-            result = (CFStringRef)CFRetain(key);
-        } else if (CFEqual(value, CFSTR(""))) {
-            result = (CFStringRef)CFRetain(key);
-        } else {
-            result = (CFStringRef)CFRetain(value);
-        }
-        __block Boolean capitalize = false;
-        if (capitalize) {
-            CFMutableStringRef capitalizedResult = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, result);
-            CFLog(__kCFLogBundle, CFSTR("Localizable string \"%@\" not found in strings table \"%@\" of bundle %@."), key, tableName, bundle);
-            CFStringUppercase(capitalizedResult, NULL);
-            CFRelease(result);
-            result = capitalizedResult;
-        }
-    } else {
-        CFRetain(result);
-    }
-    CFRelease(stringTable);
-    return result;
 }
 
 CF_EXPORT CFURLRef CFBundleCopyResourceURLInDirectory(CFURLRef bundleURL, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName) {
     CFURLRef result = NULL;
     unsigned char buff[CFMaxPathSize];
     CFURLRef newURL = NULL;
-
+    
     if (!CFURLGetFileSystemRepresentation(bundleURL, true, buff, CFMaxPathSize)) return NULL;
-
+    
     newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true);
     if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL);
     if (_CFBundleCouldBeBundle(newURL)) {
-#ifdef CFBUNDLE_NEWLOOKUP
         result = (CFURLRef) _CFBundleCopyFindResources(NULL, bundleURL, NULL, resourceName, resourceType, subDirName, NULL, NO, NO, NULL);
-#else
-        uint8_t version = 0;
-        CFArrayRef languages = _CFBundleCopyLanguageSearchListInDirectory(kCFAllocatorSystemDefault, newURL, &version), types = NULL, array;
-        if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-        array = _CFFindBundleResources(NULL, newURL, subDirName, languages, resourceName, types, 1, NULL, version);
-        if (types) CFRelease(types);
-        if (languages) CFRelease(languages);
-        if (array) {
-            if (CFArrayGetCount(array) > 0) result = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
-            CFRelease(array);
-        }
-#endif
     }
     if (newURL) CFRelease(newURL);
     return result;
@@ -1298,28 +186,21 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeInDirectory(CFURLRef bundleUR
     CFArrayRef array = NULL;
     unsigned char buff[CFMaxPathSize];
     CFURLRef newURL = NULL;
-
+    
     if (!CFURLGetFileSystemRepresentation(bundleURL, true, buff, CFMaxPathSize)) return NULL;
-
+    
     newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true);
     if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL);
     if (_CFBundleCouldBeBundle(newURL)) {
-#ifdef CFBUNDLE_NEWLOOKUP
         array = (CFArrayRef) _CFBundleCopyFindResources(NULL, bundleURL, NULL, NULL, resourceType, subDirName, NULL, YES, NO, NULL);
-#else
-        uint8_t version = 0;
-        CFArrayRef languages = _CFBundleCopyLanguageSearchListInDirectory(kCFAllocatorSystemDefault, newURL, &version), types = NULL;
-        if (resourceType) types = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&resourceType, 1, &kCFTypeArrayCallBacks);
-        // MF:!!! Better "limit" than 1,000,000?
-        array = _CFFindBundleResources(NULL, newURL, subDirName, languages, NULL, types, 1000000, NULL, version);
-        if (types) CFRelease(types);
-        if (languages) CFRelease(languages);
-#endif
     }
     if (newURL) CFRelease(newURL);
     return array;
 }
 
+#pragma mark -
+#pragma mark Lanaguages and Locales
+
 // string, with groups of 6 characters being 1 element in the array of locale abbreviations
 const char * __CFBundleLocaleAbbreviationsArray =
     "en_US\0"      "fr_FR\0"      "en_GB\0"      "de_DE\0"      "it_IT\0"      "nl_NL\0"      "nl_BE\0"      "sv_SE\0"
@@ -1556,7 +437,7 @@ static SInt32 _CFBundleGetRegionCodeForLocalization(CFStringRef localizationName
     return result;
 }
 
-static CFStringRef _CFBundleCopyLocaleAbbreviationForRegionCode(SInt32 regionCode) {
+CF_PRIVATE CFStringRef _CFBundleCopyLocaleAbbreviationForRegionCode(SInt32 regionCode) {
     CFStringRef result = NULL;
     if (0 <= regionCode && regionCode < NUM_LOCALE_ABBREVIATIONS) {
         const char *localeAbbreviation = __CFBundleLocaleAbbreviationsArray + regionCode * LOCALE_ABBREVIATION_LENGTH;
@@ -1567,7 +448,7 @@ static CFStringRef _CFBundleCopyLocaleAbbreviationForRegionCode(SInt32 regionCod
     return result;
 }
 
-Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localizationName, SInt32 *languageCode, SInt32 *regionCode, SInt32 *scriptCode, CFStringEncoding *stringEncoding) {
+CF_EXPORT Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localizationName, SInt32 *languageCode, SInt32 *regionCode, SInt32 *scriptCode, CFStringEncoding *stringEncoding) {
     Boolean retval = false;
     SInt32 language = -1, region = -1, script = 0;
     CFStringEncoding encoding = kCFStringEncodingMacRoman;
@@ -1578,7 +459,7 @@ Boolean CFBundleGetLocalizationInfoForLocalization(CFStringRef localizationName,
             languages = _CFBundleGetLanguageSearchList(mainBundle);
             if (languages) CFRetain(languages);
         }
-        if (!languages) languages = _CFBundleCopyUserLanguages(false);
+        if (!languages) languages = _CFBundleCopyUserLanguages();
         if (languages && CFArrayGetCount(languages) > 0) localizationName = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
     }
     if (localizationName) {
@@ -1634,20 +515,179 @@ CFStringRef CFBundleCopyLocalizationForLocalizationInfo(SInt32 languageCode, SIn
         for (i = 0; scriptLanguage == -1 && i < (sizeof(__CFBundleScriptCodesArray)/sizeof(SInt32)); i++) {
             if (__CFBundleScriptCodesArray[i] == scriptCode) scriptLanguage = i;
         }
-        for (i = 0; encodingLanguage == -1 && i < (sizeof(__CFBundleStringEncodingsArray)/sizeof(CFStringEncoding)); i++) {
-            if (__CFBundleStringEncodingsArray[i] == stringEncoding) encodingLanguage = i;
+        for (i = 0; encodingLanguage == -1 && i < (sizeof(__CFBundleStringEncodingsArray)/sizeof(CFStringEncoding)); i++) {
+            if (__CFBundleStringEncodingsArray[i] == stringEncoding) encodingLanguage = i;
+        }
+        localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(language);
+        if (!localizationName) localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(encodingLanguage);
+        if (!localizationName) localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(scriptLanguage);
+    }
+    return localizationName;
+}
+
+
+static Boolean CFBundleAllowMixedLocalizations(void) {
+    static Boolean allowMixed = false;
+    static dispatch_once_t once = 0;
+    dispatch_once(&once, ^{
+        CFBundleRef mainBundle = CFBundleGetMainBundle();
+        CFDictionaryRef infoDict = mainBundle ? CFBundleGetInfoDictionary(mainBundle) : NULL;
+        CFTypeRef allowMixedValue = infoDict ? CFDictionaryGetValue(infoDict, _kCFBundleAllowMixedLocalizationsKey) : NULL;
+        if (allowMixedValue) {
+            CFTypeID typeID = CFGetTypeID(allowMixedValue);
+            if (typeID == CFBooleanGetTypeID()) {
+                allowMixed = CFBooleanGetValue((CFBooleanRef)allowMixedValue);
+            } else if (typeID == CFStringGetTypeID()) {
+                allowMixed = (CFStringCompare((CFStringRef)allowMixedValue, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)allowMixedValue, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo);
+            } else if (typeID == CFNumberGetTypeID()) {
+                SInt32 val = 0;
+                if (CFNumberGetValue((CFNumberRef)allowMixedValue, kCFNumberSInt32Type, &val)) allowMixed = (val != 0);
+            }
+        }        
+    });
+    return allowMixed;
+}
+
+// Get a list of localizations for a particular resource directory URL. Uncached. Does not include any predefined localizations from an Info.plist.
+static CFArrayRef _CFBundleCopyURLLocalizations(CFAllocatorRef allocator, CFURLRef url) {
+    __block CFMutableArrayRef result = NULL;
+    CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
+    CFStringRef directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+    CFRelease(absoluteURL);
+    
+    CFStringRef lproj = _CFBundleLprojExtensionWithDot;
+    CFIndex lprojLen = CFStringGetLength(lproj);
+    
+    _CFIterateDirectory(directoryPath, ^Boolean(CFStringRef fileName, uint8_t fileType) {
+        // See if the fileName ends in .lproj
+        // The comparison starts at the end of the fileName, backed up by the length of .lproj
+        CFIndex fileNameLen = CFStringGetLength(fileName);
+        if (fileNameLen > lprojLen && CFStringCompareWithOptions(fileName, lproj, CFRangeMake(fileNameLen - lprojLen, lprojLen), 0) == kCFCompareEqualTo) {
+            // Chop off the .lproj part before creating a string
+            CFStringRef lprojDirectoryName = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(0, fileNameLen - lprojLen));
+            if (!result) result = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+            CFArrayAppendValue(result, lprojDirectoryName);
+            CFRelease(lprojDirectoryName);
+        }
+        return true;
+    });
+    
+    CFRelease(directoryPath);
+    return (CFArrayRef)result;
+}
+
+static Boolean _CFBundleTryOnePreferredLprojNameInURL(CFAllocatorRef alloc, CFArrayRef localizations, CFStringRef curLangStr, CFMutableArrayRef lprojNames, Boolean fallBackToLanguage);
+
+CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) {
+    CFArrayRef result = NULL;
+    
+    __CFSpinLock(&bundle->_lock);
+    if (bundle->_lookedForLocalizations) {
+        result = (CFArrayRef)CFRetain(bundle->_localizations);
+        __CFSpinUnlock(&bundle->_lock);
+        return result;
+    }
+    __CFSpinUnlock(&bundle->_lock);
+    
+    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
+    if (infoDict) {
+        CFArrayRef predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
+        if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) != CFArrayGetTypeID()) {
+            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleLocalizationsKey);
+        } else if (predefinedLocalizations) {
+            // <rdar://problem/14255685> Some people put bad things inside this array =(
+            CFMutableArrayRef realPredefinedLocalizations = CFArrayCreateMutable(CFGetAllocator(bundle), CFArrayGetCount(predefinedLocalizations), &kCFTypeArrayCallBacks);
+            for (CFIndex i = 0; i < CFArrayGetCount(predefinedLocalizations); i++) {
+                CFStringRef oneEntry = CFArrayGetValueAtIndex(predefinedLocalizations, i);
+                if (CFGetTypeID(oneEntry) == CFStringGetTypeID() && CFStringGetLength(oneEntry) > 0) {
+                    CFArrayAppendValue(realPredefinedLocalizations, oneEntry);
+                }
+            }
+            result = CFArrayCreateCopy(CFGetAllocator(bundle), realPredefinedLocalizations);
+            CFRelease(realPredefinedLocalizations);
+        }
+    }
+    
+    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
+    if (resourcesURL) {
+        CFArrayRef lprojDirectoriesInResources = _CFBundleCopyURLLocalizations(CFGetAllocator(bundle), resourcesURL);
+        if (lprojDirectoriesInResources) {
+            if (result) {
+                // Append the lproj result to the predefined localization array
+                CFMutableArrayRef newResult = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, result);
+                CFRelease(result);
+                CFArrayAppendArray(newResult, lprojDirectoriesInResources, CFRangeMake(0, CFArrayGetCount(lprojDirectoriesInResources)));
+                CFRelease(lprojDirectoriesInResources);
+                result = newResult;
+            } else {
+                result = lprojDirectoriesInResources;
+            }
+        }
+        CFRelease(resourcesURL);
+    }
+
+    CFStringRef developmentLocalization = CFBundleGetDevelopmentRegion(bundle);
+    if (result) {
+        if (developmentLocalization) {
+            CFRange entireRange = CFRangeMake(0, CFArrayGetCount(result));
+            if (CFArrayContainsValue(result, entireRange, _CFBundleBaseDirectory)) {
+                // Base.lproj contains localizations for the development region. Insert the devleopment region into the existing array if there isn't already a match so that resource lookup doesn't default to another language.
+                CFMutableArrayRef tempArray = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+                if (tempArray) {
+                    if (!_CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, result, developmentLocalization, tempArray, false) && CFArrayGetCount(tempArray) == 0) {
+                        CFMutableArrayRef newResult = CFArrayCreateMutableCopy(kCFAllocatorDefault, 0, result);
+                        CFRelease(result);
+                        CFArrayAppendValue(newResult, developmentLocalization);
+                        result = newResult;
+                    }
+                    CFRelease(tempArray);
+                }
+            }
+        }
+    } else {
+        if (developmentLocalization) {
+            result = CFArrayCreate(CFGetAllocator(bundle), (const void **)&developmentLocalization, 1, &kCFTypeArrayCallBacks);
+        } else {
+            result = CFArrayCreate(CFGetAllocator(bundle), NULL, 0, &kCFTypeArrayCallBacks);
+        }
+    }
+    
+    // Cache the result.
+    __CFSpinLock(&bundle->_lock);
+    if (bundle->_localizations) CFRelease(bundle->_localizations);
+    bundle->_localizations = (CFArrayRef)CFRetain(result);
+    bundle->_lookedForLocalizations = true;
+    __CFSpinUnlock(&bundle->_lock);
+    
+    return result;
+}
+
+CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url) {
+    CFArrayRef result = NULL;
+    CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url);
+    CFStringRef devLang = NULL;
+    if (bundle) {
+        result = CFBundleCopyBundleLocalizations(bundle);
+        CFRelease(bundle);
+    } else {
+        CFDictionaryRef infoDict = _CFBundleCopyInfoDictionaryInExecutable(url);
+        if (infoDict) {
+            CFArrayRef predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
+            if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) == CFArrayGetTypeID()) result = (CFArrayRef)CFRetain(predefinedLocalizations);
+            if (!result) {
+                devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
+                if (devLang && (CFGetTypeID(devLang) == CFStringGetTypeID() && CFStringGetLength(devLang) > 0)) result = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&devLang, 1, &kCFTypeArrayCallBacks);
+            }
+            CFRelease(infoDict);
         }
-        localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(language);
-        if (!localizationName) localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(encodingLanguage);
-        if (!localizationName) localizationName = _CFBundleCopyLanguageAbbreviationForLanguageCode(scriptLanguage);
     }
-    return localizationName;
+    return result;
 }
 
 extern void *__CFAppleLanguages;
 
 
-__private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops) {
+CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages() {
     static CFArrayRef _CFBundleUserLanguages = NULL;
     static dispatch_once_t once = 0;
     dispatch_once(&once, ^{
@@ -1695,7 +735,7 @@ CF_EXPORT void _CFBundleGetLanguageAndRegionCodes(SInt32 *languageCode, SInt32 *
         languages = _CFBundleGetLanguageSearchList(mainBundle);
         if (languages) CFRetain(languages);
     }
-    if (!languages) languages = _CFBundleCopyUserLanguages(false);
+    if (!languages) languages = _CFBundleCopyUserLanguages();
     if (languages && CFArrayGetCount(languages) > 0) {
         CFStringRef localizationName = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
         Boolean retval = false;
@@ -1722,55 +762,86 @@ CF_EXPORT void _CFBundleGetLanguageAndRegionCodes(SInt32 *languageCode, SInt32 *
 }
 
 
-static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc, UniChar *pathUniChars, CFIndex pathLen, uint8_t version, CFDictionaryRef infoDict, CFStringRef curLangStr, CFMutableArrayRef lprojNames, Boolean fallBackToLanguage) {
-    CFIndex curLangLen = CFStringGetLength(curLangStr), savedPathLen;
-    UniChar curLangUniChars[255];
-    CFStringRef altLangStr = NULL, modifiedLangStr = NULL, languageAbbreviation = NULL, languageName = NULL, canonicalLanguageIdentifier = NULL, canonicalLanguageAbbreviation = NULL;
-    CFMutableDictionaryRef canonicalLanguageIdentifiers = NULL, predefinedCanonicalLanguageIdentifiers = NULL;
+
+static Boolean _CFBundleTryOnePreferredLprojNameInArray(CFArrayRef array, CFStringRef curLangStr, CFMutableArrayRef lprojNames, Boolean fallBackToLanguage) {
+    CFRange range = CFRangeMake(0, CFArrayGetCount(array));
+    if (range.length == 0) return false;
+    
     Boolean foundOne = false, specifiesScript = false;
-    CFArrayRef predefinedLocalizations = NULL;
-    CFRange predefinedLocalizationsRange;
-    CFMutableStringRef cheapStr, tmpString;
-    CFArrayRef contents;
-    CFRange contentsRange;
-
-    // both of these used for temp string operations, for slightly
-    // different purposes, where each type is appropriate
-    cheapStr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
-    _CFStrSetDesiredCapacity(cheapStr, CFMaxPathSize);
-    tmpString = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull);    
-    
-    CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-    CFStringReplaceAll(cheapStr, tmpString);
-    contents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleAllContents);
-    contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
+    CFStringRef altLangStr = NULL, modifiedLangStr = NULL, languageAbbreviation = NULL, languageName = NULL, canonicalLanguageIdentifier = NULL, canonicalLanguageAbbreviation = NULL;
+    CFMutableDictionaryRef canonicalLanguageIdentifiers = NULL;
     
-    if (infoDict) {
-        predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
-        if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) != CFArrayGetTypeID()) {
-            predefinedLocalizations = NULL;
-            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleLocalizationsKey);
+    if (CFArrayContainsValue(array, range, curLangStr)) {
+        if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), curLangStr)) CFArrayAppendValue(lprojNames, curLangStr);
+        foundOne = true;
+        if (range.length == 1 || CFStringGetLength(curLangStr) <= 2) return foundOne;
+    }
+    if (range.length == 1 && CFArrayContainsValue(array, range, CFSTR("default"))) return foundOne;
+    
+#if defined(__CONSTANT_CFSTRINGS__)
+    if (!altLangStr) {
+        CFIndex idx;
+        for (idx = 0; !altLangStr && idx < NUM_COMMON_LANGUAGE_NAMES; idx++) {
+            if (CFEqual(curLangStr, __CFBundleCommonLanguageAbbreviationsArray[idx])) altLangStr = __CFBundleCommonLanguageNamesArray[idx];
+            else if (CFEqual(curLangStr, __CFBundleCommonLanguageNamesArray[idx])) altLangStr = __CFBundleCommonLanguageAbbreviationsArray[idx];
+        }
+    }
+    if (foundOne && altLangStr) return foundOne;
+#endif /* __CONSTANT_CFSTRINGS__ */
+    
+    if (altLangStr && CFArrayContainsValue(array, range, altLangStr)) {
+        if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), altLangStr)) CFArrayAppendValue(lprojNames, altLangStr);
+        foundOne = true;
+        return foundOne;
+    }
+    
+    if (!altLangStr && (modifiedLangStr = _CFBundleCopyModifiedLocalization(curLangStr))) {
+        if (CFArrayContainsValue(array, range, modifiedLangStr)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), modifiedLangStr)) CFArrayAppendValue(lprojNames, modifiedLangStr);
+            foundOne = true;
         }
     }
-    predefinedLocalizationsRange = CFRangeMake(0, predefinedLocalizations ? CFArrayGetCount(predefinedLocalizations) : 0);
     
-    if (curLangLen > 255) curLangLen = 255;
-    CFStringGetCharacters(curLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
-    savedPathLen = pathLen;
-    if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + savedPathLen + 1, pathLen - savedPathLen - 1, pathLen - savedPathLen - 1);
-        CFStringReplaceAll(cheapStr, tmpString);
-        if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, curLangStr)) || (version != 4 && _CFBundleSortedArrayContains(contents, cheapStr))) {
-            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), curLangStr)) CFArrayAppendValue(lprojNames, curLangStr);
+    if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageAbbreviation = _CFBundleCopyLanguageAbbreviationForLocalization(curLangStr)) && !CFEqual(curLangStr, languageAbbreviation)) {
+        if (CFArrayContainsValue(array, range, languageAbbreviation)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageAbbreviation)) CFArrayAppendValue(lprojNames, languageAbbreviation);
             foundOne = true;
-            if (CFStringGetLength(curLangStr) <= 2) {
-                CFRelease(cheapStr);
-                CFRelease(tmpString);
-                CFRelease(contents);
-                return foundOne;
-            }
         }
     }
+    if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageName = _CFBundleCopyLanguageNameForLocalization(curLangStr)) && !CFEqual(curLangStr, languageName)) {
+        if (CFArrayContainsValue(array, range, languageName)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageName)) CFArrayAppendValue(lprojNames, languageName);
+            foundOne = true;
+        }
+    }
+    if (modifiedLangStr) CFRelease(modifiedLangStr);
+    if (languageAbbreviation) CFRelease(languageAbbreviation);
+    if (languageName) CFRelease(languageName);
+    if (canonicalLanguageIdentifier) CFRelease(canonicalLanguageIdentifier);
+    if (canonicalLanguageIdentifiers) CFRelease(canonicalLanguageIdentifiers);
+    if (canonicalLanguageAbbreviation) CFRelease(canonicalLanguageAbbreviation);
+    return foundOne;
+}
+
+// localizations array must include both predefined and actual lproj localizations
+static Boolean _CFBundleTryOnePreferredLprojNameInURL(CFAllocatorRef alloc, CFArrayRef localizations, CFStringRef curLangStr, CFMutableArrayRef lprojNames, Boolean fallBackToLanguage) {
+    CFStringRef altLangStr = NULL, modifiedLangStr = NULL, languageAbbreviation = NULL, languageName = NULL, canonicalLanguageIdentifier = NULL, canonicalLanguageAbbreviation = NULL;
+    CFMutableDictionaryRef canonicalLanguageIdentifiers = NULL;
+    Boolean foundOne = false, specifiesScript = false;
+
+    if (!localizations) return false;
+    
+    CFRange localizationsRange = CFRangeMake(0, CFArrayGetCount(localizations));
+            
+    // this use of contents is only checking for language strings - it could get the list of existing localizations and use that instead
+    if (CFArrayContainsValue(localizations, localizationsRange, curLangStr)) {
+        if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), curLangStr)) CFArrayAppendValue(lprojNames, curLangStr);
+        foundOne = true;
+        if (CFStringGetLength(curLangStr) <= 2) {
+            return foundOne;
+        }
+    }
+
 #if defined(__CONSTANT_CFSTRINGS__)
     if (!altLangStr) {
         CFIndex idx;
@@ -1781,83 +852,34 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     }
 #endif /* __CONSTANT_CFSTRINGS__ */
     if (foundOne && altLangStr) {
-        CFRelease(cheapStr);
-        CFRelease(tmpString);
-        CFRelease(contents);
         return foundOne;
     }
     if (altLangStr) {
-        curLangLen = CFStringGetLength(altLangStr);
-        if (curLangLen > 255) curLangLen = 255;
-        CFStringGetCharacters(altLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
-        pathLen = savedPathLen;
-        if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + savedPathLen + 1, pathLen - savedPathLen - 1, pathLen - savedPathLen - 1);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, altLangStr)) || (version != 4 && _CFBundleSortedArrayContains(contents, cheapStr))) {
-                if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), altLangStr)) CFArrayAppendValue(lprojNames, altLangStr);
-                foundOne = true;
-                CFRelease(cheapStr);
-                CFRelease(tmpString);
-                CFRelease(contents);
-                return foundOne;
-            }
-        }
-    }
-    if (!foundOne && (!predefinedLocalizations || CFArrayGetCount(predefinedLocalizations) == 0)) {
-        Boolean hasLocalizations = false;
-        CFIndex idx;
-        for (idx = 0; !hasLocalizations && idx < contentsRange.length; idx++) {
-            CFStringRef name = (CFStringRef)CFArrayGetValueAtIndex(contents, idx);
-            if (CFStringHasSuffix(name, _CFBundleLprojExtensionWithDot)) hasLocalizations = true;
-        }
-        if (!hasLocalizations) {
-            CFRelease(cheapStr);
-            CFRelease(tmpString);
-            CFRelease(contents);
+        if (CFArrayContainsValue(localizations, localizationsRange, altLangStr)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), altLangStr)) CFArrayAppendValue(lprojNames, altLangStr);
+            foundOne = true;
             return foundOne;
         }
     }
+
     if (!altLangStr && (modifiedLangStr = _CFBundleCopyModifiedLocalization(curLangStr))) {
-        curLangLen = CFStringGetLength(modifiedLangStr);
-        if (curLangLen > 255) curLangLen = 255;
-        CFStringGetCharacters(modifiedLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
-        pathLen = savedPathLen;
-        if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + savedPathLen + 1, pathLen - savedPathLen - 1, pathLen - savedPathLen - 1);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, modifiedLangStr)) || (version != 4 && _CFBundleSortedArrayContains(contents, cheapStr))) {
-                if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), modifiedLangStr)) CFArrayAppendValue(lprojNames, modifiedLangStr);
-                foundOne = true;
-            }
+        if (CFArrayContainsValue(localizations, localizationsRange, modifiedLangStr)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), modifiedLangStr)) CFArrayAppendValue(lprojNames, modifiedLangStr);
+            foundOne = true;
         }
     }
+    
+    
     if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageAbbreviation = _CFBundleCopyLanguageAbbreviationForLocalization(curLangStr)) && !CFEqual(curLangStr, languageAbbreviation)) {
-        curLangLen = CFStringGetLength(languageAbbreviation);
-        if (curLangLen > 255) curLangLen = 255;
-        CFStringGetCharacters(languageAbbreviation, CFRangeMake(0, curLangLen), curLangUniChars);
-        pathLen = savedPathLen;
-        if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + savedPathLen + 1, pathLen - savedPathLen - 1, pathLen - savedPathLen - 1);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, languageAbbreviation)) || (version != 4 && _CFBundleSortedArrayContains(contents, cheapStr))) {
-                if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageAbbreviation)) CFArrayAppendValue(lprojNames, languageAbbreviation);
-                foundOne = true;
-            }
+        if (CFArrayContainsValue(localizations, localizationsRange, languageAbbreviation)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageAbbreviation)) CFArrayAppendValue(lprojNames, languageAbbreviation);
+            foundOne = true;
         }
     }
     if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageName = _CFBundleCopyLanguageNameForLocalization(curLangStr)) && !CFEqual(curLangStr, languageName)) {
-        curLangLen = CFStringGetLength(languageName);
-        if (curLangLen > 255) curLangLen = 255;
-        CFStringGetCharacters(languageName, CFRangeMake(0, curLangLen), curLangUniChars);
-        pathLen = savedPathLen;
-        if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + savedPathLen + 1, pathLen - savedPathLen - 1, pathLen - savedPathLen - 1);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, languageName)) || (version != 4 && _CFBundleSortedArrayContains(contents, cheapStr))) {
-                if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageName)) CFArrayAppendValue(lprojNames, languageName);
-                foundOne = true;
-            }
+        if (CFArrayContainsValue(localizations, localizationsRange, languageName)) {
+            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageName)) CFArrayAppendValue(lprojNames, languageName);
+            foundOne = true;
         }
     }
     if (modifiedLangStr) CFRelease(modifiedLangStr);
@@ -1865,36 +887,10 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     if (languageName) CFRelease(languageName);
     if (canonicalLanguageIdentifier) CFRelease(canonicalLanguageIdentifier);
     if (canonicalLanguageIdentifiers) CFRelease(canonicalLanguageIdentifiers);
-    if (predefinedCanonicalLanguageIdentifiers) CFRelease(predefinedCanonicalLanguageIdentifiers);
     if (canonicalLanguageAbbreviation) CFRelease(canonicalLanguageAbbreviation);
-    CFRelease(cheapStr);
-    CFRelease(tmpString);
-    CFRelease(contents);
     return foundOne;
 }
 
-static Boolean CFBundleAllowMixedLocalizations(void) {
-    static Boolean allowMixed = false;
-    static dispatch_once_t once = 0;
-    dispatch_once(&once, ^{
-        CFBundleRef mainBundle = CFBundleGetMainBundle();
-        CFDictionaryRef infoDict = mainBundle ? CFBundleGetInfoDictionary(mainBundle) : NULL;
-        CFTypeRef allowMixedValue = infoDict ? CFDictionaryGetValue(infoDict, _kCFBundleAllowMixedLocalizationsKey) : NULL;
-        if (allowMixedValue) {
-            CFTypeID typeID = CFGetTypeID(allowMixedValue);
-            if (typeID == CFBooleanGetTypeID()) {
-                allowMixed = CFBooleanGetValue((CFBooleanRef)allowMixedValue);
-            } else if (typeID == CFStringGetTypeID()) {
-                allowMixed = (CFStringCompare((CFStringRef)allowMixedValue, CFSTR("true"), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare((CFStringRef)allowMixedValue, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo);
-            } else if (typeID == CFNumberGetTypeID()) {
-                SInt32 val = 0;
-                if (CFNumberGetValue((CFNumberRef)allowMixedValue, kCFNumberSInt32Type, &val)) allowMixed = (val != 0);
-            }
-        }        
-    });
-    return allowMixed;
-}
-
 static Boolean _CFBundleLocalizationsHaveCommonPrefix(CFStringRef loc1, CFStringRef loc2) {
     Boolean result = false;
     CFIndex length1 = CFStringGetLength(loc1), length2 = CFStringGetLength(loc2), idx;
@@ -1912,34 +908,13 @@ static Boolean _CFBundleLocalizationsHaveCommonPrefix(CFStringRef loc1, CFString
     return result;
 }
 
-__private_extern__ void _CFBundleAddPreferredLprojNamesInDirectory(CFAllocatorRef alloc, CFURLRef bundleURL, uint8_t version, CFDictionaryRef infoDict, CFMutableArrayRef lprojNames, CFStringRef devLang) {
+static void _CFBundleAddPreferredLprojNamesInDirectory(CFAllocatorRef alloc, CFURLRef bundleURL, CFArrayRef localizations, CFMutableArrayRef lprojNames, CFStringRef devLang) {
     // This function will add zero, one or two elements to the lprojNames array.
     // It examines the users preferred language list and the lproj directories inside the bundle directory.  It picks the lproj directory that is highest on the users list.
     // The users list can contain region names (like "en_US" for US English).  In this case, if the region lproj exists, it will be added, and, if the region's associated language lproj exists that will be added.
-    CFURLRef resourcesURL = _CFBundleCopyResourcesDirectoryURLInDirectory(bundleURL, version);
-    CFURLRef absoluteURL;
-    CFIndex idx, startIdx;
-    CFIndex count;
-    CFStringRef resourcesPath;
-    UniChar pathUniChars[CFMaxPathSize];
-    CFIndex pathLen;
-    CFStringRef curLangStr, nextLangStr;
+
     Boolean foundOne = false;
-    CFArrayRef userLanguages;
     
-    // Init the one-time-only unichar buffers.
-    _CFEnsureStaticBuffersInited();
-
-    // Get the path to the resources and extract into a buffer.
-    absoluteURL = CFURLCopyAbsoluteURL(resourcesURL);
-    resourcesPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-    CFRelease(absoluteURL);
-    pathLen = CFStringGetLength(resourcesPath);
-    if (pathLen > CFMaxPathSize) pathLen = CFMaxPathSize;
-    CFStringGetCharacters(resourcesPath, CFRangeMake(0, pathLen), pathUniChars);
-    CFRelease(resourcesURL);
-    CFRelease(resourcesPath);
-
     // First check the main bundle.
     if (!CFBundleAllowMixedLocalizations()) {
         CFBundleRef mainBundle = CFBundleGetMainBundle();
@@ -1950,8 +925,8 @@ __private_extern__ void _CFBundleAddPreferredLprojNamesInDirectory(CFAllocatorRe
                     // If there is a main bundle, and it isn't this one, try to use the language it prefers.
                     CFArrayRef mainBundleLangs = _CFBundleGetLanguageSearchList(mainBundle);
                     if (mainBundleLangs && (CFArrayGetCount(mainBundleLangs) > 0)) {
-                        curLangStr = (CFStringRef)CFArrayGetValueAtIndex(mainBundleLangs, 0);
-                        foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, curLangStr, lprojNames, true);
+                        CFStringRef curLangStr = (CFStringRef)CFArrayGetValueAtIndex(mainBundleLangs, 0);
+                        foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, curLangStr, lprojNames, true);
                     }
                 }
                 CFRelease(mainBundleURL);
@@ -1961,86 +936,80 @@ __private_extern__ void _CFBundleAddPreferredLprojNamesInDirectory(CFAllocatorRe
 
     if (!foundOne) {
         // If we didn't find the main bundle's preferred language, look at the users' prefs again and find the best one.
-        userLanguages = _CFBundleCopyUserLanguages(true);
-        count = (userLanguages ? CFArrayGetCount(userLanguages) : 0);
-        for (idx = 0, startIdx = -1; !foundOne && idx < count; idx++) {
-            curLangStr = (CFStringRef)CFArrayGetValueAtIndex(userLanguages, idx);
-            nextLangStr = (idx + 1 < count) ? (CFStringRef)CFArrayGetValueAtIndex(userLanguages, idx + 1) : NULL;
-            if (nextLangStr && _CFBundleLocalizationsHaveCommonPrefix(curLangStr, nextLangStr)) {
-                foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, curLangStr, lprojNames, false);
-                if (startIdx < 0) startIdx = idx;
-            } else if (startIdx >= 0 && startIdx <= idx) {
-                foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, curLangStr, lprojNames, false);
-                for (; !foundOne && startIdx <= idx; startIdx++) {
-                    curLangStr = (CFStringRef)CFArrayGetValueAtIndex(userLanguages, startIdx);
-                    foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, curLangStr, lprojNames, true);
+        CFArrayRef userLanguages = _CFBundleCopyUserLanguages();
+        if (userLanguages) {
+            CFIndex count = CFArrayGetCount(userLanguages);
+            CFIndex idx, startIdx;
+            for (idx = 0, startIdx = -1; !foundOne && idx < count; idx++) {
+                CFStringRef curLangStr = (CFStringRef)CFArrayGetValueAtIndex(userLanguages, idx);
+                CFStringRef nextLangStr = (idx + 1 < count) ? (CFStringRef)CFArrayGetValueAtIndex(userLanguages, idx + 1) : NULL;
+                if (nextLangStr && _CFBundleLocalizationsHaveCommonPrefix(curLangStr, nextLangStr)) {
+                    foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, curLangStr, lprojNames, false);
+                    if (startIdx < 0) startIdx = idx;
+                } else if (startIdx >= 0 && startIdx <= idx) {
+                    foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, curLangStr, lprojNames, false);
+                    for (; !foundOne && startIdx <= idx; startIdx++) {
+                        curLangStr = (CFStringRef)CFArrayGetValueAtIndex(userLanguages, startIdx);
+                        foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, curLangStr, lprojNames, true);
+                    }
+                    startIdx = -1;
+                } else {
+                    foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, curLangStr, lprojNames, true);
+                    startIdx = -1;
                 }
-                startIdx = -1;
-            } else {
-                foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, curLangStr, lprojNames, true);
-                startIdx = -1;
             }
         }
         // use development region and U.S. English as backstops
-        if (!foundOne && devLang) foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, devLang, lprojNames, true);
-        if (!foundOne) foundOne = _CFBundleTryOnePreferredLprojNameInDirectory(kCFAllocatorSystemDefault, pathUniChars, pathLen, version, infoDict, CFSTR("en_US"), lprojNames, true);
+        if (!foundOne && devLang) foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, devLang, lprojNames, true);
+        if (!foundOne) foundOne = _CFBundleTryOnePreferredLprojNameInURL(kCFAllocatorSystemDefault, localizations, CFSTR("en_US"), lprojNames, true);
         if (userLanguages) CFRelease(userLanguages);
     }
 }
 
-static Boolean _CFBundleTryOnePreferredLprojNameInArray(CFArrayRef array, CFStringRef curLangStr, CFMutableArrayRef lprojNames, Boolean fallBackToLanguage) {
-    Boolean foundOne = false, specifiesScript = false;
-    CFRange range = CFRangeMake(0, CFArrayGetCount(array));
-    CFStringRef altLangStr = NULL, modifiedLangStr = NULL, languageAbbreviation = NULL, languageName = NULL, canonicalLanguageIdentifier = NULL, canonicalLanguageAbbreviation = NULL;
-    CFMutableDictionaryRef canonicalLanguageIdentifiers = NULL;
+static CFArrayRef _CFBundleCopyLanguageSearchListInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) {
+    uint8_t localVersion = 0;
+    CFDictionaryRef infoDict = _CFBundleCopyInfoDictionaryInDirectory(alloc, url, &localVersion);
 
-    if (range.length == 0) return foundOne;
-    if (CFArrayContainsValue(array, range, curLangStr)) {
-        if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), curLangStr)) CFArrayAppendValue(lprojNames, curLangStr);
-        foundOne = true;
-        if (range.length == 1 || CFStringGetLength(curLangStr) <= 2) return foundOne;
-    }
-    if (range.length == 1 && CFArrayContainsValue(array, range, CFSTR("default"))) return foundOne;
-#if defined(__CONSTANT_CFSTRINGS__)
-    if (!altLangStr) {
-        CFIndex idx;
-        for (idx = 0; !altLangStr && idx < NUM_COMMON_LANGUAGE_NAMES; idx++) {
-            if (CFEqual(curLangStr, __CFBundleCommonLanguageAbbreviationsArray[idx])) altLangStr = __CFBundleCommonLanguageNamesArray[idx];
-            else if (CFEqual(curLangStr, __CFBundleCommonLanguageNamesArray[idx])) altLangStr = __CFBundleCommonLanguageAbbreviationsArray[idx];
-        }
-    }
-#endif /* __CONSTANT_CFSTRINGS__ */
-    if (foundOne && altLangStr) return foundOne;
-    if (altLangStr && CFArrayContainsValue(array, range, altLangStr)) {
-        if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), altLangStr)) CFArrayAppendValue(lprojNames, altLangStr);
-        foundOne = true;
-        return foundOne;
-    }
-    if (!altLangStr && (modifiedLangStr = _CFBundleCopyModifiedLocalization(curLangStr))) {
-        if (CFArrayContainsValue(array, range, modifiedLangStr)) {
-            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), modifiedLangStr)) CFArrayAppendValue(lprojNames, modifiedLangStr);
-            foundOne = true;
-        }
-    }
-    if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageAbbreviation = _CFBundleCopyLanguageAbbreviationForLocalization(curLangStr)) && !CFEqual(curLangStr, languageAbbreviation)) {
-        if (CFArrayContainsValue(array, range, languageAbbreviation)) {
-            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageAbbreviation)) CFArrayAppendValue(lprojNames, languageAbbreviation);
-            foundOne = true;
+    CFArrayRef predefinedLocalizations = NULL;
+    CFStringRef devLang = NULL;
+    if (infoDict) {
+        devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
+        if (devLang && (CFGetTypeID(devLang) != CFStringGetTypeID() || CFStringGetLength(devLang) == 0)) devLang = NULL;
+
+        predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
+        if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) != CFArrayGetTypeID()) {
+            predefinedLocalizations = NULL;
+            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleLocalizationsKey);
         }
     }
-    if (!specifiesScript && (foundOne || fallBackToLanguage) && !altLangStr && (languageName = _CFBundleCopyLanguageNameForLocalization(curLangStr)) && !CFEqual(curLangStr, languageName)) {
-        if (CFArrayContainsValue(array, range, languageName)) {
-            if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageName)) CFArrayAppendValue(lprojNames, languageName);
-            foundOne = true;
-        }
+    
+    CFURLRef resourcesURL = _CFBundleCopyResourcesDirectoryURLInDirectory(url, localVersion);
+    CFArrayRef localizations = _CFBundleCopyURLLocalizations(alloc, resourcesURL);
+    CFRelease(resourcesURL);
+    
+    if (predefinedLocalizations && localizations) {
+        CFMutableArrayRef newLocalizations = CFArrayCreateMutableCopy(alloc, 0, predefinedLocalizations);
+        CFArrayAppendArray(newLocalizations, localizations, CFRangeMake(0, CFArrayGetCount(localizations)));
+        CFRelease(localizations);
+        localizations = (CFArrayRef)newLocalizations;
+    } else if (predefinedLocalizations) {
+        localizations = (CFArrayRef)CFRetain(predefinedLocalizations);
+    } else if (!localizations) {
+        localizations = CFArrayCreate(alloc, NULL, 0, &kCFTypeArrayCallBacks);
     }
-    if (modifiedLangStr) CFRelease(modifiedLangStr);
-    if (languageAbbreviation) CFRelease(languageAbbreviation);
-    if (languageName) CFRelease(languageName);
-    if (canonicalLanguageIdentifier) CFRelease(canonicalLanguageIdentifier);
-    if (canonicalLanguageIdentifiers) CFRelease(canonicalLanguageIdentifiers);
-    if (canonicalLanguageAbbreviation) CFRelease(canonicalLanguageAbbreviation);
-    return foundOne;
+    
+    CFMutableArrayRef langs = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
+    _CFBundleAddPreferredLprojNamesInDirectory(alloc, url, localizations, langs, devLang);
+    CFRelease(localizations);
+    
+    if (devLang && CFArrayGetFirstIndexOfValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), devLang) < 0) CFArrayAppendValue(langs, devLang);
+    
+    // Total backstop behavior to avoid having an empty array. 
+    if (CFArrayGetCount(langs) == 0) CFArrayAppendValue(langs, CFSTR("en"));
+    
+    if (infoDict) CFRelease(infoDict);
+    if (version) *version = localVersion;
+    return langs;
 }
 
 static CFArrayRef _CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray, CFArrayRef prefArray, Boolean considerMain) {
@@ -2060,7 +1029,7 @@ static CFArrayRef _CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray,
     if (!foundOne) {
         CFStringRef curLangStr, nextLangStr;
         if (!prefArray) {
-            prefArray = _CFBundleCopyUserLanguages(true);
+            prefArray = _CFBundleCopyUserLanguages();
             if (prefArray) releasePrefArray = true;
         }
         count = (prefArray ? CFArrayGetCount(prefArray) : 0);
@@ -2094,36 +1063,84 @@ static CFArrayRef _CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray,
     if (releasePrefArray) {
         CFRelease(prefArray);
     }
-    return lprojNames;
-}
-
-CF_EXPORT CFArrayRef CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray, CFArrayRef prefArray) {
-    return _CFBundleCopyLocalizationsForPreferences(locArray, prefArray, false);
-}
-
-CF_EXPORT CFArrayRef CFBundleCopyPreferredLocalizationsFromArray(CFArrayRef locArray) {
-    return _CFBundleCopyLocalizationsForPreferences(locArray, NULL, true);
+    return lprojNames;
+}
+
+CF_EXPORT CFArrayRef CFBundleCopyLocalizationsForPreferences(CFArrayRef locArray, CFArrayRef prefArray) {
+    return _CFBundleCopyLocalizationsForPreferences(locArray, prefArray, false);
+}
+
+CF_EXPORT CFArrayRef CFBundleCopyPreferredLocalizationsFromArray(CFArrayRef locArray) {
+    return _CFBundleCopyLocalizationsForPreferences(locArray, NULL, true);
+}
+
+static CFStringRef _defaultLocalization = NULL;
+
+CF_EXPORT void _CFBundleSetDefaultLocalization(CFStringRef localizationName) {
+    CFStringRef newLocalization = localizationName ? (CFStringRef)CFStringCreateCopy(kCFAllocatorSystemDefault, localizationName) : NULL;
+    if (_defaultLocalization) CFRelease(_defaultLocalization);
+    _defaultLocalization = newLocalization;
+}
+
+CF_EXPORT CFArrayRef _CFBundleGetLanguageSearchList(CFBundleRef bundle) {
+    if (!bundle->_searchLanguages) {
+        CFMutableArrayRef langs = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+        CFStringRef devLang = CFBundleGetDevelopmentRegion(bundle);
+        
+#if DEPLOYMENT_TARGET_WINDOWS
+        if (_defaultLocalization) CFArrayAppendValue(langs, _defaultLocalization);
+#endif
+        // includes predefined localizations
+        CFArrayRef localizationsForBundle = CFBundleCopyBundleLocalizations(bundle);
+        
+        _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, localizationsForBundle, langs, devLang);
+        
+        if (CFArrayGetCount(langs) == 0) {
+            // If the user does not prefer any of our languages, and devLang is not present, try English
+            _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, localizationsForBundle, langs, CFSTR("en_US"));
+        }
+        
+        if (CFArrayGetCount(langs) == 0) {
+            // if none of the preferred localizations are present, fall back on a random localization that is present
+            if (localizationsForBundle && CFArrayGetCount(localizationsForBundle) > 0) {
+                CFStringRef firstLocalization = (CFStringRef)CFArrayGetValueAtIndex(localizationsForBundle, 0);
+                _CFBundleAddPreferredLprojNamesInDirectory(CFGetAllocator(bundle), bundle->_url, localizationsForBundle, langs, firstLocalization);
+            }
+        }
+        
+        if (devLang && !CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), devLang)) {
+            // Make sure that devLang is on the list as a fallback for individual resources that are not present
+            CFArrayAppendValue(langs, devLang);
+        } else if (!devLang) {
+            if (localizationsForBundle) {
+                CFStringRef en_US = CFSTR("en_US"), en = CFSTR("en"), English = CFSTR("English");
+                CFRange range = CFRangeMake(0, CFArrayGetCount(localizationsForBundle));
+                if (CFArrayContainsValue(localizationsForBundle, range, en)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en)) CFArrayAppendValue(langs, en);
+                } else if (CFArrayContainsValue(localizationsForBundle, range, English)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), English)) CFArrayAppendValue(langs, English);
+                } else if (CFArrayContainsValue(localizationsForBundle, range, en_US)) {
+                    if (!CFArrayContainsValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), en_US)) CFArrayAppendValue(langs, en_US);
+                }
+            }
+        }
+        
+        if (localizationsForBundle) CFRelease(localizationsForBundle);
+        
+        if (CFArrayGetCount(langs) == 0) {
+            // Total backstop behavior to avoid having an empty array.
+            if (_defaultLocalization) {
+                CFArrayAppendValue(langs, _defaultLocalization);
+            } else {
+                CFArrayAppendValue(langs, CFSTR("en"));
+            }
+        }
+        if (!OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)langs, (void * volatile *)&(bundle->_searchLanguages))) CFRelease(langs);
+    }
+    return bundle->_searchLanguages;
 }
 
-__private_extern__ CFArrayRef _CFBundleCopyLanguageSearchListInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) {
-    CFMutableArrayRef langs = CFArrayCreateMutable(alloc, 0, &kCFTypeArrayCallBacks);
-    uint8_t localVersion = 0;
-    CFDictionaryRef infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefaultGCRefZero, url, &localVersion);
-    CFStringRef devLang = NULL;
-    if (infoDict) devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
-    if (devLang && (CFGetTypeID(devLang) != CFStringGetTypeID() || CFStringGetLength(devLang) == 0)) devLang = NULL;
-
-    _CFBundleAddPreferredLprojNamesInDirectory(alloc, url, localVersion, infoDict, langs, devLang);
-    
-    if (devLang && CFArrayGetFirstIndexOfValue(langs, CFRangeMake(0, CFArrayGetCount(langs)), devLang) < 0) CFArrayAppendValue(langs, devLang);
-
-    // Total backstop behavior to avoid having an empty array. 
-    if (CFArrayGetCount(langs) == 0) CFArrayAppendValue(langs, CFSTR("en"));
-    
-    if (infoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(infoDict);
-    if (version) *version = localVersion;
-    return langs;
-}
+#pragma mark -
 
 CF_EXPORT Boolean _CFBundleURLLooksLikeBundle(CFURLRef url) {
     Boolean result = false;
@@ -2135,6 +1152,7 @@ CF_EXPORT Boolean _CFBundleURLLooksLikeBundle(CFURLRef url) {
     return result;
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
 // Note that subDirName is expected to be the string for a URL
 CF_INLINE Boolean _CFBundleURLHasSubDir(CFURLRef url, CFStringRef subDirName) {
     Boolean isDir = false, result = false;
@@ -2145,8 +1163,9 @@ CF_INLINE Boolean _CFBundleURLHasSubDir(CFURLRef url, CFStringRef subDirName) {
     }
     return result;
 }
+#endif
 
-__private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint8_t *version) {
+CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url) {
     // check for existence of "Resources" or "Contents" or "Support Files"
     // but check for the most likely one first
     // version 0:  old-style "Resources" bundles
@@ -2154,28 +1173,69 @@ __private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint
     // version 2:  modern "Contents" bundles
     // version 3:  none of the above (see below)
     // version 4:  not a bundle (for main bundle only)
-    uint8_t localVersion = 3;
+    
     CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
     CFStringRef directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-    CFArrayRef contents = _CFBundleCopySortedDirectoryContentsAtPath(directoryPath, _CFBundleAllContents);
+    CFRelease(absoluteURL);
+    
     Boolean hasFrameworkSuffix = CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework/"));
 #if DEPLOYMENT_TARGET_WINDOWS
     hasFrameworkSuffix = hasFrameworkSuffix || CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework\\"));
 #endif
+
+    /*
+     #define _CFBundleSupportFilesDirectoryName1 CFSTR("Support Files")
+     #define _CFBundleSupportFilesDirectoryName2 CFSTR("Contents")
+     #define _CFBundleResourcesDirectoryName CFSTR("Resources")
+     #define _CFBundleExecutablesDirectoryName CFSTR("Executables")
+     #define _CFBundleNonLocalizedResourcesDirectoryName CFSTR("Non-localized Resources")
+    */
+    __block uint8_t localVersion = 3;
+    CFIndex resourcesDirectoryLength = CFStringGetLength(_CFBundleResourcesDirectoryName);
+    CFIndex contentsDirectoryLength = CFStringGetLength(_CFBundleSupportFilesDirectoryName2);
+    CFIndex supportFilesDirectoryLength = CFStringGetLength(_CFBundleSupportFilesDirectoryName1);
+    
+    __block Boolean foundResources = false;
+    __block Boolean foundSupportFiles2 = false;
+    __block Boolean foundSupportFiles1 = false;
+    
+    _CFIterateDirectory(directoryPath, ^Boolean (CFStringRef fileName, uint8_t fileType) {
+        // We're looking for a few different names, and also some info on if it's a directory or not.
+        // We don't stop looking once we find one of the names. Otherwise we could run into the situation where we have both "Contents" and "Resources" in a framework, and we see Contents first but Resources is more important.
+        if (fileType == DT_DIR || fileType == DT_LNK) {
+            CFIndex fileNameLen = CFStringGetLength(fileName);
+            if (fileNameLen == resourcesDirectoryLength && CFStringCompareWithOptions(fileName, _CFBundleResourcesDirectoryName, CFRangeMake(0, resourcesDirectoryLength), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+                foundResources = true;
+            } else if (fileNameLen == contentsDirectoryLength && CFStringCompareWithOptions(fileName, _CFBundleSupportFilesDirectoryName2, CFRangeMake(0, contentsDirectoryLength), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+                foundSupportFiles2 = true;
+            } else if (fileNameLen == supportFilesDirectoryLength && CFStringCompareWithOptions(fileName, _CFBundleSupportFilesDirectoryName1, CFRangeMake(0, supportFilesDirectoryLength), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+                foundSupportFiles1 = true;
+            }
+        }
+        return true;
+    });
     
+    // The order of these if statements is important - the Resources directory presence takes precedence over Contents, and so forth.
     if (hasFrameworkSuffix) {
-        if (_CFBundleSortedArrayContains(contents, _CFBundleResourcesDirectoryName)) localVersion = 0;
-        else if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName2)) localVersion = 2;
-        else if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName1)) localVersion = 1;
+        if (foundResources) {
+            localVersion = 0;
+        } else if (foundSupportFiles2) {
+            localVersion = 2;
+        } else if (foundSupportFiles1) {
+            localVersion = 1;
+        }
     } else {
-        if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName2)) localVersion = 2;
-        else if (_CFBundleSortedArrayContains(contents, _CFBundleResourcesDirectoryName)) localVersion = 0;
-        else if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName1)) localVersion = 1;
+        if (foundSupportFiles2) {
+            localVersion = 2;
+        } else if (foundResources) {
+            localVersion = 0;
+        } else if (foundSupportFiles1) {
+            localVersion = 1;
+        }
     }
-    if (contents) CFRelease(contents);
-    if (directoryPath) CFRelease(directoryPath);
-    if (absoluteURL) CFRelease(absoluteURL);
+    
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
+    // Do a more substantial check for the subdirectories that make up version 0/1/2 bundles. These are sometimes symlinks (like in Frameworks) and they would have been missed by our check above. Perhaps we can do a check for DT_LNK there as well, if it's sufficient instead of looking at the actual contents.
     if (localVersion == 3) {
         if (hasFrameworkSuffix) {
             if (_CFBundleURLHasSubDir(url, _CFBundleResourcesURLFromBase0)) localVersion = 0;
@@ -2188,478 +1248,13 @@ __private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint
         }
     }
 #endif
-    if (version) *version = localVersion;
-    return (localVersion != 3);
-}
-
-static Boolean _isValidPlatformSuffix(CFStringRef suffix) {
-    for (CFIndex idx = 0; idx < _CFBundleNumberOfPlatforms; idx++) {
-        if (CFEqual(suffix, _CFBundleSupportedPlatforms[idx])) return true;
-    }
-    return false;
-}
-
-static Boolean _isValidProductSuffix(CFStringRef suffix) {
-    for (CFIndex idx = 0; idx < _CFBundleNumberOfProducts; idx++) {
-        if (CFEqual(suffix, _CFBundleSupportedProducts[idx])) return true;
-    }
-    return false;
-}
-
-static Boolean _isValidiPhoneOSPlatformProductSuffix(CFStringRef suffix) {
-    for (CFIndex idx = 0; idx < _CFBundleNumberOfiPhoneOSPlatformProducts; idx++) {
-        if (CFEqual(suffix, _CFBundleSupportediPhoneOSPlatformProducts[idx])) return true;
-    }
-    return false;
-}
-
-static Boolean _isValidPlatformAndProductSuffixPair(CFStringRef platform, CFStringRef product) {
-    if (!platform && !product) return true;
-    if (!platform) {
-        return _isValidProductSuffix(product);
-    }
-    if (!product) {
-        return _isValidPlatformSuffix(platform);
-    }
-    if (CFEqual(platform, _CFBundleiPhoneOSPlatformName)) {
-        return _isValidiPhoneOSPlatformProductSuffix(product);
-    }
-    return false;
-}
-
-static Boolean _isBlacklistedKey(CFStringRef keyName) {
-#if __CONSTANT_STRINGS__
-#define _CFBundleNumberOfBlacklistedInfoDictionaryKeys 2
-    static const CFStringRef _CFBundleBlacklistedInfoDictionaryKeys[_CFBundleNumberOfBlacklistedInfoDictionaryKeys] = { CFSTR("CFBundleExecutable"), CFSTR("CFBundleIdentifier") };
-    
-    for (CFIndex idx = 0; idx < _CFBundleNumberOfBlacklistedInfoDictionaryKeys; idx++) {
-        if (CFEqual(keyName, _CFBundleBlacklistedInfoDictionaryKeys[idx])) return true;
-    }
-#endif
-    return false;
-}
-
-static Boolean _isOverrideKey(CFStringRef fullKey, CFStringRef *outBaseKey, CFStringRef *outPlatformSuffix, CFStringRef *outProductSuffix) {
-    if (outBaseKey) {
-        *outBaseKey = NULL;
-    }
-    if (outPlatformSuffix) {
-        *outPlatformSuffix = NULL;
-    }
-    if (outProductSuffix) {
-        *outProductSuffix = NULL;
-    }
-    if (!fullKey)
-        return false;
-    CFRange minusRange = CFStringFind(fullKey, CFSTR("-"), kCFCompareBackwards);
-    CFRange tildeRange = CFStringFind(fullKey, CFSTR("~"), kCFCompareBackwards);
-    if (minusRange.location == kCFNotFound && tildeRange.location == kCFNotFound) return false;
-    // minus must come before tilde if both are present
-    if (minusRange.location != kCFNotFound && tildeRange.location != kCFNotFound && tildeRange.location <= minusRange.location) return false;
-    
-    CFIndex strLen = CFStringGetLength(fullKey);
-    CFRange baseKeyRange = (minusRange.location != kCFNotFound) ? CFRangeMake(0, minusRange.location) : CFRangeMake(0, tildeRange.location);
-    CFRange platformRange = CFRangeMake(kCFNotFound, 0);
-    CFRange productRange = CFRangeMake(kCFNotFound, 0);
-    if (minusRange.location != kCFNotFound) {
-        platformRange.location = minusRange.location + minusRange.length;
-        platformRange.length = ((tildeRange.location != kCFNotFound) ? tildeRange.location : strLen) - platformRange.location;
-    }
-    if (tildeRange.location != kCFNotFound) {
-        productRange.location = tildeRange.location + tildeRange.length;
-        productRange.length = strLen - productRange.location;
-    }
-    if (baseKeyRange.length < 1) return false;
-    if (platformRange.location != kCFNotFound && platformRange.length < 1) return false;
-    if (productRange.location != kCFNotFound && productRange.length < 1) return false;
-    
-    CFStringRef platform = (platformRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefaultGCRefZero, fullKey, platformRange) : NULL;
-    CFStringRef product = (productRange.location != kCFNotFound) ? CFStringCreateWithSubstring(kCFAllocatorSystemDefaultGCRefZero, fullKey, productRange) : NULL;
-    Boolean result = _isValidPlatformAndProductSuffixPair(platform, product);
-    
-    if (result) {
-        if (outBaseKey) {
-            *outBaseKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefaultGCRefZero, fullKey, baseKeyRange);
-        }
-        if (outPlatformSuffix) {
-            *outPlatformSuffix = platform;
-        } else {
-            if (platform && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(platform);
-        }
-        if (outProductSuffix) {
-            *outProductSuffix = product;
-        } else {
-            if (product && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(product);
-        }
-    } else {
-        if (platform && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(platform);
-        if (product && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(product);
-    }
-    return result;
-}
-    
-static Boolean _isCurrentPlatformAndProduct(CFStringRef platform, CFStringRef product) {
-    if (!platform && !product) return true;
-    if (!platform) {
-        return CFEqual(_CFGetProductName(), product);
-    }
-    if (!product) {
-        return CFEqual(_CFGetPlatformName(), platform);
-    }
-    
-    return CFEqual(_CFGetProductName(), product) && CFEqual(_CFGetPlatformName(), platform);
-}
-    
-static CFArrayRef _CopySortedOverridesForBaseKey(CFStringRef keyName, CFDictionaryRef dict) {
-    CFMutableArrayRef overrides = CFArrayCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, &kCFTypeArrayCallBacks);
-    CFStringRef keyNameWithBoth = CFStringCreateWithFormat(kCFAllocatorSystemDefaultGCRefZero, NULL, CFSTR("%@-%@~%@"), keyName, _CFGetPlatformName(), _CFGetProductName());
-    CFStringRef keyNameWithProduct = CFStringCreateWithFormat(kCFAllocatorSystemDefaultGCRefZero, NULL, CFSTR("%@~%@"), keyName, _CFGetProductName());
-    CFStringRef keyNameWithPlatform = CFStringCreateWithFormat(kCFAllocatorSystemDefaultGCRefZero, NULL, CFSTR("%@-%@"), keyName, _CFGetPlatformName());
-
-    CFIndex count = CFDictionaryGetCount(dict);
-    
-    if (count > 0) {
-        CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), 0);
-        CFTypeRef *values = &(keys[count]);
-        
-        CFDictionaryGetKeysAndValues(dict, keys, values);
-        for (CFIndex idx = 0; idx < count; idx++) {
-                       if (CFEqual(keys[idx], keyNameWithBoth)) {
-                               CFArrayAppendValue(overrides, keys[idx]);
-                               break;
-                       }
-               }
-        for (CFIndex idx = 0; idx < count; idx++) {
-                       if (CFEqual(keys[idx], keyNameWithProduct)) {
-                               CFArrayAppendValue(overrides, keys[idx]);
-                               break;
-                       }
-               }
-        for (CFIndex idx = 0; idx < count; idx++) {
-                       if (CFEqual(keys[idx], keyNameWithPlatform)) {
-                               CFArrayAppendValue(overrides, keys[idx]);
-                               break;
-                       }
-               }
-        for (CFIndex idx = 0; idx < count; idx++) {
-                       if (CFEqual(keys[idx], keyName)) {
-                               CFArrayAppendValue(overrides, keys[idx]);
-                               break;
-                       }
-               }
-
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) {
-            CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, keys);
-               }
-       }
-
-       if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) {
-               CFRelease(keyNameWithProduct);
-               CFRelease(keyNameWithPlatform);
-               CFRelease(keyNameWithBoth);
-       }
-
-    return overrides;
-}
-
-__private_extern__ void _processInfoDictionary(CFMutableDictionaryRef dict, CFStringRef platformSuffix, CFStringRef productSuffix) {
-    CFIndex count = CFDictionaryGetCount(dict);
-    
-    if (count > 0) {
-        CFTypeRef *keys = (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), 0);
-        CFTypeRef *values = &(keys[count]);
-        CFMutableArrayRef guard = CFArrayCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, &kCFTypeArrayCallBacks);
-        
-        CFDictionaryGetKeysAndValues(dict, keys, values);
-        for (CFIndex idx = 0; idx < count; idx++) {
-            CFStringRef keyPlatformSuffix, keyProductSuffix, keyName;
-            if (_isOverrideKey((CFStringRef)keys[idx], &keyName, &keyPlatformSuffix, &keyProductSuffix)) {
-                CFArrayRef keysForBaseKey = NULL;
-                if (_isCurrentPlatformAndProduct(keyPlatformSuffix, keyProductSuffix) && !_isBlacklistedKey(keyName) && CFDictionaryContainsKey(dict, keys[idx])) {
-                    keysForBaseKey = _CopySortedOverridesForBaseKey(keyName, dict);
-                    CFIndex keysForBaseKeyCount = CFArrayGetCount(keysForBaseKey);
-                    
-                    //make sure the other keys for this base key don't get released out from under us until we're done
-                    CFArrayAppendValue(guard, keysForBaseKey); 
-                    
-                    //the winner for this base key will be sorted to the front, do the override with it
-                    CFTypeRef highestPriorityKey = CFArrayGetValueAtIndex(keysForBaseKey, 0);
-                    CFDictionarySetValue(dict, keyName, CFDictionaryGetValue(dict, highestPriorityKey));
-                    
-                    //remove everything except the now-overridden key; this will cause them to fail the CFDictionaryContainsKey(dict, keys[idx]) check in the enclosing if() and not be reprocessed
-                    for (CFIndex presentKeysIdx = 0; presentKeysIdx < keysForBaseKeyCount; presentKeysIdx++) {
-                        CFStringRef currentKey = (CFStringRef)CFArrayGetValueAtIndex(keysForBaseKey, presentKeysIdx);
-                        if (!CFEqual(currentKey, keyName))
-                            CFDictionaryRemoveValue(dict, currentKey);
-                    }
-                } else {
-                    CFDictionaryRemoveValue(dict, keys[idx]);
-                }
-
-                
-                if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) {
-                    if (keyPlatformSuffix) CFRelease(keyPlatformSuffix);
-                    if (keyProductSuffix) CFRelease(keyProductSuffix);
-                    CFRelease(keyName);
-                    if (keysForBaseKey) CFRelease(keysForBaseKey);
-                }
-            }
-        }
-        
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) {
-            CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, keys);
-            CFRelease(guard);
-        }
-    }
-}      
-
-// returns zero-ref dictionary under GC if given kCFAllocatorSystemDefaultGCRefZero
-__private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) {
-    CFDictionaryRef dict = NULL;
-    unsigned char buff[CFMaxPathSize];
-    uint8_t localVersion = 0;
-    
-    if (CFURLGetFileSystemRepresentation(url, true, buff, CFMaxPathSize)) {
-        CFURLRef newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true);
-        if (!newURL) newURL = (CFURLRef)CFRetain(url);
-
-        // version 3 is for flattened pseudo-bundles with no Contents, Support Files, or Resources directories
-        if (!_CFBundleURLLooksLikeBundleVersion(newURL, &localVersion)) localVersion = 3;
-        
-        dict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(alloc, newURL, localVersion);
-        CFRelease(newURL);
-    }
-    if (version) *version = localVersion;
-    return dict;
-}
-
-// returns zero-ref dictionary under GC if given kCFAllocatorSystemDefaultGCRefZero
-__private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, uint8_t version) {
-    CFDictionaryRef result = NULL;
-    if (url) {
-        CFURLRef infoURL = NULL, rawInfoURL = NULL;
-        CFDataRef infoData = NULL;
-        UniChar buff[CFMaxPathSize];
-        CFIndex len;
-        CFMutableStringRef cheapStr;
-        CFStringRef infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension0, infoURLFromBase = _CFBundleInfoURLFromBase0;
-        Boolean tryPlatformSpecific = true, tryGlobal = true;
-        CFURLRef directoryURL = NULL, absoluteURL;
-        CFStringRef directoryPath;
-        CFArrayRef contents = NULL;
-        CFRange contentsRange = CFRangeMake(0, 0);
-
-        _CFEnsureStaticBuffersInited();
-
-        if (0 == version) {
-            directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleResourcesURLFromBase0, url);
-            infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension0;
-            infoURLFromBase = _CFBundleInfoURLFromBase0;
-        } else if (1 == version) {
-            directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase1, url);
-            infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension1;
-            infoURLFromBase = _CFBundleInfoURLFromBase1;
-        } else if (2 == version) {
-            directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase2, url);
-            infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension2;
-            infoURLFromBase = _CFBundleInfoURLFromBase2;
-        } else if (3 == version) {
-            CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
-            // this test is necessary to exclude the case where a bundle is spuriously created from the innards of another bundle
-            if (path) {
-                if (!(CFStringHasSuffix(path, _CFBundleSupportFilesDirectoryName1) || CFStringHasSuffix(path, _CFBundleSupportFilesDirectoryName2) || CFStringHasSuffix(path, _CFBundleResourcesDirectoryName))) {
-                    directoryURL = (CFURLRef)CFRetain(url);
-                    infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension3;
-                    infoURLFromBase = _CFBundleInfoURLFromBase3;
-                }
-                CFRelease(path);
-            }
-        }
-        if (directoryURL) {
-            absoluteURL = CFURLCopyAbsoluteURL(directoryURL);
-            directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-            contents = _CFBundleCopySortedDirectoryContentsAtPath(directoryPath, _CFBundleAllContents);
-            contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-            if (directoryPath) CFRelease(directoryPath);
-            if (absoluteURL) CFRelease(absoluteURL);
-            if (directoryURL) CFRelease(directoryURL);
-        }
-
-        len = CFStringGetLength(infoURLFromBaseNoExtension);
-        CFStringGetCharacters(infoURLFromBaseNoExtension, CFRangeMake(0, len), buff);
-        buff[len++] = (UniChar)'-';
-        memmove(buff + len, _PlatformUniChars, _PlatformLen * sizeof(UniChar));
-        len += _PlatformLen;
-        _CFAppendPathExtension(buff, &len, CFMaxPathSize, _InfoExtensionUniChars, _InfoExtensionLen);
-        cheapStr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
-        CFStringAppendCharacters(cheapStr, buff, len);
-        infoURL = CFURLCreateWithString(kCFAllocatorSystemDefault, cheapStr, url);
-        if (contents) {
-            CFIndex resourcesLen, idx;
-            for (resourcesLen = len; resourcesLen > 0; resourcesLen--) if (buff[resourcesLen - 1] == PATH_SEP) break;
-            CFStringDelete(cheapStr, CFRangeMake(0, CFStringGetLength(cheapStr)));
-            CFStringAppendCharacters(cheapStr, buff + resourcesLen, len - resourcesLen);
-            for (tryPlatformSpecific = false, idx = 0; !tryPlatformSpecific && idx < contentsRange.length; idx++) {
-                // Need to do this case-insensitive to accommodate Palm
-                if (kCFCompareEqualTo == CFStringCompare(cheapStr, (CFStringRef)CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryPlatformSpecific = true;
-            }
-        }
-        if (tryPlatformSpecific) CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, infoURL, &infoData, NULL, NULL, NULL);
-        //fprintf(stderr, "looking for ");CFShow(infoURL);fprintf(stderr, infoData ? "found it\n" : (tryPlatformSpecific ? "missed it\n" : "skipped it\n"));
-        CFRelease(cheapStr);
-        if (!infoData) {
-            // Check for global Info.plist
-            CFRelease(infoURL);
-            infoURL = CFURLCreateWithString(kCFAllocatorSystemDefault, infoURLFromBase, url);
-            if (contents) {
-                CFIndex idx;
-                for (tryGlobal = false, idx = 0; !tryGlobal && idx < contentsRange.length; idx++) {
-                    // Need to do this case-insensitive to accommodate Palm
-                    if (kCFCompareEqualTo == CFStringCompare(_CFBundleInfoFileName, (CFStringRef)CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryGlobal = true;
-                }
-            }
-            if (tryGlobal) CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, infoURL, &infoData, NULL, NULL, NULL);
-            //fprintf(stderr, "looking for ");CFShow(infoURL);fprintf(stderr, infoData ? "found it\n" : (tryGlobal ? "missed it\n" : "skipped it\n"));
-        }
-        
-        if (infoData) {
-            result = (CFDictionaryRef)CFPropertyListCreateFromXMLData(alloc, infoData, kCFPropertyListMutableContainers, NULL);
-            if (result) {
-                if (CFDictionaryGetTypeID() == CFGetTypeID(result)) {
-                    CFDictionarySetValue((CFMutableDictionaryRef)result, _kCFBundleInfoPlistURLKey, infoURL);
-                } else {
-                    if (!_CFAllocatorIsGCRefZero(alloc)) CFRelease(result);
-                    result = NULL;
-                }
-            }
-            if (!result) rawInfoURL = infoURL;
-            CFRelease(infoData);
-        }
-        if (!result) {
-            result = CFDictionaryCreateMutable(alloc, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-            if (rawInfoURL) CFDictionarySetValue((CFMutableDictionaryRef)result, _kCFBundleRawInfoPlistURLKey, rawInfoURL);
-        }
-
-        CFRelease(infoURL);
-        if (contents) CFRelease(contents);
-    }
-    _processInfoDictionary((CFMutableDictionaryRef)result, _CFGetPlatformName(), _CFGetProductName());
-    return result;
-}
-
-static Boolean _CFBundleGetPackageInfoInDirectoryWithInfoDictionary(CFAllocatorRef alloc, CFURLRef url, CFDictionaryRef infoDict, UInt32 *packageType, UInt32 *packageCreator) {
-    Boolean retVal = false, hasType = false, hasCreator = false, releaseInfoDict = false;
-    CFURLRef tempURL;
-    CFDataRef pkgInfoData = NULL;
-
-    // Check for a "real" new bundle
-    tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePkgInfoURLFromBase2, url);
-    CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
-    CFRelease(tempURL);
-    if (!pkgInfoData) {
-        tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePkgInfoURLFromBase1, url);
-        CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
-        CFRelease(tempURL);
-    }
-    if (!pkgInfoData) {
-        // Check for a "pseudo" new bundle
-        tempURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundlePseudoPkgInfoURLFromBase, url);
-        CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tempURL, &pkgInfoData, NULL, NULL, NULL);
-        CFRelease(tempURL);
-    }
-
-    // Now, either we have a pkgInfoData or not.  If not, then is it because this is a new bundle without one (do we allow this?), or is it dbecause it is an old bundle.
-    // If we allow new bundles to not have a PkgInfo (because they already have the same data in the Info.plist), then we have to go read the info plist which makes failure expensive.
-    // drd: So we assume that a new bundle _must_ have a PkgInfo if they have this data at all, otherwise we manufacture it from the extension.
-    
-    if (pkgInfoData && CFDataGetLength(pkgInfoData) >= (int)(sizeof(UInt32) * 2)) {
-        UInt32 *pkgInfo = (UInt32 *)CFDataGetBytePtr(pkgInfoData);
-        if (packageType) *packageType = CFSwapInt32BigToHost(pkgInfo[0]);
-        if (packageCreator) *packageCreator = CFSwapInt32BigToHost(pkgInfo[1]);
-        retVal = hasType = hasCreator = true;
-    }
-    if (pkgInfoData) CFRelease(pkgInfoData);
-    if (!retVal) {
-        if (!infoDict) {
-            infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefaultGCRefZero, url, NULL);
-            releaseInfoDict = true;
-        }
-        if (infoDict) {
-            CFStringRef typeString = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundlePackageTypeKey), creatorString = (CFStringRef)CFDictionaryGetValue(infoDict, _kCFBundleSignatureKey);
-            UInt32 tmp;
-            CFIndex usedBufLen = 0;
-            if (typeString && CFGetTypeID(typeString) == CFStringGetTypeID() && CFStringGetLength(typeString) == 4 && 4 == CFStringGetBytes(typeString, CFRangeMake(0, 4), kCFStringEncodingMacRoman, 0, false, (UInt8 *)&tmp, 4, &usedBufLen) && 4 == usedBufLen) {
-                if (packageType) *packageType = CFSwapInt32BigToHost(tmp);
-                retVal = hasType = true;
-            }
-            if (creatorString && CFGetTypeID(creatorString) == CFStringGetTypeID() && CFStringGetLength(creatorString) == 4 && 4 == CFStringGetBytes(creatorString, CFRangeMake(0, 4), kCFStringEncodingMacRoman, 0, false, (UInt8 *)&tmp, 4, &usedBufLen) && 4 == usedBufLen) {
-                if (packageCreator) *packageCreator = CFSwapInt32BigToHost(tmp);
-                retVal = hasCreator = true;
-            }
-            if (releaseInfoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(infoDict);
-        }
-    }
-    if (!hasType || !hasCreator) {
-        // If this looks like a bundle then manufacture the type and creator.
-        if (retVal || _CFBundleURLLooksLikeBundle(url)) {
-            if (packageCreator && !hasCreator) *packageCreator = 0x3f3f3f3f;  // '????'
-            if (packageType && !hasType) {
-                CFStringRef urlStr;
-                UniChar buff[CFMaxPathSize];
-                CFIndex strLen, startOfExtension;
-                CFURLRef absoluteURL;
-                
-                // Detect "app", "debug", "profile", or "framework" extensions
-                absoluteURL = CFURLCopyAbsoluteURL(url);
-                urlStr = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-                CFRelease(absoluteURL);
-                strLen = CFStringGetLength(urlStr);
-                if (strLen > CFMaxPathSize) strLen = CFMaxPathSize;
-                CFStringGetCharacters(urlStr, CFRangeMake(0, strLen), buff);
-                CFRelease(urlStr);
-                startOfExtension = _CFStartOfPathExtension(buff, strLen);
-                if ((strLen - startOfExtension == 4 || strLen - startOfExtension == 5) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'a' && buff[startOfExtension+2] == (UniChar)'p' && buff[startOfExtension+3] == (UniChar)'p' && (strLen - startOfExtension == 4 || buff[startOfExtension+4] == (UniChar)PATH_SEP)) {
-                    // This is an app
-                    *packageType = 0x4150504c;  // 'APPL'
-                } else if ((strLen - startOfExtension == 6 || strLen - startOfExtension == 7) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'d' && buff[startOfExtension+2] == (UniChar)'e' && buff[startOfExtension+3] == (UniChar)'b' && buff[startOfExtension+4] == (UniChar)'u' && buff[startOfExtension+5] == (UniChar)'g' && (strLen - startOfExtension == 6 || buff[startOfExtension+6] == (UniChar)PATH_SEP)) {
-                    // This is an app (debug version)
-                    *packageType = 0x4150504c;  // 'APPL'
-                } else if ((strLen - startOfExtension == 8 || strLen - startOfExtension == 9) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'p' && buff[startOfExtension+2] == (UniChar)'r' && buff[startOfExtension+3] == (UniChar)'o' && buff[startOfExtension+4] == (UniChar)'f' && buff[startOfExtension+5] == (UniChar)'i' && buff[startOfExtension+6] == (UniChar)'l' && buff[startOfExtension+7] == (UniChar)'e' && (strLen - startOfExtension == 8 || buff[startOfExtension+8] == (UniChar)PATH_SEP)) {
-                    // This is an app (profile version)
-                    *packageType = 0x4150504c;  // 'APPL'
-                } else if ((strLen - startOfExtension == 8 || strLen - startOfExtension == 9) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'s' && buff[startOfExtension+2] == (UniChar)'e' && buff[startOfExtension+3] == (UniChar)'r' && buff[startOfExtension+4] == (UniChar)'v' && buff[startOfExtension+5] == (UniChar)'i' && buff[startOfExtension+6] == (UniChar)'c' && buff[startOfExtension+7] == (UniChar)'e' && (strLen - startOfExtension == 8 || buff[startOfExtension+8] == (UniChar)PATH_SEP)) {
-                    // This is a service
-                    *packageType = 0x4150504c;  // 'APPL'
-                } else if ((strLen - startOfExtension == 10 || strLen - startOfExtension == 11) && buff[startOfExtension] == (UniChar)'.' && buff[startOfExtension+1] == (UniChar)'f' && buff[startOfExtension+2] == (UniChar)'r' && buff[startOfExtension+3] == (UniChar)'a' && buff[startOfExtension+4] == (UniChar)'m' && buff[startOfExtension+5] == (UniChar)'e' && buff[startOfExtension+6] == (UniChar)'w' && buff[startOfExtension+7] == (UniChar)'o' && buff[startOfExtension+8] == (UniChar)'r' && buff[startOfExtension+9] == (UniChar)'k' && (strLen - startOfExtension == 10 || buff[startOfExtension+10] == (UniChar)PATH_SEP)) {
-                    // This is a framework
-                    *packageType = 0x464d574b;  // 'FMWK'
-                } else {
-                    // Default to BNDL for generic bundle
-                    *packageType = 0x424e444c;  // 'BNDL'
-                }
-            }
-            retVal = true;
-        }
-    }
-    return retVal;
-}
 
-CF_EXPORT Boolean _CFBundleGetPackageInfoInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt32 *packageType, UInt32 *packageCreator) {
-    return _CFBundleGetPackageInfoInDirectoryWithInfoDictionary(alloc, url, NULL, packageType, packageCreator);
+    CFRelease(directoryPath);
+    return localVersion;
 }
 
-CF_EXPORT void CFBundleGetPackageInfo(CFBundleRef bundle, UInt32 *packageType, UInt32 *packageCreator) {
-    CFURLRef bundleURL = CFBundleCopyBundleURL(bundle);
-    if (!_CFBundleGetPackageInfoInDirectoryWithInfoDictionary(kCFAllocatorSystemDefault, bundleURL, CFBundleGetInfoDictionary(bundle), packageType, packageCreator)) {
-        if (packageType) *packageType = 0x424e444c;  // 'BNDL'
-        if (packageCreator) *packageCreator = 0x3f3f3f3f;  // '????'
-    }
-    if (bundleURL) CFRelease(bundleURL);
-}
-
-CF_EXPORT Boolean CFBundleGetPackageInfoInDirectory(CFURLRef url, UInt32 *packageType, UInt32 *packageCreator) {
-    return _CFBundleGetPackageInfoInDirectory(kCFAllocatorSystemDefault, url, packageType, packageCreator);
-}
+#pragma mark -
+#pragma mark Platforms
 
 static void _CFBundleCheckSupportedPlatform(CFMutableArrayRef mutableArray, UniChar *buff, CFIndex startLen, CFStringRef platformName, CFStringRef platformIdentifier) {
     CFIndex buffLen = startLen, platformLen = CFStringGetLength(platformName), extLen = CFStringGetLength(_CFBundleInfoExtension);
@@ -2742,7 +1337,7 @@ CF_EXPORT CFStringRef _CFBundleGetCurrentPlatform(void) {
 #endif
 }
 
-__private_extern__ CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void) {
+CF_PRIVATE CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("MacOS");
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -2760,7 +1355,7 @@ __private_extern__ CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(v
 #endif
 }
 
-__private_extern__ CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void) {
+CF_PRIVATE CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("Mac OS X");
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -2778,7 +1373,7 @@ __private_extern__ CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirect
 #endif
 }
 
-__private_extern__ CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void) {
+CF_PRIVATE CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("MacOSClassic");
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -2796,7 +1391,7 @@ __private_extern__ CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryN
 #endif
 }
 
-__private_extern__ CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(void) {
+CF_PRIVATE CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(void) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("Mac OS 8");
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -2814,79 +1409,6 @@ __private_extern__ CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubd
 #endif
 }
 
-__private_extern__ CFArrayRef _CFBundleCopyBundleRegionsArray(CFBundleRef bundle) {
-    return CFBundleCopyBundleLocalizations(bundle);
-}
-
-CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) {
-    CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
-    CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
-    CFURLRef absoluteURL;
-    CFStringRef directoryPath;
-    CFArrayRef contents;
-    CFRange contentsRange;
-    CFIndex idx;
-    CFArrayRef predefinedLocalizations = NULL;
-    CFMutableArrayRef result = NULL;
-
-    if (infoDict) {
-        predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
-        if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) != CFArrayGetTypeID()) {
-            predefinedLocalizations = NULL;
-            CFDictionaryRemoveValue((CFMutableDictionaryRef)infoDict, kCFBundleLocalizationsKey);
-        }
-        if (predefinedLocalizations) {
-            CFIndex i, c = CFArrayGetCount(predefinedLocalizations);
-            if (c > 0 && !result) result = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &kCFTypeArrayCallBacks);
-            for (i = 0; i < c; i++) CFArrayAppendValue(result, CFArrayGetValueAtIndex(predefinedLocalizations, i));
-        }
-    }
-
-    if (resourcesURL) {
-        absoluteURL = CFURLCopyAbsoluteURL(resourcesURL);
-        directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
-        contents = _CFBundleCopySortedDirectoryContentsAtPath(directoryPath, _CFBundleAllContents);
-        contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-        for (idx = 0; idx < contentsRange.length; idx++) {
-            CFStringRef name = (CFStringRef)CFArrayGetValueAtIndex(contents, idx);
-            if (CFStringHasSuffix(name, _CFBundleLprojExtensionWithDot)) {
-                CFStringRef localization = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, name, CFRangeMake(0, CFStringGetLength(name) - 6));
-                if (!result) result = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &kCFTypeArrayCallBacks);
-                CFArrayAppendValue(result, localization);
-                CFRelease(localization);
-            }
-        }
-        if (contents) CFRelease(contents);
-        if (directoryPath) CFRelease(directoryPath);
-        if (absoluteURL) CFRelease(absoluteURL);
-    }
-    
-    if (!result) {
-        CFStringRef developmentLocalization = CFBundleGetDevelopmentRegion(bundle);
-        if (developmentLocalization) {
-            result = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &kCFTypeArrayCallBacks);
-            CFArrayAppendValue(result, developmentLocalization);
-        }
-    }
-    if (resourcesURL) CFRelease(resourcesURL);
-    return result;
-}
-
-
-CF_EXPORT CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url) {
-    CFDictionaryRef result = NULL;
-    Boolean isDir = false;
-    if (_CFIsResourceAtURL(url, &isDir)) {
-        if (isDir) {
-            result = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefaultGCRefZero, url, NULL);
-        } else {
-            result = _CFBundleCopyInfoDictionaryInExecutable(url);  // return zero-ref dictionary under GC
-        }
-    }
-    if (result && _CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRetain(result); // conditionally put on a retain for a Copy function
-    return result;
-}
-
 CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) {
     CFArrayRef result = NULL;
     CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url);
@@ -2899,30 +1421,29 @@ CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) {
     return result;
 }
 
-CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url) {
-    CFArrayRef result = NULL;
-    CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url);
-    CFStringRef devLang = NULL;
-    if (bundle) {
-        result = CFBundleCopyBundleLocalizations(bundle);
-        CFRelease(bundle);
-    } else {
-        CFDictionaryRef infoDict = _CFBundleCopyInfoDictionaryInExecutable(url);  // return zero-ref dictionary under GC
-        if (infoDict) {
-            CFArrayRef predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
-            if (predefinedLocalizations && CFGetTypeID(predefinedLocalizations) == CFArrayGetTypeID()) result = (CFArrayRef)CFRetain(predefinedLocalizations);
-            if (!result) {
-                devLang = (CFStringRef)CFDictionaryGetValue(infoDict, kCFBundleDevelopmentRegionKey);
-                if (devLang && (CFGetTypeID(devLang) == CFStringGetTypeID() && CFStringGetLength(devLang) > 0)) result = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&devLang, 1, &kCFTypeArrayCallBacks);
-            }
-            if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(infoDict);
-        }
+#pragma mark -
+#pragma mark Resource Lookup - Query Table
+
+static void _CFBundleAddValueForType(CFStringRef type, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFTypeRef value, CFMutableDictionaryRef addedTypes, Boolean firstLproj) {
+    CFMutableArrayRef tFiles = (CFMutableArrayRef) CFDictionaryGetValue(typeDir, type);
+    if (!tFiles) {
+        CFStringRef key = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@.%@"), _CFBundleTypeIndicator, type);
+        tFiles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+        CFDictionarySetValue(queryTable, key, tFiles);
+        CFDictionarySetValue(typeDir, type, tFiles);
+        CFRelease(tFiles);
+        CFRelease(key);
+    }
+    if (!addedTypes) {
+        CFArrayAppendValue(tFiles, value);
+    } else if (firstLproj) {
+        CFDictionarySetValue(addedTypes, type, type);
+        CFArrayAppendValue(tFiles, value);
+    } else if (!(CFDictionaryGetValue(addedTypes, type))) {
+        CFArrayAppendValue(tFiles, value);
     }
-    return result;
 }
 
-    
 CF_INLINE Boolean _CFBundleFindCharacterInStr(const UniChar *str, UniChar c, Boolean backward, CFIndex start, CFIndex length, CFRange *result){
     *result = CFRangeMake(kCFNotFound, 0);
     Boolean found = false;
@@ -2946,7 +1467,6 @@ CF_INLINE Boolean _CFBundleFindCharacterInStr(const UniChar *str, UniChar c, Boo
     return found;
 }
 
-
 typedef enum {
     _CFBundleFileVersionNoProductNoPlatform = 1,
     _CFBundleFileVersionWithProductNoPlatform,
@@ -2955,52 +1475,31 @@ typedef enum {
     _CFBundleFileVersionUnmatched
 } _CFBundleFileVersion;
 
-static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef file, UniChar *fileBuffer1, CFIndex fileLen, CFRange searchRange, CFStringRef product, CFStringRef platform, CFRange* prodp, CFRange* platp, CFIndex prodLen)
+static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef file, CFRange searchRange, CFStringRef product, CFStringRef platform)
 {
     _CFBundleFileVersion version;
-    CFRange found;
     Boolean foundprod, foundplat;
     foundplat = foundprod = NO;
-    UniChar fileBuffer2[CFMaxPathSize];
-    UniChar *fileBuffer;
     Boolean wrong = false;
     
-    if (fileBuffer1) {
-        fileBuffer = fileBuffer1;
-    }else{
-        fileLen = CFStringGetLength(file);
-        if (fileLen > CFMaxPathSize) fileLen = CFMaxPathSize;
-        CFStringGetCharacters(file, CFRangeMake(0, fileLen), fileBuffer2);
-        fileBuffer = fileBuffer2;
-    }
-        
-    if (_CFBundleFindCharacterInStr(fileBuffer, '~', NO, searchRange.location, searchRange.length, &found)) {
-        if (prodLen != 1) {
-            if (CFStringFindWithOptions(file, product, searchRange, kCFCompareEqualTo, prodp)) {
+    if (CFStringFindWithOptions(file, CFSTR("~"), searchRange, 0, NULL)) {
+        if (CFStringGetLength(product) != 1) {
+            // todo: really, search the same range again?
+            if (CFStringFindWithOptions(file, product, searchRange, kCFCompareEqualTo, NULL)) {
                 foundprod = YES;
             }
         }
         if (!foundprod) {
-            for (CFIndex i = 0; i < _CFBundleNumberOfProducts; i++) {
-                if (CFStringFindWithOptions(file, _CFBundleSupportedProducts[i], searchRange, kCFCompareEqualTo, &found)) {
-                    wrong = true;
-                    break;
-                }
-            }
+            wrong = _CFBundleSupportedProductName(file, searchRange);
         }
     }
-
-    if (!wrong && _CFBundleFindCharacterInStr(fileBuffer, '-', NO, searchRange.location, searchRange.length, &found)) {
-        if (CFStringFindWithOptions(file, platform, searchRange, kCFCompareEqualTo, platp)) {
+    
+    if (!wrong && CFStringFindWithOptions(file, CFSTR("-"), searchRange, 0, NULL)) {
+        if (CFStringFindWithOptions(file, platform, searchRange, kCFCompareEqualTo, NULL)) {
             foundplat = YES;
         }
         if (!foundplat) {
-            for (CFIndex i = 0; i < _CFBundleNumberOfPlatforms; i++) {
-                if (CFStringFindWithOptions(file, _CFBundleSupportedPlatforms[i], searchRange, kCFCompareEqualTo, &found)) {
-                    wrong = true;
-                    break;
-                }
-            }
+            wrong = _CFBundleSupportedPlatformName(file, searchRange);
         }
     }
     
@@ -3008,9 +1507,57 @@ static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef fil
         version = _CFBundleFileVersionUnmatched;
     } else if (foundplat && foundprod) {
         version = _CFBundleFileVersionWithProductWithPlatform;
-    } else if (foundplat) {
+    } else if (foundplat) {
+        version = _CFBundleFileVersionNoProductWithPlatform;
+    } else if (foundprod) {
+        version = _CFBundleFileVersionWithProductNoPlatform;
+    } else {
+        version = _CFBundleFileVersionNoProductNoPlatform;
+    }
+    return version;
+}
+
+static _CFBundleFileVersion _CFBundleVersionForFileName(CFStringRef fileName, CFStringRef expectedProduct, CFStringRef expectedPlatform, CFRange *outProductRange, CFRange *outPlatformRange) {
+    // Search for a product name, e.g.: foo~iphone.jpg or bar~ipad
+    Boolean foundProduct = false;
+    Boolean foundPlatform = false;
+    CFIndex fileNameLen = CFStringGetLength(fileName);
+    CFRange productRange;
+    CFRange platformRange;
+    
+    CFIndex dotLocation = fileNameLen;
+    for (CFIndex i = fileNameLen - 1; i > 0; i--) {
+        UniChar c = CFStringGetCharacterAtIndex(fileName, i);
+        if (c == '.') {
+            dotLocation = i;
+        }
+#if DEPLOYMENT_TARGET_EMBEDDED
+        // Product names are only supported on iOS
+        // ref docs here: "iOS Supports Device-Specific Resources" in "Resource Programming Guide"
+        else if (c == '~' && !foundProduct) {
+            productRange = CFRangeMake(i, dotLocation - i);
+            foundProduct = (CFStringCompareWithOptions(fileName, expectedProduct, productRange, kCFCompareAnchored) == kCFCompareEqualTo);
+            if (foundProduct && outProductRange) *outProductRange = productRange;
+        }
+#endif
+        else if (c == '-') {
+            if (foundProduct) {
+                platformRange = CFRangeMake(i, productRange.location - i);
+            } else {
+                platformRange = CFRangeMake(i, dotLocation - i);
+            }
+            foundPlatform = (CFStringCompareWithOptions(fileName, expectedPlatform, platformRange, kCFCompareAnchored) == kCFCompareEqualTo);
+            if (foundPlatform && outPlatformRange) *outPlatformRange = platformRange;
+            break;
+        }
+    }
+    
+    _CFBundleFileVersion version;
+    if (foundPlatform && foundProduct) {
+        version = _CFBundleFileVersionWithProductWithPlatform;
+    } else if (foundPlatform) {
         version = _CFBundleFileVersionNoProductWithPlatform;
-    } else if (foundprod) {
+    } else if (foundProduct) {
         version = _CFBundleFileVersionWithProductNoPlatform;
     } else {
         version = _CFBundleFileVersionNoProductNoPlatform;
@@ -3018,290 +1565,217 @@ static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef fil
     return version;
 }
 
+// Splits up a string into its various parts. Note that the out-types must be released by the caller if they exist.
+static void _CFBundleSplitFileName(CFStringRef fileName, CFStringRef *noProductOrPlatform, CFStringRef *endType, CFStringRef *startType, CFStringRef expectedProduct, CFStringRef expectedPlatform, _CFBundleFileVersion *version) {
+    CFIndex fileNameLen = CFStringGetLength(fileName);
     
-// ZFH
+    if (endType || startType) {
+        // Search for the type from the end (type defined as everything after the last '.')
+        // e.g., a file name like foo.jpg has a type of 'jpg'
+        Boolean foundDot = false;
+        uint16_t dotLocation = 0;
+        for (CFIndex i = fileNameLen; i > 0; i--) {
+            if (CFStringGetCharacterAtIndex(fileName, i - 1) == '.') {
+                foundDot = true;
+                dotLocation = i - 1;
+                break;
+            }
+        }
+        
+        if (foundDot && dotLocation != fileNameLen - 1) {
+            if (endType) *endType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(dotLocation + 1, CFStringGetLength(fileName) - dotLocation - 1));
+        }
+        
+        // Search for the type from the beginning (type defined as everything after the first '.')
+        // e.g., a file name like foo.jpg.gz has a type of 'jpg.gz'
+        if (startType) {
+            for (CFIndex i = 0; i < fileNameLen; i++) {
+                if (CFStringGetCharacterAtIndex(fileName, i) == '.') {
+                    // no need to create this again if it's the same as previous
+                    if (i != dotLocation) {
+                        *startType = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, fileName, CFRangeMake(i + 1, CFStringGetLength(fileName) - i - 1));
+                    }
+                    break;
+                }
+            }
+        }
+    }
     
+    CFRange productRange, platformRange;
+    *version = _CFBundleVersionForFileName(fileName, expectedProduct, expectedPlatform, &productRange, &platformRange);
     
-static void _CFBundleAddValueForType(CFMutableStringRef type, UniChar* fileNameBuffer, CFMutableDictionaryRef queryTable, CFRange dotPosition, CFIndex fileLen, CFMutableDictionaryRef typeDir, CFTypeRef value, CFMutableDictionaryRef addedTypes, Boolean firstLproj){
-    CFIndex typeLen = fileLen - dotPosition.location - 1;
-    CFStringSetExternalCharactersNoCopy(type, fileNameBuffer+dotPosition.location+1, typeLen, typeLen);
-    CFMutableArrayRef tFiles = (CFMutableArrayRef) CFDictionaryGetValue(typeDir, type);
-    if (!tFiles) {
-        CFStringRef key = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@.%@"), _CFBundleTypeIndicator, type);
-        tFiles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        CFDictionarySetValue(queryTable, key, tFiles);
-        CFDictionarySetValue(typeDir, type, tFiles);
-        CFRelease(tFiles);
-        CFRelease(key);
-    }
-    if (!addedTypes) {
-        CFArrayAppendValue(tFiles, value);        
-    } else if (firstLproj) {
-        CFDictionarySetValue(addedTypes, type, type);
-        CFArrayAppendValue(tFiles, value);
-    } else if (!(CFDictionaryGetValue(addedTypes, type))) {
-        CFArrayAppendValue(tFiles, value);
-    }
+    Boolean foundPlatform = (*version == _CFBundleFileVersionNoProductWithPlatform || *version == _CFBundleFileVersionWithProductWithPlatform);
+    Boolean foundProduct = (*version == _CFBundleFileVersionWithProductNoPlatform || *version == _CFBundleFileVersionWithProductWithPlatform);
+    // Create a string that excludes both platform and product name
+    // e.g., foo-iphone~iphoneos.jpg -> foo.jpg
+    if (foundPlatform || foundProduct) {
+        CFMutableStringRef fileNameScratch = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, fileName);
+        CFIndex start, length = 0;
+        
+        // Because the platform always comes first and is immediately followed by product if it exists, we'll use the platform start location as the start of our range to delete.
+        if (foundPlatform) {
+            start = platformRange.location;
+        } else {
+            start = productRange.location;
+        }
+        
+        if (foundPlatform && foundProduct) {
+            length = platformRange.length + productRange.length;
+        } else if (foundPlatform) {
+            length = platformRange.length;
+        } else if (foundProduct) {
+            length = productRange.length;
+        }
+        CFStringDelete(fileNameScratch, CFRangeMake(start, length));
+        *noProductOrPlatform = (CFStringRef)fileNameScratch;
+    }    
 }
 
-static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFBundleRef bundle, CFURLRef bundleURL, UniChar *resDir, UniChar *subDir, CFIndex subDirLen, CFMutableArrayRef allFiles, Boolean hasFileAdded, CFMutableStringRef type, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFMutableDictionaryRef addedTypes, Boolean firstLproj, CFStringRef product, CFStringRef platform, CFStringRef lprojName, Boolean appendLprojCharacters) {
-
-    Boolean result = true;
-    
-    const CFIndex cPathBuffLen = CFStringGetMaximumSizeOfFileSystemRepresentation(pathOfDir) + 1;
-    const CFIndex valueBufferLen = cPathBuffLen + 1 + CFMaxPathSize;
-    UniChar *valueBuff = (UniChar *) CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * valueBufferLen, 0);
-    CFMutableStringRef valueStr = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull);
-    CFIndex pathOfDirWithSlashLen = 0; 
-    
-    CFIndex productLen = CFStringGetLength(product);
-    CFIndex platformLen = CFStringGetLength(platform);
+static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFBundleRef bundle, CFStringRef subdirectory, CFMutableArrayRef allFiles, Boolean hasFileAdded, CFMutableStringRef type, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFMutableDictionaryRef addedTypes, Boolean firstLproj, CFStringRef product, CFStringRef platform, CFStringRef lprojName, Boolean appendLprojCharacters) {
     
+    Boolean result = true;
+    CFMutableStringRef pathPrefix = NULL;
     if (lprojName) {
-        // valueBuff is allocated with the actual length of lprojTarget
-        CFRange lprojRange = CFRangeMake(0, CFStringGetLength(lprojName));
-        CFStringGetCharacters(lprojName, lprojRange, valueBuff);
-        pathOfDirWithSlashLen += lprojRange.length;
-        if (appendLprojCharacters) _CFAppendPathExtension(valueBuff, &pathOfDirWithSlashLen, valueBufferLen, _LprojUniChars, _LprojLen);
-        _CFAppendTrailingPathSlash(valueBuff, &pathOfDirWithSlashLen, valueBufferLen);
+        pathPrefix = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, lprojName);
+        if (appendLprojCharacters) _CFAppendPathExtension2(pathPrefix, _CFBundleLprojExtension);
+        _CFAppendTrailingPathSlash2(pathPrefix);
     }
-    
-    if (subDirLen) {
-        memmove(valueBuff+pathOfDirWithSlashLen, subDir, subDirLen*sizeof(UniChar));
-        pathOfDirWithSlashLen += subDirLen;
-        if (subDir[subDirLen-1] != _CFGetSlash()) {
-            _CFAppendTrailingPathSlash(valueBuff, &pathOfDirWithSlashLen, valueBufferLen);
+    if (subdirectory) {
+        if (pathPrefix) {
+            CFStringAppend(pathPrefix, subdirectory);
+        } else {
+            pathPrefix = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, subdirectory);
+        }
+        UniChar lastChar = CFStringGetCharacterAtIndex(subdirectory, CFStringGetLength(subdirectory)-1);
+        if (lastChar != _CFGetSlash()) {
+            _CFAppendTrailingPathSlash2(pathPrefix);
         }
     }
     
-    UniChar *fileNameBuffer = valueBuff + pathOfDirWithSlashLen;
-    char *cPathBuff = (char *)malloc(sizeof(char) * cPathBuffLen);
-
-    if (CFStringGetFileSystemRepresentation(pathOfDir, cPathBuff, cPathBuffLen)) {
-// this is a fix for traversing ouside of a bundle security issue: 8302591
-// it will be enabled after the bug 10956699 gets fixed
-#ifdef CFBUNDLE_NO_TRAVERSE_OUTSIDE
-#endif // CFBUNDLE_NO_TRAVERSE_OUTSIDE
+    _CFIterateDirectory(pathOfDir, ^Boolean(CFStringRef fileName, uint8_t fileType) {
+        CFStringRef startType = NULL, endType = NULL, noProductOrPlatform = NULL;
+        _CFBundleFileVersion fileVersion;
+        _CFBundleSplitFileName(fileName, &noProductOrPlatform, &endType, &startType, product, platform, &fileVersion);
         
-#if DEPLOYMENT_TARGET_WINDOWS
-        wchar_t pathBuf[CFMaxPathSize];
-        CFStringRef pathInUTF8 = CFStringCreateWithCString(kCFAllocatorSystemDefault, cPathBuff, kCFStringEncodingUTF8);
-        CFIndex pathInUTF8Len = CFStringGetLength(pathInUTF8);
-        if (pathInUTF8Len > CFMaxPathSize) pathInUTF8Len = CFMaxPathSize;
-        
-        CFStringGetCharacters(pathInUTF8, CFRangeMake(0, pathInUTF8Len), (UniChar *)pathBuf);
-        pathBuf[pathInUTF8Len] = 0;
-        CFRelease(pathInUTF8);
-        WIN32_FIND_DATAW filePt;
-        HANDLE handle;
+        CFStringRef pathToFile;
+        if (pathPrefix && CFStringGetLength(pathPrefix) > 0) {
+            CFMutableStringRef tmp = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, pathPrefix);
+            CFStringAppend(tmp, fileName);
+            pathToFile = (CFStringRef)tmp;
+        } else {
+            pathToFile = (CFStringRef)CFRetain(fileName);
+        }
+
+        // If this file is a directory, the path needs to include a trailing slash so we can later create the right kind of CFURL object
+        Boolean appendSlash = false;
+        if (fileType == DT_DIR) {
+            appendSlash = true;
+        }
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+        else if (fileType == DT_UNKNOWN) {
+            Boolean isDir = false;
+            char subdirPath[CFMaxPathLength];
+            struct stat statBuf;
+            if (CFStringGetFileSystemRepresentation(pathOfDir, subdirPath, sizeof(subdirPath))) {
+                strlcat(subdirPath, "/", sizeof(subdirPath));
+                char fileNameBuf[CFMaxPathLength];
+                if (CFStringGetFileSystemRepresentation(fileName, fileNameBuf, sizeof(fileNameBuf))) {
+                    strlcat(subdirPath, fileNameBuf, sizeof(subdirPath));
+                    if (stat(subdirPath, &statBuf) == 0) {
+                        isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
+                    }
+                    if (isDir) {
+                        appendSlash = true;
+                    }
+                }
+            }
+        }
+#endif
+        if (appendSlash) {
+            // This is fairly inefficient
+            CFMutableStringRef tmp = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, pathToFile);
+            _CFAppendTrailingPathSlash2(tmp);
+            CFRelease(pathToFile);
+            pathToFile = (CFStringRef)tmp;
+        }
         
-        if (pathInUTF8Len + 2 >= CFMaxPathLength) {
-            result = false;
+        // put it into all file array
+        if (!hasFileAdded) {
+            CFArrayAppendValue(allFiles, pathToFile);
         }
         
-        pathBuf[pathInUTF8Len] = '\\';
-        pathBuf[pathInUTF8Len + 1] = '*';
-        pathBuf[pathInUTF8Len + 2] = '\0';
-        handle = FindFirstFileW(pathBuf, (LPWIN32_FIND_DATAW)&filePt);
-        if (INVALID_HANDLE_VALUE == handle) {
-            pathBuf[pathInUTF8Len] = '\0';
-            result = false;
-        }
-        if (!result) {
-            free(cPathBuff);
-            CFAllocatorDeallocate(kCFAllocatorSystemDefault, valueBuff);
-            CFRelease(valueStr);
-            return result;
+        if (startType) {
+            _CFBundleAddValueForType(startType, queryTable, typeDir, pathToFile, addedTypes, firstLproj);
         }
         
-        do {
-            CFIndex nameLen = wcslen(filePt.cFileName);
-            if (filePt.cFileName[0] == '.' && (nameLen == 1 || (nameLen == 2  && filePt.cFileName[1] == '.'))) {
-                continue;
+        if (endType) {
+            _CFBundleAddValueForType(endType, queryTable, typeDir, pathToFile, addedTypes, firstLproj);
+        }
+                
+        if (fileVersion == _CFBundleFileVersionNoProductNoPlatform || fileVersion == _CFBundleFileVersionUnmatched) {
+            // No product/no platform, or unmatched files get added directly to the query table.
+            CFStringRef prevPath = (CFStringRef)CFDictionaryGetValue(queryTable, fileName);
+            if (!prevPath) {
+                CFDictionarySetValue(queryTable, fileName, pathToFile);
+            }
+        } else {
+            // If the file has a product or platform extension, we add the full name to the query table so that it may be found using that name. But only if it doesn't already exist.
+            CFStringRef prevPath = (CFStringRef)CFDictionaryGetValue(queryTable, fileName);
+            if (!prevPath) {
+                CFDictionarySetValue(queryTable, fileName, pathToFile);
             }
-            CFStringRef file = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)filePt.cFileName, nameLen * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-        DIR *dirp = NULL;
-        struct dirent* dent;
-        if ( result && (dirp = opendir(cPathBuff))) {
             
-            while ((dent = readdir(dirp))) {
-
-#if DEPLOYMENT_TARGET_LINUX
-                CFIndex nameLen = strlen(dent->d_name);
-#else
-                CFIndex nameLen = dent->d_namlen;
-#endif
-                if (0 == nameLen || 0 == dent->d_fileno || ('.' == dent->d_name[0] && (1 == nameLen || (2 == nameLen && '.' == dent->d_name[1]) || '_' == dent->d_name[1]))) 
-                    continue;
-                
-                CFStringRef file = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, dent->d_name);
-#else
-#error unknown architecture, not implemented
-#endif
-                if (file) {
-                    
-                    CFIndex fileNameLen = CFStringGetLength(file);
-                    if (fileNameLen > CFMaxPathSize) fileNameLen = CFMaxPathSize;
-                    CFStringGetCharacters(file, CFRangeMake(0, fileNameLen), fileNameBuffer);
-                    CFIndex valueTotalLen = pathOfDirWithSlashLen + fileNameLen;
-                    
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-                    // construct the path for a file, which is the value in the query table
-                    // if it is a dir
-                    if (dent->d_type == DT_DIR) {
-                        _CFAppendTrailingPathSlash(valueBuff, &valueTotalLen, valueBufferLen);
-                    } else if (dent->d_type == DT_UNKNOWN) {
-                        Boolean isDir = false;
-                        char subdirPath[CFMaxPathLength];
-                        struct stat statBuf;
-                        strlcpy(subdirPath, cPathBuff, sizeof(subdirPath));
-                        strlcat(subdirPath, "/", sizeof(subdirPath));
-                        strlcat(subdirPath, dent->d_name, sizeof(subdirPath));
-                        if (stat(subdirPath, &statBuf) == 0) {
-                             isDir = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
-                        }
-                        if (isDir) {
-                            _CFAppendTrailingPathSlash(valueBuff, &valueTotalLen, valueBufferLen);
-                        }
-                    } 
-#elif DEPLOYMENT_TARGET_WINDOWS
-                    if ((filePt.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
-                        _CFAppendTrailingPathSlash(valueBuff, &valueTotalLen, valueBufferLen);   
-                    }
-#endif
-                    CFStringSetExternalCharactersNoCopy(valueStr, valueBuff, valueTotalLen, valueBufferLen);
-                    CFTypeRef value = CFStringCreateCopy(kCFAllocatorSystemDefault, valueStr);
-                    
-                    // put it into all file array
-                    if (!hasFileAdded) {
-                        CFArrayAppendValue(allFiles, value);
-                    }
-                    
-                    // put it into type array
-                    // search the type from the end
-                    CFRange backDotPosition, dotPosition; 
-                    Boolean foundDot = _CFBundleFindCharacterInStr(fileNameBuffer, '.', YES, fileNameLen-1, fileNameLen, &backDotPosition);
-
-                    if (foundDot && backDotPosition.location != (fileNameLen-1)) {
-                        _CFBundleAddValueForType(type, fileNameBuffer, queryTable, backDotPosition, fileNameLen, typeDir, value, addedTypes, firstLproj);
-                    }
-                    
-                    // search the type from the beginning
-                    //CFRange dotPosition = CFStringFind(file, _CFBundleDot, kCFCompareEqualTo);
-                    foundDot = _CFBundleFindCharacterInStr(fileNameBuffer, '.', NO, 0, fileNameLen, &dotPosition);
-                    if (dotPosition.location != backDotPosition.location && foundDot) {
-                        _CFBundleAddValueForType(type, fileNameBuffer, queryTable, dotPosition, fileNameLen, typeDir, value, addedTypes, firstLproj);
-                    }
-                    
-                    // check if the file is product and platform specific
-                    CFRange productRange, platformRange;
-                    _CFBundleFileVersion fileVersion = _CFBundleCheckFileProductAndPlatform(file, fileNameBuffer, fileNameLen, CFRangeMake(0, fileNameLen), product, platform, &productRange, &platformRange, productLen);
-                    
-                    if (fileVersion == _CFBundleFileVersionNoProductNoPlatform || fileVersion == _CFBundleFileVersionUnmatched) {                        
-                        // No product/no platform, or unmatched files get added directly to the query table.
-                        CFStringRef prevPath = (CFStringRef)CFDictionaryGetValue(queryTable, file);
-                        if (!prevPath) {
-                            CFDictionarySetValue(queryTable, file, value);
+            // Then we add the more specific name as well, replacing the existing one if this is a more specific version.
+            if (noProductOrPlatform) {
+                // add the path of the key into the query table
+                prevPath = (CFStringRef) CFDictionaryGetValue(queryTable, noProductOrPlatform);
+                if (!prevPath) {
+                    CFDictionarySetValue(queryTable, noProductOrPlatform, pathToFile);
+                } else {
+                    if (!lprojName || CFStringHasPrefix(prevPath, lprojName)) {
+                        // we need to know the version of exisiting path to see if we can replace it by the current path
+                        CFRange searchRange;
+                        if (lprojName) {
+                            searchRange.location = CFStringGetLength(lprojName);
+                            searchRange.length = CFStringGetLength(prevPath) - searchRange.location;
+                        } else {
+                            searchRange.location = 0;
+                            searchRange.length = CFStringGetLength(prevPath);
                         }
-                    } else {
-                        // If the file has a product or platform extension, we add the full name to the query table so that it may be found using that name.
-                        // Then we add the more specific name as well.
-                        CFDictionarySetValue(queryTable, file, value);
-                        
-                        CFIndex searchOffset = platformLen;
-                        CFStringRef key = NULL;
-                        
-                        // set the key accordining to the version of the file (product and platform)
-                        switch (fileVersion) {
+                        _CFBundleFileVersion prevFileVersion = _CFBundleCheckFileProductAndPlatform(prevPath, searchRange, product, platform);
+                        switch (prevFileVersion) {
+                            case _CFBundleFileVersionNoProductNoPlatform:
+                                CFDictionarySetValue(queryTable, noProductOrPlatform, pathToFile);
+                                break;
                             case _CFBundleFileVersionWithProductNoPlatform:
-                                platformRange = productRange;
-                                searchOffset = productLen;
+                                if (fileVersion == _CFBundleFileVersionWithProductWithPlatform) CFDictionarySetValue(queryTable, noProductOrPlatform, pathToFile);
+                                break;
                             case _CFBundleFileVersionNoProductWithPlatform:
-                            case _CFBundleFileVersionWithProductWithPlatform:
-                                foundDot = _CFBundleFindCharacterInStr(fileNameBuffer, '.', NO, platformRange.location+searchOffset, fileNameLen-platformRange.location-searchOffset, &dotPosition);
-                                if (foundDot) {
-                                    CFMutableStringRef mutableKey = CFStringCreateMutable(kCFAllocatorSystemDefault, platformRange.location + (fileNameLen - dotPosition.location));
-                                    CFStringAppendCharacters(mutableKey, fileNameBuffer, platformRange.location);
-                                    CFStringAppendCharacters(mutableKey, fileNameBuffer+dotPosition.location, fileNameLen - dotPosition.location);
-                                    key = (CFStringRef)mutableKey;
-                                } else {
-                                    key = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, fileNameBuffer, platformRange.location);
-                                }
+                                CFDictionarySetValue(queryTable, noProductOrPlatform, pathToFile);
                                 break;
                             default:
-                                CFLog(kCFLogLevelError, CFSTR("CFBundle: Unknown kind of file (%d) when creating CFBundle: %@"), pathOfDir);
                                 break;
                         }
-                        
-                        if (key) {
-                            // add the path of the key into the query table
-                            CFStringRef prevPath = (CFStringRef) CFDictionaryGetValue(queryTable, key);
-                            if (!prevPath) {
-                                CFDictionarySetValue(queryTable, key, value);
-                            } else {
-                                if (!lprojName || CFStringHasPrefix(prevPath, lprojName)) {
-                                    // we need to know the version of exisiting path to see if we can replace it by the current path
-                                    CFRange searchRange;
-                                    if (lprojName) {
-                                        searchRange.location = CFStringGetLength(lprojName);
-                                        searchRange.length = CFStringGetLength(prevPath) - searchRange.location;
-                                    } else {
-                                        searchRange.location = 0;
-                                        searchRange.length = CFStringGetLength(prevPath);
-                                    }
-                                    _CFBundleFileVersion prevFileVersion = _CFBundleCheckFileProductAndPlatform(prevPath, NULL, 0, searchRange, product, platform, &productRange, &platformRange, productLen);
-                                    switch (prevFileVersion) {
-                                        case _CFBundleFileVersionNoProductNoPlatform:
-                                            CFDictionarySetValue(queryTable, key, value);
-                                            break;
-                                        case _CFBundleFileVersionWithProductNoPlatform:
-                                            if (fileVersion == _CFBundleFileVersionWithProductWithPlatform) CFDictionarySetValue(queryTable, key, value);
-                                            break;
-                                        case _CFBundleFileVersionNoProductWithPlatform:
-                                            CFDictionarySetValue(queryTable, key, value);
-                                            break;
-                                        default:
-                                            break;
-                                    }
-                                }
-                            }
-                            
-                            CFRelease(key);
-                        }
                     }
-                    
-                    CFRelease(value);
-                    CFRelease(file);
                 }
-                
-                
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
             }
-            closedir(dirp);
-        } else { // opendir
-            result = false;
-        }            
-#elif DEPLOYMENT_TARGET_WINDOWS
-        } while ((FindNextFileW(handle, &filePt)));    
-        FindClose(handle);
-        pathBuf[pathInUTF8Len] = '\0';
-#endif
-
-    } else { // the path counld not be resolved to be a file system representation
-        result = false;
-    }
+        }
+        
+        if (pathToFile) CFRelease(pathToFile);
+        if (startType) CFRelease(startType);
+        if (endType) CFRelease(endType);
+        if (noProductOrPlatform) CFRelease(noProductOrPlatform);
+        
+        return true;
+    });
     
-    free(cPathBuff);
-    CFAllocatorDeallocate(kCFAllocatorSystemDefault, valueBuff);
-    CFRelease(valueStr);
+    if (pathPrefix) CFRelease(pathPrefix);
     return result;
 }
 
-__private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDir, CFIndex subDirLen)
+
+static CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourcesDirectory, CFStringRef subdirectory)
 {
-    const CFIndex pathBufferSize = 2*CFMaxPathSize+resDirLen+subDirLen+2;
-    UniChar *pathBuffer = (UniChar *) CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * pathBufferSize, 0);
     
     CFMutableDictionaryRef queryTable = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     CFMutableArrayRef allFiles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
@@ -3316,37 +1790,30 @@ __private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef b
     CFStringRef product = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("~%@"), productName);
     CFStringRef platform = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("-%@"), platformName);
     
-    CFStringRef bundlePath = NULL;
+    CFMutableStringRef path = NULL;
     if (bundle) {
-        bundlePath = _CFBundleGetBundlePath(bundle);
-        CFRetain(bundlePath);
+        path = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, bundle->_bundleBasePath);
     } else {
         CFURLRef url = CFURLCopyAbsoluteURL(bundleURL);
-        bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
+        CFStringRef bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
         CFRelease(url);
+        path = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, bundlePath);
+        CFRelease(bundlePath);
     }
-    // bundlePath is an actual path, so it should not have a length greater than CFMaxPathSize
-    CFIndex pathLen = CFStringGetLength(bundlePath);
-    CFStringGetCharacters(bundlePath, CFRangeMake(0, pathLen), pathBuffer);
-    CFRelease(bundlePath);
     
-    Boolean appendSucc = true;
-    if (resDirLen > 0) { // should not fail, buffer has enought space
-        appendSucc = _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, resDir, resDirLen);
+    if (resourcesDirectory) {
+        _CFAppendPathComponent2(path, resourcesDirectory);
     }
     
-    CFStringRef basePath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);
+    // Record the length of the base path, so we can strip off the stuff we'll be appending later
+    CFIndex basePathLen = CFStringGetLength(path);
     
-    if (subDirLen > 0) { // should not fail, buffer has enought space
-        appendSucc = _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, subDir, subDirLen);
+    if (subdirectory) {
+        _CFAppendPathComponent2(path, subdirectory);
     }
-    
-    CFStringRef pathToRead = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);
-    
     // read the content in sub dir and put them into query table
-    _CFBundleReadDirectory(pathToRead, bundle, bundleURL, resDir, subDir, subDirLen, allFiles, false, type, queryTable, typeDir, NULL, false, product, platform, NULL, false);
-    
-    CFRelease(pathToRead);
+    _CFBundleReadDirectory(path, bundle, subdirectory, allFiles, false, type, queryTable, typeDir, NULL, false, product, platform, NULL, false);
+    CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen));    // Strip the string back to the base path
     
     CFIndex numOfAllFiles = CFArrayGetCount(allFiles);
     
@@ -3356,28 +1823,20 @@ __private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef b
     CFIndex numLprojs = languages ? CFArrayGetCount(languages) : 0;
     CFMutableDictionaryRef addedTypes = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     
-    CFIndex basePathLen = CFStringGetLength(basePath);
     Boolean hasFileAdded = false;
     Boolean firstLproj = true;
-
+    
     // First, search lproj for user's chosen language
     if (numLprojs >= 1) {
         CFStringRef lprojTarget = (CFStringRef)CFArrayGetValueAtIndex(languages, 0);
-        // lprojTarget is from _CFBundleGetLanguageSearchList, so it should not have a length greater than CFMaxPathSize
-        UniChar lprojBuffer[CFMaxPathSize];
-        CFIndex lprojLen = CFStringGetLength(lprojTarget);
-        CFStringGetCharacters(lprojTarget, CFRangeMake(0, lprojLen), lprojBuffer);
-        
-        pathLen = basePathLen;
-        _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, lprojBuffer, lprojLen);
-        _CFAppendPathExtension(pathBuffer, &pathLen, pathBufferSize, _LprojUniChars, _LprojLen);
-        if (subDirLen > 0) {
-            _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, subDir, subDirLen);
-        }
-        pathToRead = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);        
-        _CFBundleReadDirectory(pathToRead, bundle, bundleURL, resDir, subDir, subDirLen, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, firstLproj, product, platform, lprojTarget, true);
-        CFRelease(pathToRead);
-        
+        _CFAppendPathComponent2(path, lprojTarget);
+        _CFAppendPathExtension2(path, _CFBundleLprojExtension);
+        if (subdirectory) {
+            _CFAppendPathComponent2(path, subdirectory);
+        }
+        _CFBundleReadDirectory(path, bundle, subdirectory, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, firstLproj, product, platform, lprojTarget, true);
+        CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen));         // Strip the string back to the base path
+
         if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) {
             hasFileAdded = true;
         }
@@ -3385,39 +1844,30 @@ __private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef b
     }
     
     // Next, search Base.lproj folder
-    pathLen = basePathLen;
-    _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, _BaseUniChars, _BaseLen);
-    _CFAppendPathExtension(pathBuffer, &pathLen, pathBufferSize, _LprojUniChars, _LprojLen);
-    if (subDirLen > 0) {
-        _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, subDir, subDirLen);
+    _CFAppendPathComponent2(path, _CFBundleBaseDirectory);
+    _CFAppendPathExtension2(path, _CFBundleLprojExtension);
+    if (subdirectory) {
+        _CFAppendPathComponent2(path, subdirectory);
     }
-    pathToRead = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);
-    _CFBundleReadDirectory(pathToRead, bundle, bundleURL, resDir, subDir, subDirLen, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, YES, product, platform, _CFBundleBaseDirectory, true);
-    CFRelease(pathToRead);
+    _CFBundleReadDirectory(path, bundle, subdirectory, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, YES, product, platform, _CFBundleBaseDirectory, true);
+    CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen));    // Strip the string back to the base path
     
     if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) {
         hasFileAdded = true;
     }
-
+    
     // Finally, search remaining languages (development language first)
     if (numLprojs >= 2) {
         // for each lproj we are interested in, read the content and put them into query table
         for (CFIndex i = 1; i < CFArrayGetCount(languages); i++) {
             CFStringRef lprojTarget = (CFStringRef) CFArrayGetValueAtIndex(languages, i);
-            // lprojTarget is from _CFBundleGetLanguageSearchList, so it should not have a length greater than CFMaxPathSize
-            UniChar lprojBuffer[CFMaxPathSize];
-            CFIndex lprojLen = CFStringGetLength(lprojTarget);
-            CFStringGetCharacters(lprojTarget, CFRangeMake(0, lprojLen), lprojBuffer);
-            
-            pathLen = basePathLen;
-            _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, lprojBuffer, lprojLen);
-            _CFAppendPathExtension(pathBuffer, &pathLen, pathBufferSize, _LprojUniChars, _LprojLen);
-            if (subDirLen > 0) {
-                _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, subDir, subDirLen);
+            _CFAppendPathComponent2(path, lprojTarget);
+            _CFAppendPathExtension2(path, _CFBundleLprojExtension);
+            if (subdirectory) {
+                _CFAppendPathComponent2(path, subdirectory);
             }
-            pathToRead = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);
-            _CFBundleReadDirectory(pathToRead, bundle, bundleURL, resDir, subDir, subDirLen, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, false, product, platform, lprojTarget, true);            
-            CFRelease(pathToRead);
+            _CFBundleReadDirectory(path, bundle, subdirectory, allFiles, hasFileAdded, type, queryTable, typeDir, addedTypes, false, product, platform, lprojTarget, true);
+            CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen));         // Strip the string back to the base path
             
             if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) {
                 hasFileAdded = true;
@@ -3426,6 +1876,7 @@ __private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef b
     }
     
     CFRelease(addedTypes);
+    CFRelease(path);
     
     // put the array of all files in sub dir to the query table
     if (CFArrayGetCount(allFiles) > 0) {
@@ -3437,28 +1888,48 @@ __private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef b
     CFRelease(allFiles);
     CFRelease(typeDir);
     CFRelease(type);
-    CFRelease(basePath);
     
-    CFAllocatorDeallocate(kCFAllocatorSystemDefault, pathBuffer);
+    
     return queryTable;
 }   
-    
-static CFURLRef _CFBundleCreateURLFromPath(CFStringRef path, UniChar slash, UniChar *urlBuffer, CFIndex urlBufferLen, CFMutableStringRef urlStr)
+
+// caller need to release the table
+static CFDictionaryRef _CFBundleCopyQueryTable(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourcesDirectory, CFStringRef subdirectory)
 {
-    CFURLRef url = NULL;
-    // path is a part of an actual path in the query table, so it should not have a length greater than the buffer size
-    CFIndex pathLen = CFStringGetLength(path);
-    CFStringGetCharacters(path, CFRangeMake(0, pathLen), urlBuffer+urlBufferLen);
-    CFStringSetExternalCharactersNoCopy(urlStr, urlBuffer, urlBufferLen+pathLen, CFMaxPathSize);
-    if (CFStringGetCharacterAtIndex(path, pathLen-1) == slash) {
-        url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, YES);
+    CFDictionaryRef subTable = NULL;
+    
+    // take the lock
+    if (bundle) {
+        CFMutableStringRef argDirStr = NULL;
+        if (subdirectory) {
+            argDirStr = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, resourcesDirectory);
+            _CFAppendPathComponent2(argDirStr, subdirectory);
+        } else {
+            argDirStr = (CFMutableStringRef)CFRetain(resourcesDirectory);
+        }
+        
+        __CFSpinLock(&bundle->_queryLock);
+        
+        // check if the query table for the given sub dir has been created
+        subTable = (CFDictionaryRef) CFDictionaryGetValue(bundle->_queryTable, argDirStr);
+        
+        if (!subTable) {
+            // create the query table for the given sub dir
+            subTable = _CFBundleCreateQueryTableAtPath(bundle, bundleURL, languages, resourcesDirectory, subdirectory);
+            
+            CFDictionarySetValue(bundle->_queryTable, argDirStr, subTable);
+        } else {
+            CFRetain(subTable);
+        }
+        __CFSpinUnlock(&bundle->_queryLock);
+        CFRelease(argDirStr);
     } else {
-        url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, NO);
+        subTable = _CFBundleCreateQueryTableAtPath(NULL, bundleURL, languages, resourcesDirectory, subdirectory);
     }
     
-    return url;
+    return subTable;
 }
-    
+
 static CFURLRef _CFBundleCreateRelativeURLFromBaseAndPath(CFStringRef path, CFURLRef base, UniChar slash, CFStringRef slashStr)
 {
     CFURLRef url = NULL;
@@ -3472,9 +1943,9 @@ static CFURLRef _CFBundleCreateRelativeURLFromBaseAndPath(CFStringRef path, CFUR
         needToRelease = true;
     }
     if (CFStringGetCharacterAtIndex(path, CFStringGetLength(path)-1) == slash) {
-        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, YES, base);
+        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, true, base);
     } else {
-        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, NO, base);
+        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, false, base);
     }
     if (needToRelease) {
         CFRelease(base);
@@ -3482,7 +1953,7 @@ static CFURLRef _CFBundleCreateRelativeURLFromBaseAndPath(CFStringRef path, CFUR
     }
     return url;
 }
-    
+
 static void _CFBundleFindResourcesWithPredicate(CFMutableArrayRef interResult, CFDictionaryRef queryTable, Boolean (^predicate)(CFStringRef filename, Boolean *stop), Boolean *stop)
 {
     CFIndex dictSize = CFDictionaryGetCount(queryTable);
@@ -3504,32 +1975,31 @@ static void _CFBundleFindResourcesWithPredicate(CFMutableArrayRef interResult, C
         if (*stop) break;
     }
 }
-    
-static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDirBuffer, CFIndex subDirLen, CFStringRef subDir, CFStringRef key, CFStringRef lproj, UniChar *lprojBuff, Boolean returnArray, Boolean localized, uint8_t bundleVersion, Boolean (^predicate)(CFStringRef filename, Boolean *stop))
+
+static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourcesDirectory, CFStringRef subDir, CFStringRef key, CFStringRef lproj, Boolean returnArray, Boolean localized, uint8_t bundleVersion, Boolean (^predicate)(CFStringRef filename, Boolean *stop))
 {
     CFTypeRef value = NULL;
     Boolean stop = false; // for predicate
     CFMutableArrayRef interResult = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     CFDictionaryRef subTable = NULL;
-        
+    
+    CFMutableStringRef path = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, resourcesDirectory);
     if (1 == bundleVersion) {
-        CFIndex savedResDirLen = resDirLen;
+        CFIndex savedPathLength = CFStringGetLength(path);
         // add the non-localized resource dir
-        Boolean appendSucc = _CFAppendPathComponent(resDir, &resDirLen, CFMaxPathSize, _GlobalResourcesUniChars, _GlobalResourcesLen);
-        if (appendSucc) {
-            subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, resDir, resDirLen, subDirBuffer, subDirLen);
-            if (predicate) {
-                _CFBundleFindResourcesWithPredicate(interResult, subTable, predicate, &stop);
-            } else {
-                value = CFDictionaryGetValue(subTable, key);
-            }
+        _CFAppendPathComponent2(path, _CFBundleNonLocalizedResourcesDirectoryName);
+        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, path, subDir);
+        if (predicate) {
+            _CFBundleFindResourcesWithPredicate(interResult, subTable, predicate, &stop);
+        } else {
+            value = CFDictionaryGetValue(subTable, key);
         }
-        resDirLen = savedResDirLen;
+        CFStringDelete(path, CFRangeMake(savedPathLength, CFStringGetLength(path) - savedPathLength));    // Strip the string back to the base path
     }
     
     if (!value && !stop) {
         if (subTable) CFRelease(subTable);
-        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, resDir, resDirLen, subDirBuffer, subDirLen);
+        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, path, subDir);
         if (predicate) {
             _CFBundleFindResourcesWithPredicate(interResult, subTable, predicate, &stop);
         } else {
@@ -3561,11 +2031,11 @@ static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL,
             
             // if we have subdir, we find the subdir and see if it is after the base path (bundle path + res dir)
             Boolean searchForLocalization = false;
-            if (subDirLen) {
+            if (subDir && CFStringGetLength(subDir) > 0) {
                 if (CFStringFindWithOptions(pathValue, subDir, searchRange, kCFCompareEqualTo, &resultRange) && resultRange.location != searchRange.location) {
                     searchForLocalization = true;
                 }
-            } else if (!subDirLen && searchRange.length != 0) {
+            } else if (!(subDir && CFStringGetLength(subDir) > 0) && searchRange.length != 0) {
                 if (CFStringFindWithOptions(pathValue, _CFBundleLprojExtensionWithDot, searchRange, kCFCompareEqualTo, &resultRange) && resultRange.location + 7 < pathValueLen) {
                     searchForLocalization = true;
                 }
@@ -3599,16 +2069,13 @@ static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL,
     
     // we fetch the result for a given lproj and join them with the nonlocalized result fetched above
     if (lpLen && checkLP) {
-        CFIndex lprojBuffLen = lpLen;
-        // lprojBuff is allocated with the actual size of lproj
-        CFStringGetCharacters(lproj, CFRangeMake(0, lpLen), lprojBuff);
-        _CFAppendPathExtension(lprojBuff, &lprojBuffLen, lprojBuffLen+7, _LprojUniChars, _LprojLen);
-        
-        if (subDirLen) {
-            _CFAppendTrailingPathSlash(lprojBuff, &lprojBuffLen, lprojBuffLen+1);
+        CFMutableStringRef lprojSubdirName = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, lproj);
+        _CFAppendPathExtension2(lprojSubdirName, _CFBundleLprojExtension);
+        if (subDir && CFStringGetLength(subDir) > 0) {
+            _CFAppendTrailingPathSlash2(lprojSubdirName);
         }
-        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, resDir, resDirLen, lprojBuff, subDirLen+lprojBuffLen);
-        
+        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, path, lprojSubdirName);
+        CFRelease(lprojSubdirName);
         value = CFDictionaryGetValue(subTable, key);
         
         if (value) {
@@ -3626,25 +2093,22 @@ static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL,
     CFTypeRef result = NULL;
     if (CFArrayGetCount(interResult) > 0) {
         UniChar slash = _CFGetSlash();
-        UniChar *urlBuffer = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * CFMaxPathSize, 0);
-        CFMutableStringRef urlStr = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull);
-        CFStringRef bundlePath = NULL;
+        CFMutableStringRef urlStr = NULL;
         if (bundle) {
-            bundlePath = _CFBundleGetBundlePath(bundle);
-            CFRetain(bundlePath);
+            urlStr = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, bundle->_bundleBasePath);
         } else {
             CFURLRef url = CFURLCopyAbsoluteURL(bundleURL);
-            bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
+            CFStringRef bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
+            urlStr = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, bundlePath);
             CFRelease(url);
+            CFRelease(bundlePath);
         }
-        CFIndex urlBufferLen = CFStringGetLength(bundlePath);
-        CFStringGetCharacters(bundlePath, CFRangeMake(0, urlBufferLen), urlBuffer);
-        CFRelease(bundlePath);
         
-        if (resDirLen) {
-            _CFAppendPathComponent(urlBuffer, &urlBufferLen, CFMaxPathSize, resDir, resDirLen);
+        if (resourcesDirectory && CFStringGetLength(resourcesDirectory)) {
+            _CFAppendPathComponent2(urlStr, resourcesDirectory);
         }
-        _CFAppendTrailingPathSlash(urlBuffer, &urlBufferLen, CFMaxPathSize);
+
+        _CFAppendTrailingPathSlash2(urlStr);
         
         if (!returnArray) {
             Boolean isOnlyTypeOrAllFiles = CFStringHasPrefix(key, _CFBundleTypeIndicator);
@@ -3652,25 +2116,27 @@ static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL,
             
             CFStringRef resultPath = (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)interResult, 0);
             if (!isOnlyTypeOrAllFiles) {
-                result = (CFURLRef)_CFBundleCreateURLFromPath((CFStringRef)resultPath, slash, urlBuffer, urlBufferLen, urlStr);
-            } else { // need to create relative URLs for binary compatibility issues
-                CFStringSetExternalCharactersNoCopy(urlStr, urlBuffer, urlBufferLen, CFMaxPathSize);
-                CFURLRef base = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, YES);
-                CFStringRef slashStr = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &slash, 1);
-                result = (CFURLRef)_CFBundleCreateRelativeURLFromBaseAndPath(resultPath, base, slash, slashStr);
-                CFRelease(slashStr);
+                // path is a part of an actual path in the query table, so it should not have a length greater than the buffer size
+                CFStringAppend(urlStr, resultPath);
+                if (CFStringGetCharacterAtIndex(resultPath, CFStringGetLength(resultPath)-1) == slash) {
+                    result = (CFURLRef)CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, true);
+                } else {
+                    result = (CFURLRef)CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, false);
+                }
+            } else {
+                // need to create relative URLs for binary compatibility issues
+                CFURLRef base = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, true);
+                result = (CFURLRef)_CFBundleCreateRelativeURLFromBaseAndPath(resultPath, base, slash, _CFGetSlashStr());
                 CFRelease(base);
             }
         } else {
             // need to create relative URLs for binary compatibility issues
             CFIndex numOfPaths = CFArrayGetCount((CFArrayRef)interResult);
-            CFStringSetExternalCharactersNoCopy(urlStr, urlBuffer, urlBufferLen, CFMaxPathSize);
-            CFURLRef base = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, YES);
-            CFStringRef slashStr = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &slash, 1);
+            CFURLRef base = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, true);
             CFMutableArrayRef urls = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
             for (CFIndex i = 0; i < numOfPaths; i++) {
                 CFStringRef path = (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)interResult, i);
-                CFURLRef url = _CFBundleCreateRelativeURLFromBaseAndPath(path, base, slash, slashStr);
+                CFURLRef url = _CFBundleCreateRelativeURLFromBaseAndPath(path, base, slash, _CFGetSlashStr());
                 CFArrayAppendValue(urls, url);
                 CFRelease(url);
             }
@@ -3678,121 +2144,87 @@ static CFTypeRef _CFBundleCopyURLsOfKey(CFBundleRef bundle, CFURLRef bundleURL,
             CFRelease(base);
         }
         CFRelease(urlStr);
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, urlBuffer);
     } else if (returnArray) {
         result = CFRetain(interResult);
     }
-    
+    if (path) CFRelease(path);
     CFRelease(interResult);
     return result;
 }
 
-CFTypeRef _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized, Boolean (^predicate)(CFStringRef filename, Boolean *stop))
+#pragma mark -
+
+// This is the main entry point for all resource lookup.
+// Research shows that by far the most common scenario is to pass in a bundle object, a resource name, and a resource type, using the default localization.
+// It is probably the case that more than a few resources will be looked up, making the cost of a readdir less than repeated stats. But it is a relative waste of memory to create strings for every file name in the bundle, especially since those are not what are returned to the caller (URLs are). So, an idea: cache the existence of the most common file names (Info.plist, en.lproj, etc) instead of creating entries for them. If other resources are requested, then go ahead and do the readdir and cache the rest of the file names.
+// Another idea: if you want caching, you should create a bundle object. Otherwise we'll happily readdir each time.
+CF_EXPORT CFTypeRef _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized, Boolean (^predicate)(CFStringRef filename, Boolean *stop))
 {
-    CFIndex rnameLen = 0;
-    CFIndex typeLen = resourceType ? CFStringGetLength(resourceType) : 0;
-    CFIndex lprojLen = lproj ? CFStringGetLength(lproj) + 7 : 0; // 7 is the length of ".lproj/"
+    
+    // Don't use any path info passed into the resource name
+    CFStringRef realResourceName = NULL;
     CFStringRef subPathFromResourceName = NULL;
-    CFIndex subPathFromResourceNameLen = 0;
+
     if (resourceName) {
-        UniChar tmpNameBuffer[CFMaxPathSize];
-        rnameLen = CFStringGetLength(resourceName);
-        if (rnameLen > CFMaxPathSize) rnameLen = CFMaxPathSize;
-        CFStringGetCharacters(resourceName, CFRangeMake(0, rnameLen), tmpNameBuffer);
-        CFIndex rnameIndex = _CFStartOfLastPathComponent(tmpNameBuffer, rnameLen);
-        if (rnameIndex != 0) {
-            resourceName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, tmpNameBuffer+rnameIndex, rnameLen - rnameIndex);
-            subPathFromResourceName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, tmpNameBuffer, rnameIndex-1);
-            subPathFromResourceNameLen = rnameIndex-1;
-        } else {
-            CFRetain(resourceName);
+        CFIndex slashLocation = -1;
+        realResourceName = _CFCreateLastPathComponent(kCFAllocatorSystemDefault, resourceName, &slashLocation);
+        if (slashLocation > 0) {
+            // do not include the /
+            subPathFromResourceName = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, resourceName, CFRangeMake(0, slashLocation));
         }
         
+        // Normalize the resource name by converting it to file system representation. Otherwise when we look for the key in our tables, it will not match.
+        // TODO: remove this in some way to avoid the malloc?
         char buff[CFMaxPathSize];
-        CFStringRef newResName = NULL;
-        if (CFStringGetFileSystemRepresentation(resourceName, buff, CFMaxPathSize)) {
-            newResName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, buff);
-        }
-        CFStringRef tmpStr = resourceName;
-        resourceName = newResName ? newResName : (CFStringRef)CFRetain(resourceName);
-        rnameLen = CFStringGetLength(resourceName);
-        CFRelease(tmpStr);
-    }
-    CFIndex subDirLen = subPath ? CFStringGetLength(subPath) : 0;
-    if (subDirLen == 0) subPath = NULL;
-    if (subDirLen && subPathFromResourceName) {
-        subDirLen += (subPathFromResourceNameLen + 1);
-    } else if (subPathFromResourceNameLen) {
-        subDirLen = subPathFromResourceNameLen;
-    }
-    
-    // the nameBuff have the format: [resourceName].[resourceType][lprojName.lproj/][subPath][resource dir]
-    UniChar *nameBuff = (UniChar *) CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UniChar) * (rnameLen + 1 + typeLen + subDirLen + lprojLen + CFMaxPathSize), 0);
-    UniChar *typeBuff = rnameLen ? nameBuff + rnameLen + 1 : nameBuff + CFStringGetLength(_CFBundleTypeIndicator) + 1;
-    UniChar *lprojBuffer = typeBuff + typeLen;
-    UniChar *subDirBuffer = lprojBuffer + lprojLen;
-    UniChar *resDir = subDirBuffer + subDirLen;
-    
-    CFStringRef key = NULL;
-    
-    CFIndex typeP = 0;
-    if (typeLen && CFStringGetCharacterAtIndex(resourceType, 0) == '.') {
-        typeP = 1;
-        typeLen--;
-    }
-    if (rnameLen && typeLen) {
-        CFStringGetCharacters(resourceName, CFRangeMake(0, rnameLen), nameBuff);
-        nameBuff[rnameLen] = '.';
-        CFStringGetCharacters(resourceType, CFRangeMake(typeP, typeLen), typeBuff);
-        key = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, nameBuff, rnameLen+typeLen+1);
-    } else if (rnameLen) {
-        CFStringGetCharacters(resourceName, CFRangeMake(0, rnameLen), nameBuff);
-        key = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, nameBuff, rnameLen);
-    } else if (typeLen) {
-        rnameLen = CFStringGetLength(_CFBundleTypeIndicator);
-        CFStringGetCharacters(_CFBundleTypeIndicator, CFRangeMake(0, rnameLen), nameBuff);
-        nameBuff[rnameLen] = '.';
-        CFStringGetCharacters(resourceType, CFRangeMake(typeP, typeLen), typeBuff);
-        key = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, nameBuff, rnameLen+typeLen+1);
+        if (CFStringGetFileSystemRepresentation(realResourceName, buff, CFMaxPathSize)) {
+            CFRelease(realResourceName);
+            realResourceName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, buff);
+        }
+    }
+        
+    CFMutableStringRef key = NULL;
+    const static UniChar extensionSep = '.';
+    
+    if (realResourceName && CFStringGetLength(realResourceName) > 0 && resourceType && CFStringGetLength(resourceType) > 0) {
+        // Testing shows that using a mutable string here is significantly faster than using the format functions.
+        key = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, realResourceName);
+        // Don't re-append a . if the resource name already has one
+        if (CFStringGetCharacterAtIndex(resourceType, 0) != '.') CFStringAppendCharacters(key, &extensionSep, 1);
+        CFStringAppend(key, resourceType);
+    } else if (realResourceName && CFStringGetLength(realResourceName) > 0) {
+        key = (CFMutableStringRef)CFRetain(realResourceName);
+    } else if (resourceType && CFStringGetLength(resourceType) > 0) {
+        key = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, _CFBundleTypeIndicator);
+        // Don't re-append a . if the resource name already has one
+        if (CFStringGetCharacterAtIndex(resourceType, 0) != '.') CFStringAppendCharacters(key, &extensionSep, 1);
+        CFStringAppend(key, resourceType);
     } else {
-        key = (CFStringRef)CFRetain(_CFBundleAllFiles);
+        key = (CFMutableStringRef)CFRetain(_CFBundleAllFiles);
     }
     
-    if (subDirLen) {
-        CFIndex subPathLen = 0;
-        if (subPath) {
-            subPathLen = CFStringGetLength(subPath);
-            CFStringGetCharacters(subPath, CFRangeMake(0, subPathLen), subDirBuffer);
-            if (subPathFromResourceName) _CFAppendTrailingPathSlash(subDirBuffer, &subPathLen, subDirLen);
-        }
-        if (subPathFromResourceName) {
-            CFStringGetCharacters(subPathFromResourceName, CFRangeMake(0, subPathFromResourceNameLen), subDirBuffer+subPathLen);
-            subPathLen += subPathFromResourceNameLen;
-            subPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, subDirBuffer, subPathLen);
-        } else {
-            CFRetain(subPath);
-        }
-    }
+    CFStringRef realSubdirectory = NULL;
     
-    // Init the one-time-only unichar buffers.
-    _CFEnsureStaticBuffersInited();
+    if (subPath && CFStringGetLength(subPath) && !subPathFromResourceName) {
+        realSubdirectory = (CFStringRef)CFRetain(subPath);
+    } else if (subPathFromResourceName && CFStringGetLength(subPathFromResourceName)) {
+        realSubdirectory = (CFStringRef)CFRetain(subPathFromResourceName);
+    }
     
-    CFIndex resDirLen = 0;
     uint8_t bundleVersion = bundle ? _CFBundleLayoutVersion(bundle) : 0;
     if (bundleURL && !languages) {
         languages = _CFBundleCopyLanguageSearchListInDirectory(kCFAllocatorSystemDefault, bundleURL, &bundleVersion);
     } else if (languages) {
         CFRetain(languages);
     }
-
-    _CFBundleSetResourceDir(resDir, &resDirLen, CFMaxPathSize, bundleVersion);
     
-    CFTypeRef returnValue = _CFBundleCopyURLsOfKey(bundle, bundleURL, languages, resDir, resDirLen, subDirBuffer, subDirLen, subPath, key, lproj, lprojBuffer, returnArray, localized, bundleVersion, predicate);
-        
+    CFStringRef resDir = _CFBundleGetResourceDirForVersion(bundleVersion);
+    
+    CFTypeRef returnValue = _CFBundleCopyURLsOfKey(bundle, bundleURL, languages, resDir, realSubdirectory, key, lproj, returnArray, localized, bundleVersion, predicate);
+    
     if ((!returnValue || (CFGetTypeID(returnValue) == CFArrayGetTypeID() && CFArrayGetCount((CFArrayRef)returnValue) == 0)) && (0 == bundleVersion || 2 == bundleVersion)) {
         CFStringRef bundlePath = NULL;
         if (bundle) {
-            bundlePath = _CFBundleGetBundlePath(bundle);
+            bundlePath = bundle->_bundleBasePath;
             CFRetain(bundlePath);
         } else {
             CFURLRef absoluteURL = CFURLCopyAbsoluteURL(bundleURL);
@@ -3803,36 +2235,117 @@ CFTypeRef _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFA
             if (returnValue) CFRelease(returnValue);
             CFRange found;
             // 9 is the length of "Resources"
-            if ((bundleVersion == 0 && subPath && CFEqual(subPath, CFSTR("Resources"))) || (bundleVersion == 2 && subPath && CFEqual(subPath, CFSTR("Contents/Resources")))){
-                subDirLen = 0;
-            } else if ((bundleVersion == 0 && subPath && CFStringFindWithOptions(subPath, CFSTR("Resources/"), CFRangeMake(0, 10), kCFCompareEqualTo, &found) && found.location+10 < subDirLen)) {
-                subDirBuffer = subDirBuffer + 10;
-                subDirLen -= 10;
-            } else if ((bundleVersion == 2 && subPath && CFStringFindWithOptions(subPath, CFSTR("Contents/Resources/"), CFRangeMake(0, 19), kCFCompareEqualTo, &found) && found.location+19 < subDirLen)) {
-                subDirBuffer = subDirBuffer + 19;
-                subDirLen -= 19;
+            if ((bundleVersion == 0 && realSubdirectory && CFEqual(realSubdirectory, CFSTR("Resources"))) || (bundleVersion == 2 && realSubdirectory && CFEqual(realSubdirectory, CFSTR("Contents/Resources")))) {
+                if (realSubdirectory) CFRelease(realSubdirectory);
+                realSubdirectory = CFSTR("");
+            } else if ((bundleVersion == 0 && realSubdirectory && CFStringFindWithOptions(realSubdirectory, CFSTR("Resources/"), CFRangeMake(0, 10), kCFCompareEqualTo, &found) && found.location+10 < CFStringGetLength(realSubdirectory))) {
+                CFStringRef tmpRealSubdirectory = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, realSubdirectory, CFRangeMake(10, CFStringGetLength(realSubdirectory) - 10));
+                if (realSubdirectory) CFRelease(realSubdirectory);
+                realSubdirectory = tmpRealSubdirectory;
+            } else if ((bundleVersion == 2 && realSubdirectory && CFStringFindWithOptions(realSubdirectory, CFSTR("Contents/Resources/"), CFRangeMake(0, 19), kCFCompareEqualTo, &found) && found.location+19 < CFStringGetLength(realSubdirectory))) {
+                CFStringRef tmpRealSubdirectory = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, realSubdirectory, CFRangeMake(19, CFStringGetLength(realSubdirectory) - 19));
+                if (realSubdirectory) CFRelease(realSubdirectory);
+                realSubdirectory = tmpRealSubdirectory;
             } else {
-                resDirLen = 0;
+                // Assume no resources directory
+                resDir = CFSTR("");
             }
-            if (subDirLen > 0) {
-                CFRelease(subPath);
-                subPath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, subDirBuffer, subDirLen);
-            }
-            returnValue = _CFBundleCopyURLsOfKey(bundle, bundleURL, languages, resDir, resDirLen, subDirBuffer, subDirLen, subPath, key, lproj, lprojBuffer, returnArray, localized, bundleVersion, predicate);
+            returnValue = _CFBundleCopyURLsOfKey(bundle, bundleURL, languages, resDir, realSubdirectory, key, lproj, returnArray, localized, bundleVersion, predicate);
         }
         CFRelease(bundlePath);
     }
-
-    if (resourceName) CFRelease(resourceName);
-    if (subPath) CFRelease(subPath);
+    
+    if (realResourceName) CFRelease(realResourceName);
+    if (realSubdirectory) CFRelease(realSubdirectory);
     if (subPathFromResourceName) CFRelease(subPathFromResourceName);
     if (languages) CFRelease(languages);
-    CFAllocatorDeallocate(kCFAllocatorSystemDefault, nameBuff);
     CFRelease(key);
     return returnValue;
 }
 
-__private_extern__ CFTypeRef _CFBundleCopyFindResourcesWithNoBlock(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized)
-{
-    return _CFBundleCopyFindResources(bundle, bundleURL, languages, resourceName, resourceType, subPath, lproj, returnArray, localized, NULL);
+#pragma mark -
+#pragma mark Localized Strings
+
+
+CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName) {
+    CFStringRef result = NULL;
+    CFDictionaryRef stringTable = NULL;
+    static CFSpinLock_t CFBundleLocalizedStringLock = CFSpinLockInit;
+    
+    if (!key) return (value ? (CFStringRef)CFRetain(value) : (CFStringRef)CFRetain(CFSTR("")));
+    
+    // Make sure to check the mixed localizations key early -- if the main bundle has not yet been cached, then we need to create the cache of the Info.plist before we start asking for resources (11172381)
+    (void)CFBundleAllowMixedLocalizations();
+    
+    if (!tableName || CFEqual(tableName, CFSTR(""))) tableName = _CFBundleDefaultStringTableName;
+    
+    __CFSpinLock(&CFBundleLocalizedStringLock);
+    if (__CFBundleGetResourceData(bundle)->_stringTableCache) {
+        stringTable = (CFDictionaryRef)CFDictionaryGetValue(__CFBundleGetResourceData(bundle)->_stringTableCache, tableName);
+        if (stringTable) CFRetain(stringTable);
+    }
+    __CFSpinUnlock(&CFBundleLocalizedStringLock);
+    
+    if (!stringTable) {
+        // Go load the table.
+        CFURLRef tableURL = CFBundleCopyResourceURL(bundle, tableName, _CFBundleStringTableType, NULL);
+        if (tableURL) {
+            CFStringRef nameForSharing = NULL;
+            if (!stringTable) {
+                CFDataRef tableData = NULL;
+                SInt32 errCode;
+                CFStringRef errStr;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+                if (CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, tableURL, &tableData, NULL, NULL, &errCode)) {
+#pragma GCC diagnostic pop
+                    stringTable = (CFDictionaryRef)CFPropertyListCreateFromXMLData(CFGetAllocator(bundle), tableData, kCFPropertyListImmutable, &errStr);
+                    if (errStr) {
+                        CFRelease(errStr);
+                        errStr = NULL;
+                    }
+                    if (stringTable && CFDictionaryGetTypeID() != CFGetTypeID(stringTable)) {
+                        CFRelease(stringTable);
+                        stringTable = NULL;
+                    }
+                    CFRelease(tableData);
+                    
+                }
+            }
+            if (nameForSharing) CFRelease(nameForSharing);
+            if (tableURL) CFRelease(tableURL);
+        }
+        if (!stringTable) stringTable = CFDictionaryCreate(CFGetAllocator(bundle), NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+        
+        if (!CFStringHasSuffix(tableName, CFSTR(".nocache")) || !_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) {
+            __CFSpinLock(&CFBundleLocalizedStringLock);
+            if (!__CFBundleGetResourceData(bundle)->_stringTableCache) __CFBundleGetResourceData(bundle)->_stringTableCache = CFDictionaryCreateMutable(CFGetAllocator(bundle), 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            CFDictionarySetValue(__CFBundleGetResourceData(bundle)->_stringTableCache, tableName, stringTable);
+            __CFSpinUnlock(&CFBundleLocalizedStringLock);
+        }
+    }
+    
+    result = (CFStringRef)CFDictionaryGetValue(stringTable, key);
+    if (!result) {
+        if (!value) {
+            result = (CFStringRef)CFRetain(key);
+        } else if (CFEqual(value, CFSTR(""))) {
+            result = (CFStringRef)CFRetain(key);
+        } else {
+            result = (CFStringRef)CFRetain(value);
+        }
+        __block Boolean capitalize = false;
+        if (capitalize) {
+            CFMutableStringRef capitalizedResult = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, result);
+            CFLog(__kCFLogBundle, CFSTR("Localizable string \"%@\" not found in strings table \"%@\" of bundle %@."), key, tableName, bundle);
+            CFStringUppercase(capitalizedResult, NULL);
+            CFRelease(result);
+            result = capitalizedResult;
+        }
+    } else {
+        CFRetain(result);
+    }
+    CFRelease(stringTable);
+    return result;
 }
+
index b7233212e063869041ef3e63e001b8bdcab46991..16fa515bc77b3a396ad81f7221b3d1d2130e0100 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*  CFBurstTrie.c
-    Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+    Copyright (c) 2008-2013, Apple Inc. All rights reserved.
     Responsibility: Jennifer Moore
 */
 
@@ -36,7 +36,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <limits.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <unistd.h>
 #include <sys/param.h>
 #include <sys/mman.h>
@@ -282,7 +282,7 @@ typedef struct _TraverseContext {
     void (*callback)(void*, const UInt8*, uint32_t, uint32_t);
 } TraverseContext;
 
-bool foundKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
+static bool foundKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
 {
     if (context != NULL) {
         TraverseContext *ctx = (TraverseContext *)context;
@@ -317,8 +317,8 @@ static void finalizeCFBurstTrieList(ListNodeRef node);
 static int nodeWeightCompare(const void *a, const void *b);
 static int nodeStringCompare(const void *a, const void *b);
 
-bool foundKey(void *context, const uint8_t *key, uint32_t payload, bool exact);
-bool containsKey(void *context, const uint8_t *key, uint32_t payload, bool exact);
+static bool foundKey(void *context, const uint8_t *key, uint32_t payload, bool exact);
+static bool containsKey(void *context, const uint8_t *key, uint32_t payload, bool exact);
 
 static CFIndex burstTrieConvertCharactersToUTF8(UniChar *chars, CFIndex numChars, UInt8 *buffer);
 
@@ -330,27 +330,6 @@ static void traverseFromMapCursor(CFBurstTrieRef trie, CompactMapCursor *cursor,
 static Boolean getMapCursorPayloadFromPackedPageEntry(PageEntryPacked *entry, const CompactMapCursor *cursor, uint32_t *payload);
 static Boolean getMapCursorPayloadFromPageEntry(PageEntry *entry, const CompactMapCursor *cursor, uint32_t *payload);
 
-#if 0
-#pragma mark -
-#pragma mark Core Foundation boilerplate
-#endif
-
-static const void *_CFBurstTrieRetainCallback(CFAllocatorRef allocator, const void *value) {
-    CFBurstTrieRetain((CFBurstTrieRef)value);
-    return value;
-}
-
-static void _CFBurstTrieReleaseCallback(CFAllocatorRef allocator, const void *value) {
-    CFBurstTrieRelease((CFBurstTrieRef)value);
-}
-
-const CFDictionaryValueCallBacks kCFBurstTrieValueCallbacks = {0, _CFBurstTrieRetainCallback, _CFBurstTrieReleaseCallback, NULL, NULL};
-
-#if 0
-#pragma mark -
-#pragma mark Public Interface
-#endif
-
 CFBurstTrieRef CFBurstTrieCreateWithOptions(CFDictionaryRef options) {
     CFBurstTrieRef trie = NULL;
     trie = (CFBurstTrieRef) calloc(1, sizeof(struct _CFBurstTrie));
@@ -1891,7 +1870,7 @@ static void serializeCFBurstTrieList(CFBurstTrieRef trie, ListNodeRef listNode,
     }
     
     char _buffer[MAX_BUFFER_SIZE];
-    char bufferSize = (sizeof(Page) + size * (sizeof(PageEntryPacked) + MAX_STRING_SIZE));
+    size_t bufferSize = (sizeof(Page) + size * (sizeof(PageEntryPacked) + MAX_STRING_SIZE));
     char *buffer = bufferSize < MAX_BUFFER_SIZE ? _buffer : (char *) malloc(bufferSize);
     
     Page *page = (Page *)buffer;
@@ -2058,7 +2037,7 @@ static int nodeStringCompare(const void *a, const void *b) {
     return result;
 }
 
-bool containsKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
+static bool containsKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
 {
     uint32_t *ctx = (uint32_t *)context;
     if (exact) *ctx = payload;
index e6c88307a3d9c416a72a5aaa5e1139c70c73c3c6..161a34953e3fcf54d62375710efddf48eb9158fc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFBurstTrie.h
-        Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+        Copyright (c) 2008-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBURSTTRIE__)
@@ -194,8 +194,6 @@ void CFBurstTrieTraverseFromCursor(CFBurstTrieCursorRef cursor, void *ctx, CFBur
 CF_EXPORT
 void CFBurstTrieCursorRelease(CFBurstTrieCursorRef cursor) CF_AVAILABLE(10_8, 6_0);
 
-__private_extern__ const CFDictionaryValueCallBacks kCFBurstTrieValueCallbacks;
-
 CF_EXTERN_C_END
 
 #endif /* __COREFOUNDATION_CFBURSTTRIE__ */
index d7d506ebbe83cf03cdc5922959bc978b8ba29529..ea507a3c92b7588d79aa9fbb2f95374e737bc8fe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFByteOrder.h
-       Copyright (c) 1995-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1995-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBYTEORDER__)
index c3a19207cde66c391ecfc1db4a1474af10084734..cde70e7c9c541c188f19944c5ffaf11a92ce2b8d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFCalendar.c
-       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -83,7 +83,7 @@ static const CFRuntimeClass __CFCalendarClass = {
     __CFCalendarCopyDescription
 };
 
-__private_extern__ void __CFCalendarInitialize(void) {
+CF_PRIVATE void __CFCalendarInitialize(void) {
     __kCFCalendarTypeID = _CFRuntimeRegisterClass(&__CFCalendarClass);
 }
 
@@ -92,7 +92,7 @@ CFTypeID CFCalendarGetTypeID(void) {
     return __kCFCalendarTypeID;
 }
 
-__private_extern__ UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz) {
+CF_PRIVATE UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz) {
     if (calendarID) {
        CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeID);
        CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components);
index 8cee56590af6c1916cc91b4e8c46ae472e3c63f6..ac2b37981f16a4cdc8321df4fef5bd4dbed02224 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFCalendar.h
-       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFCALENDAR__)
index 771ee4d6a42b7db61910339ae1bb9a30b6eb3488..8c55bbfb3c692e503ce5953263f300d927fc3b00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSet.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -145,7 +145,7 @@ CF_INLINE void __CFCSetPutIsInverted(CFMutableCharacterSetRef cset, Boolean isIn
 CF_INLINE void __CFCSetPutHasHashValue(CFMutableCharacterSetRef cset, Boolean hasHash) {(hasHash ? (cset->_base._cfinfo[CF_INFO_BITS] |= __kCFCharSetHasHashValue) : (cset->_base._cfinfo[CF_INFO_BITS] &= ~__kCFCharSetHasHashValue));}
 CF_INLINE void __CFCSetPutClassType(CFMutableCharacterSetRef cset, UInt32 classType) {cset->_base._cfinfo[CF_INFO_BITS] &= ~__kCFCharSetClassTypeMask;  cset->_base._cfinfo[CF_INFO_BITS] |= classType;}
 
-__private_extern__ Boolean __CFCharacterSetIsMutable(CFCharacterSetRef cset) {return __CFCSetIsMutable(cset);}
+CF_PRIVATE Boolean __CFCharacterSetIsMutable(CFCharacterSetRef cset) {return __CFCSetIsMutable(cset);}
 
 /* Inline contents accessor macros
 */
@@ -911,7 +911,7 @@ static Boolean __CFCharacterSetEqual(CFTypeRef cf1, CFTypeRef cf2) {
     if (__CFCSetHasHashValue((CFCharacterSetRef)cf1) && __CFCSetHasHashValue((CFCharacterSetRef)cf2) && ((CFCharacterSetRef)cf1)->_hashValue != ((CFCharacterSetRef)cf2)->_hashValue) return false;
     if (__CFCSetIsEmpty((CFCharacterSetRef)cf1) && __CFCSetIsEmpty((CFCharacterSetRef)cf2) && !isInvertStateIdentical) return false;
 
-    if (__CFCSetClassType((CFCharacterSetRef)cf1) == __CFCSetClassType((CFCharacterSetRef)cf2)) { // Types are identical, we can do it fast
+    if ((__CFCSetClassType((CFCharacterSetRef)cf1) == __CFCSetClassType((CFCharacterSetRef)cf2)) && !__CFCSetIsCompactBitmap((CFCharacterSetRef)cf1)) { // Types are identical, we can do it fast
         switch (__CFCSetClassType((CFCharacterSetRef)cf1)) {
             case __kCFCharSetClassBuiltin:
                 return (__CFCSetBuiltinType((CFCharacterSetRef)cf1) == __CFCSetBuiltinType((CFCharacterSetRef)cf2) && isInvertStateIdentical ? true : false);
@@ -920,12 +920,21 @@ static Boolean __CFCharacterSetEqual(CFTypeRef cf1, CFTypeRef cf2) {
                 return (__CFCSetRangeFirstChar((CFCharacterSetRef)cf1) == __CFCSetRangeFirstChar((CFCharacterSetRef)cf2) && __CFCSetRangeLength((CFCharacterSetRef)cf1) && __CFCSetRangeLength((CFCharacterSetRef)cf2) && isInvertStateIdentical ? true : false);
 
             case __kCFCharSetClassString:
-                if (__CFCSetStringLength((CFCharacterSetRef)cf1) == __CFCSetStringLength((CFCharacterSetRef)cf2) && isInvertStateIdentical) {
+                if (isInvertStateIdentical) {
                     const UniChar *buf1 = __CFCSetStringBuffer((CFCharacterSetRef)cf1);
+                    const UniChar *buf1End = buf1 + __CFCSetStringLength((CFCharacterSetRef)cf1);
                     const UniChar *buf2 = __CFCSetStringBuffer((CFCharacterSetRef)cf2);
-                    CFIndex length = __CFCSetStringLength((CFCharacterSetRef)cf1);
+                    const UniChar *buf2End = buf2 + __CFCSetStringLength((CFCharacterSetRef)cf2);
 
-                    while (length--) if (*buf1++ != *buf2++) return false;
+                    while ((buf1 < buf1End) && (buf2 < buf2End)) {
+                        UniChar char1 = *buf1;
+                        UniChar char2 = *buf2;
+
+                        if (char1 != char2) return false;
+
+                        do { ++buf1; } while ((buf1 < buf1End) && (char1 == *buf1));
+                        do { ++buf2; } while ((buf2 < buf2End) && (char2 == *buf2));
+                    }
                 } else {
                     return false;
                 }
@@ -1232,7 +1241,7 @@ static CFStringRef  __CFCharacterSetCopyDescription(CFTypeRef cf) {
             break;
 
         case __kCFCharSetClassRange:
-            return CFStringCreateWithFormat(CFGetAllocator((CFCharacterSetRef)cf), NULL, CFSTR("<CFCharacterSet Range(%d, %d)>"), __CFCSetRangeFirstChar((CFCharacterSetRef)cf), __CFCSetRangeLength((CFCharacterSetRef)cf));
+            return CFStringCreateWithFormat(CFGetAllocator((CFCharacterSetRef)cf), NULL, CFSTR("<CFCharacterSet Range(%u, %ld)>"), (unsigned int)__CFCSetRangeFirstChar((CFCharacterSetRef)cf), (long)__CFCSetRangeLength((CFCharacterSetRef)cf));
 
         case __kCFCharSetClassString: {
             CFStringRef format = CFSTR("<CFCharacterSet Items(");
@@ -1241,7 +1250,7 @@ static CFStringRef  __CFCharacterSetCopyDescription(CFTypeRef cf) {
             string = CFStringCreateMutable(CFGetAllocator(cf), CFStringGetLength(format) + 7 * length + 2); // length of format + "U+XXXX "(7) * length + ")>"(2)
             CFStringAppend(string, format);
             for (idx = 0;idx < length;idx++) {
-                CFStringAppendFormat(string, NULL, CFSTR("%sU+%04X"), (idx > 0 ? " " : ""), (UInt32)((__CFCSetStringBuffer((CFCharacterSetRef)cf))[idx]));
+                CFStringAppendFormat(string, NULL, CFSTR("%sU+%04X"), (idx > 0 ? " " : ""), (unsigned int)((__CFCSetStringBuffer((CFCharacterSetRef)cf))[idx]));
             }
             CFStringAppend(string, CFSTR(")>"));
             return string;
@@ -1288,7 +1297,7 @@ static const CFRuntimeClass __CFCharacterSetClass = {
 
 static bool __CFCheckForExapendedSet = false;
 
-__private_extern__ void __CFCharacterSetInitialize(void) {
+CF_PRIVATE void __CFCharacterSetInitialize(void) {
     const char *checkForExpandedSet = __CFgetenv("__CF_DEBUG_EXPANDED_SET");
 
     __kCFCharacterSetTypeID = _CFRuntimeRegisterClass(&__CFCharacterSetClass);
@@ -2064,6 +2073,14 @@ void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
     __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__);
 
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
+
     if (!theRange.length || (__CFCSetIsInverted(theSet) && __CFCSetIsEmpty(theSet))) return; // Inverted && empty set contains all char
 
     if (!__CFCSetIsInverted(theSet)) {
@@ -2121,6 +2138,14 @@ void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet, CFRa
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
     __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     if (!theRange.length || (!__CFCSetIsInverted(theSet) && __CFCSetIsEmpty(theSet))) return; // empty set
 
@@ -2187,6 +2212,14 @@ void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet,  CFStr
     CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, addCharactersInString:(NSString *)theString);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     if ((__CFCSetIsEmpty(theSet) && __CFCSetIsInverted(theSet)) || !(length = CFStringGetLength(theString))) return;
 
@@ -2271,6 +2304,14 @@ void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFS
     CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, removeCharactersInString:(NSString *)theString);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     if ((__CFCSetIsEmpty(theSet) && !__CFCSetIsInverted(theSet)) || !(length = CFStringGetLength(theString))) return;
 
@@ -2347,6 +2388,14 @@ void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theO
     CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, formUnionWithCharacterSet:(NSCharacterSet *)theOtherSet);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     if (__CFCSetIsEmpty(theSet) && __CFCSetIsInverted(theSet)) return; // Inverted empty set contains all char
 
@@ -2470,6 +2519,14 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef
     CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, formIntersectionWithCharacterSet:(NSCharacterSet *)theOtherSet);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     if (__CFCSetIsEmpty(theSet) && !__CFCSetIsInverted(theSet)) return; // empty set
 
@@ -2569,7 +2626,9 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef
                 for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) {
                     if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theOtherSet, idx))) {
                         annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
+                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                         CFCharacterSetIntersect(annexPlane, otherSetPlane);
+                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                         if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                     } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) {
                         __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
@@ -2618,7 +2677,9 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef
                 for (idx = 1;idx <= MAX_ANNEX_PLANE;idx++) {
                     if ((otherSetPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSetNoAlloc(tempOtherSet, idx))) {
                         annexPlane = (CFMutableCharacterSetRef)__CFCSetGetAnnexPlaneCharacterSet(theSet, idx);
+                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                         CFCharacterSetIntersect(annexPlane, otherSetPlane);
+                        if (__CFCSetAnnexIsInverted(theSet)) CFCharacterSetInvert(annexPlane);
                         if (__CFCSetIsEmpty(annexPlane) && !__CFCSetIsInverted(annexPlane)) __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
                     } else if (__CFCSetGetAnnexPlaneCharacterSetNoAlloc(theSet, idx)) {
                         __CFCSetPutCharacterSetToAnnexPlane(theSet, NULL, idx);
@@ -2651,6 +2712,14 @@ void CFCharacterSetInvert(CFMutableCharacterSetRef theSet) {
     CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, invert);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
+    
+    if (__CFCSetIsBuiltin((CFCharacterSetRef)theSet) && !__CFCSetIsMutable((CFCharacterSetRef)theSet) && !__CFCSetIsInverted((CFCharacterSetRef)theSet)) {
+        CFCharacterSetRef sharedSet = CFCharacterSetGetPredefined(__CFCSetBuiltinType((CFCharacterSetRef)theSet));
+        if (sharedSet == theSet) { // We're trying to dealloc the builtin set
+            CFAssert1(0, __kCFLogAssertion, "%s: Trying to mutable predefined set.", __PRETTY_FUNCTION__);
+            return; // We don't mutate builtin set
+        }
+    }
 
     __CFCSetPutHasHashValue(theSet, false);
 
index f499893c4fdd51de5ade1ae7d2af4447cb94277a..f31eff4bc5314788b0ee6319e8c81598fb90a0da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSet.h
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
 */
 
 /*!
index a9e9572a6404a9aee3d70c5d86d69253faec0e1f..cd3dfd0c6d02b448f3f1a0617de2c5513a793798 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSetPriv.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFCHARACTERSETPRIV__)
index c2f9c715b9aaaa9efe7898164a5dee50b56b6618..00ff49ac267063037fb374732cc09c886ea728d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFConcreteStreams.c
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
@@ -168,7 +168,7 @@ static Boolean fileOpen(struct _CFStream *stream, CFStreamError *errorCode, Bool
     return TRUE;
 }
 
-__private_extern__ CFIndex fdRead(int fd, UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, Boolean *atEOF) {
+CF_PRIVATE CFIndex fdRead(int fd, UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode, Boolean *atEOF) {
     CFIndex bytesRead = read(fd, buffer, bufferLength);
     if (bytesRead < 0) {
         errorCode->error = errno;
@@ -213,7 +213,7 @@ static CFIndex fileRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLen
 }
 
 #ifdef REAL_FILE_SCHEDULING
-__private_extern__ Boolean fdCanRead(int fd) {
+CF_PRIVATE Boolean fdCanRead(int fd) {
     struct timeval timeout = {0, 0};
     fd_set *readSetPtr;
     fd_set readSet;
@@ -246,7 +246,7 @@ static Boolean fileCanRead(CFReadStreamRef stream, void *info) {
 #endif
 }
 
-__private_extern__ CFIndex fdWrite(int fd, const UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode) {
+CF_PRIVATE CFIndex fdWrite(int fd, const UInt8 *buffer, CFIndex bufferLength, CFStreamError *errorCode) {
     CFIndex bytesWritten = write(fd, buffer, bufferLength);
     if (bytesWritten < 0) {
         errorCode->error = errno;
@@ -277,7 +277,7 @@ static CFIndex fileWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex b
 }
 
 #ifdef REAL_FILE_SCHEDULING
-__private_extern__ Boolean fdCanWrite(int fd) {
+CF_PRIVATE Boolean fdCanWrite(int fd) {
     struct timeval timeout = {0, 0};
     fd_set *writeSetPtr;
     fd_set writeSet;
@@ -676,13 +676,19 @@ static CFIndex dataWrite(CFWriteStreamRef stream, const UInt8 *buffer, CFIndex b
             if (bufferLength > 0) {
                 CFIndex bufSize = BUF_SIZE > bufferLength ? BUF_SIZE : bufferLength;
                 _CFStreamByteBuffer *newBuf = (_CFStreamByteBuffer *)CFAllocatorAllocate(dataStream->bufferAllocator, sizeof(_CFStreamByteBuffer) + bufSize, 0);
-                newBuf->bytes = (UInt8 *)(newBuf + 1);
-                newBuf->capacity = bufSize;
-                newBuf->length = 0;
-                newBuf->next = NULL;
-                dataStream->currentBuf->next = newBuf;
-                dataStream->currentBuf = newBuf;
-                freeSpace = bufSize;
+                if (newBuf == NULL) {
+                    errorCode->error = ENOMEM;
+                    errorCode->domain = kCFStreamErrorDomainPOSIX;
+                    return -1;
+                } else {
+                    newBuf->bytes = (UInt8 *)(newBuf + 1);
+                    newBuf->capacity = bufSize;
+                    newBuf->length = 0;
+                    newBuf->next = NULL;
+                    dataStream->currentBuf->next = newBuf;
+                    dataStream->currentBuf = newBuf;
+                    freeSpace = bufSize;
+                }
             }
         }
         errorCode->error = 0;
@@ -712,7 +718,6 @@ static CFPropertyListRef dataCopyProperty(struct _CFStream *stream, CFStringRef
     for (buf = dataStream->firstBuf; buf != NULL; buf = buf->next) {
         size += buf->length;
     }
-    if (size == 0) return NULL;
     bytes = (UInt8 *)CFAllocatorAllocate(alloc, size, 0);
     currByte = bytes;
     for (buf = dataStream->firstBuf; buf != NULL; buf = buf->next) {
@@ -867,13 +872,6 @@ CFWriteStreamRef CFWriteStreamCreateWithBuffer(CFAllocatorRef alloc, UInt8 *buff
 }
 
 CF_EXPORT CFWriteStreamRef CFWriteStreamCreateWithAllocatedBuffers(CFAllocatorRef alloc, CFAllocatorRef bufferAllocator) {
-    if (!(bufferAllocator == NULL || bufferAllocator == kCFAllocatorNull)) {
-        // If there is a real bufferAllocator, then we don't allow the
-        // CFStream or the contents to be allocated with one of the special
-        // *GCRefZero allocators for now.
-        bufferAllocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(bufferAllocator);
-        alloc = _CFConvertAllocatorToNonGCRefZeroEquivalent(alloc);
-    }
     _CFWriteDataStreamContext ctxt;
     ctxt.firstBuf = NULL;
     ctxt.currentBuf = NULL;
index b6528f57a88ab71ab83994288e78cfc5c11c8ee1..9d2732bf2ca671d7a85924dc2a9bb8c40f0b4eea 100644 (file)
--- a/CFData.c
+++ b/CFData.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFData.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Kevin Perry
 */
 
@@ -195,7 +195,7 @@ static void __CFDataHandleOutOfMemory(CFTypeRef obj, CFIndex numBytes) {
     if(0 < numBytes && numBytes <= CFDATA_MAX_SIZE) {
        msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFData failed"), numBytes);
     } else {
-       msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFData failed. Maximum size: %ld"), numBytes, CFDATA_MAX_SIZE);
+       msg = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Attempt to allocate %ld bytes for NS/CFData failed. Maximum size: %lld"), numBytes, CFDATA_MAX_SIZE);
     }
     {
         CFLog(kCFLogLevelCritical, CFSTR("%@"), msg);
@@ -239,7 +239,7 @@ static CFStringRef __CFDataCopyDescription(CFTypeRef cf) {
     len = __CFDataLength(data);
     bytes = CFDataGetBytePtr(data);
     result = CFStringCreateMutable(CFGetAllocator(data), 0);
-    CFStringAppendFormat(result, NULL, CFSTR("<CFData %p [%p]>{length = %u, capacity = %u, bytes = 0x"), cf, CFGetAllocator(data), len, __CFDataCapacity(data));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFData %p [%p]>{length = %lu, capacity = %lu, bytes = 0x"), cf, CFGetAllocator(data), (unsigned long)len, (unsigned long)__CFDataCapacity(data));
     if (24 < len) {
         for (idx = 0; idx < 16; idx += 4) {
            CFStringAppendFormat(result, NULL, CFSTR("%02x%02x%02x%02x"), bytes[idx], bytes[idx + 1], bytes[idx + 2], bytes[idx + 3]);
@@ -307,7 +307,7 @@ static void __CFDataDeallocate(CFTypeRef cf) {
        CFAllocatorRef deallocator = data->_bytesDeallocator;
        if (deallocator != NULL) {
            _CFAllocatorDeallocateGC(deallocator, data->_bytes);
-           if (!_CFAllocatorIsGCRefZero(deallocator)) CFRelease(deallocator);
+           CFRelease(deallocator);
            data->_bytes = NULL;
        } else {
            if (__CFDataUseAllocator(data)) {
@@ -334,7 +334,7 @@ static const CFRuntimeClass __CFDataClass = {
     __CFDataCopyDescription
 };
 
-__private_extern__ void __CFDataInitialize(void) {
+CF_PRIVATE void __CFDataInitialize(void) {
     __kCFDataTypeID = _CFRuntimeRegisterClass(&__CFDataClass);
 }
 
@@ -411,14 +411,14 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, CFOptionFlags fla
     if (noCopy) {
        __CFAssignWithWriteBarrier((void **)&memory->_bytes, (uint8_t *)bytes);
        if (finalize) {
-            if (_CFAllocatorIsGCRefZero(bytesDeallocator)) {
+            if ((0)) {
                memory->_bytesDeallocator = bytesDeallocator;
             } else {
-               memory->_bytesDeallocator = (CFAllocatorRef)CFRetain(_CFConvertAllocatorToNonGCRefZeroEquivalent(bytesDeallocator));
+               memory->_bytesDeallocator = (CFAllocatorRef)CFRetain(bytesDeallocator);
             }
        }
-       if (CF_IS_COLLECTABLE_ALLOCATOR(bytesDeallocator) && !_CFAllocatorIsGCRefZero(bytesDeallocator)) {
-           // When given a GC allocator which is not one of the GCRefZero ones as the deallocator, we assume that the no-copy memory is GC-allocated with a retain count of (at least) 1 and we should release it now instead of waiting until __CFDataDeallocate.
+       if (CF_IS_COLLECTABLE_ALLOCATOR(bytesDeallocator) && !(0)) {
+           // we assume that the no-copy memory is GC-allocated with a retain count of (at least) 1 and we should release it now instead of waiting until __CFDataDeallocate.
            auto_zone_release(objc_collectableZone(), memory->_bytes);
        }
        __CFDataSetNumBytesUsed(memory, length);
@@ -470,8 +470,7 @@ CFMutableDataRef CFDataCreateMutable(CFAllocatorRef allocator, CFIndex capacity)
     // Do not allow magic allocator for now for mutable datas, because it
     // isn't remembered for proper handling later when growth of the buffer
     // has to occur.
-    Boolean wasMagic = _CFAllocatorIsGCRefZero(allocator);
-    if (0 == capacity) allocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
+    Boolean wasMagic = (0);
     CFMutableDataRef r = (CFMutableDataRef)__CFDataInit(allocator, (0 == capacity) ? kCFMutable : kCFFixedMutable, capacity, NULL, 0, NULL);
     if (wasMagic) CFMakeCollectable(r);
     return r;
@@ -481,8 +480,7 @@ CFMutableDataRef CFDataCreateMutableCopy(CFAllocatorRef allocator, CFIndex capac
     // Do not allow magic allocator for now for mutable datas, because it
     // isn't remembered for proper handling later when growth of the buffer
     // has to occur.
-    Boolean wasMagic = _CFAllocatorIsGCRefZero(allocator);
-    if (0 == capacity) allocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
+    Boolean wasMagic = (0);
     CFMutableDataRef r = (CFMutableDataRef) __CFDataInit(allocator, (0 == capacity) ? kCFMutable : kCFFixedMutable, capacity, CFDataGetBytePtr(data), CFDataGetLength(data), NULL);
     if (wasMagic) CFMakeCollectable(r);
     return r;
index 8647e6ea97ef9f056dd23a2f836efb8dcbcb77fe..7b2394b6a07d5b70525959c58f5f0b334e513f89 100644 (file)
--- a/CFData.h
+++ b/CFData.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFData.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATA__)
index 766ebdac9ba746aafca362de7e5df205d7cdb951..be8b5112a4a64dc7dcacfb2b426c534c432a0f1c 100644 (file)
--- a/CFDate.c
+++ b/CFDate.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFDate.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -34,6 +34,8 @@
 #include <CoreFoundation/CFNumber.h>
 #include "CFInternal.h"
 #include <math.h>
+#include <dispatch/dispatch.h>
+
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <sys/time.h>
 #endif
 const CFTimeInterval kCFAbsoluteTimeIntervalSince1970 = 978307200.0L;
 const CFTimeInterval kCFAbsoluteTimeIntervalSince1904 = 3061152000.0L;
 
-__private_extern__ double __CFTSRRate = 0.0;
+CF_PRIVATE double __CFTSRRate = 0.0;
 static double __CF1_TSRRate = 0.0;
 
-__private_extern__ int64_t __CFTimeIntervalToTSR(CFTimeInterval ti) {
+CF_PRIVATE uint64_t __CFTimeIntervalToTSR(CFTimeInterval ti) {
     if ((ti * __CFTSRRate) > INT64_MAX / 2) return (INT64_MAX / 2);
-    return (int64_t)(ti * __CFTSRRate);
+    return (uint64_t)(ti * __CFTSRRate);
 }
 
-__private_extern__ CFTimeInterval __CFTSRToTimeInterval(int64_t tsr) {
+CF_PRIVATE CFTimeInterval __CFTSRToTimeInterval(uint64_t tsr) {
     return (CFTimeInterval)((double)tsr * __CF1_TSRRate);
 }
 
+CF_PRIVATE CFTimeInterval __CFTimeIntervalUntilTSR(uint64_t tsr) {
+    CFDateGetTypeID();
+    uint64_t now = mach_absolute_time();
+    if (tsr >= now) {
+        return __CFTSRToTimeInterval(tsr - now);
+    } else {
+        return -__CFTSRToTimeInterval(now - tsr);
+    }
+}
+
+// Technically this is 'TSR units' not a strict 'TSR' absolute time
+CF_PRIVATE uint64_t __CFTSRToNanoseconds(uint64_t tsr) {
+    double tsrInNanoseconds = floor(tsr * __CF1_TSRRate * NSEC_PER_SEC);
+    uint64_t ns = (uint64_t)tsrInNanoseconds;
+    return ns;
+}
+
+CF_PRIVATE dispatch_time_t __CFTSRToDispatchTime(uint64_t tsr) {
+    uint64_t tsrInNanoseconds = __CFTSRToNanoseconds(tsr);
+    
+    // It's important to clamp this value to INT64_MAX or it will become interpreted by dispatch_time as a relative value instead of absolute time
+    if (tsrInNanoseconds > INT64_MAX - 1) tsrInNanoseconds = INT64_MAX - 1;
+    
+    // 2nd argument of dispatch_time is a value in nanoseconds, but tsr does not equal nanoseconds on all platforms.
+    return dispatch_time(1, (int64_t)tsrInNanoseconds);
+}
+
 CFAbsoluteTime CFAbsoluteTimeGetCurrent(void) {
     CFAbsoluteTime ret;
     struct timeval tv;
@@ -69,7 +98,7 @@ CFAbsoluteTime CFAbsoluteTimeGetCurrent(void) {
     return ret;
 }
 
-__private_extern__ void __CFDateInitialize(void) {
+CF_PRIVATE void __CFDateInitialize(void) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     struct mach_timebase_info info;
     mach_timebase_info(&info);
@@ -84,7 +113,7 @@ __private_extern__ void __CFDateInitialize(void) {
     __CF1_TSRRate = 1.0 / __CFTSRRate;
 #elif DEPLOYMENT_TARGET_LINUX
     struct timespec res;
-    if (!clock_getres(CLOCK_MONOTONIC, &res)) {
+    if (clock_getres(CLOCK_MONOTONIC, &res) != 0) {
         HALT;
     }
     __CFTSRRate = res.tv_sec + (1000000000 * res.tv_nsec);
index fada953e99413b1c83404520f552b4c1139a3280..f019e0a8f5b308f162d76e0946b40e1c15eeee2e 100644 (file)
--- a/CFDate.h
+++ b/CFDate.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFDate.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATE__)
@@ -67,6 +67,17 @@ CF_IMPLICIT_BRIDGING_DISABLED
 
 typedef const struct __CFTimeZone * CFTimeZoneRef;
 
+
+#if !defined(CF_CALENDAR_ENUM_DEPRECATED)
+#if NS_ENABLE_CALENDAR_DEPRECATIONS
+#define CF_CALENDAR_ENUM_DEPRECATED(A, B, C, D, ...) CF_ENUM_DEPRECATED(A, B, C, D, __VA_ARGS__)
+#define CF_CALENDAR_DEPRECATED(A, B, C, D, ...) CF_DEPRECATED(A, B, C, D, __VA_ARGS__)
+#else
+#define CF_CALENDAR_ENUM_DEPRECATED(A, B, C, D, ...) CF_ENUM_AVAILABLE(A, C)
+#define CF_CALENDAR_DEPRECATED(A, B, C, D, ...) CF_AVAILABLE(A, C)
+#endif
+#endif
+
 typedef struct {
     SInt32 year;
     SInt8 month;
@@ -74,7 +85,7 @@ typedef struct {
     SInt8 hour;
     SInt8 minute;
     double second;
-} CFGregorianDate;
+} CFGregorianDate CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 typedef struct {
     SInt32 years;
@@ -83,41 +94,41 @@ typedef struct {
     SInt32 hours;
     SInt32 minutes;
     double seconds;
-} CFGregorianUnits;
+} CFGregorianUnits CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 typedef CF_OPTIONS(CFOptionFlags, CFGregorianUnitFlags) {
-    kCFGregorianUnitsYears = (1UL << 0),
-    kCFGregorianUnitsMonths = (1UL << 1),
-    kCFGregorianUnitsDays = (1UL << 2),
-    kCFGregorianUnitsHours = (1UL << 3),
-    kCFGregorianUnitsMinutes = (1UL << 4),
-    kCFGregorianUnitsSeconds = (1UL << 5),
-    kCFGregorianAllUnits = 0x00FFFFFF
+    kCFGregorianUnitsYears CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 0),
+    kCFGregorianUnitsMonths CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 1),
+    kCFGregorianUnitsDays CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 2),
+    kCFGregorianUnitsHours CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 3),
+    kCFGregorianUnitsMinutes CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 4),
+    kCFGregorianUnitsSeconds CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = (1UL << 5),
+    kCFGregorianAllUnits CF_CALENDAR_ENUM_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead") = 0x00FFFFFF
 };
 
 CF_EXPORT
-Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags);
+Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz);
+CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz);
+CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef tz, CFGregorianUnits units);
+CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef tz, CFGregorianUnits units) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1, CFAbsoluteTime at2, CFTimeZoneRef tz, CFOptionFlags unitFlags);
+CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1, CFAbsoluteTime at2, CFTimeZoneRef tz, CFOptionFlags unitFlags) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz);
+SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz);
+SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXPORT
-SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz);
+SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) CF_CALENDAR_DEPRECATED(10_4, 10_9, 2_0, 7_0, "Use CFCalendar or NSCalendar API instead");
 
 CF_EXTERN_C_END
 
index 1b1426562e4d9b498b4b2f5334754b635c6c70f3..80f270134ac14fc74065cd9496eab4e80ac56926 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*        CFDateFormatter.c
-        Copyright (c) 2002-2012, Apple Inc. All rights reserved.
+        Copyright (c) 2002-2013, Apple Inc. All rights reserved.
         Responsibility: David Smith
 */
 
 #include "CFPriv.h"
 #include "CFInternal.h"
 #include "CFLocaleInternal.h"
-#include <unicode/udat.h>
-#include <unicode/udatpg.h>
+#include "CFICULogging.h"
 #include <math.h>
 #include <float.h>
 
+
 typedef CF_ENUM(CFIndex, CFDateFormatterAmbiguousYearHandling) {
     kCFDateFormatterAmbiguousYearFailToParse = 0, // fail the parse; the default formatter behavior
     kCFDateFormatterAmbiguousYearAssumeToNone = 1, // default to assuming era 1, or the year 0-99
@@ -53,7 +53,6 @@ typedef CF_ENUM(CFIndex, CFDateFormatterAmbiguousYearHandling) {
 };
 
 extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz);
-static void __CFDateFormatterCustomize(CFDateFormatterRef formatter);
 
 CF_EXPORT const CFStringRef kCFDateFormatterCalendarIdentifierKey;
 
@@ -71,6 +70,37 @@ CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRef allocato
     return (CFArrayRef)CFDateFormatterCreateDateFormatFromTemplate(allocator, (CFStringRef)tmplates, options, locale);
 }
 
+static Boolean useTemplatePatternGenerator(const char *localeName, void(^work)(UDateTimePatternGenerator *ptg)) {
+    static UDateTimePatternGenerator *ptg;
+    static pthread_mutex_t ptgLock = PTHREAD_MUTEX_INITIALIZER;
+    static const char *ptgLocaleName;
+
+    static void (^flushCache)() = ^{
+        __cficu_udatpg_close(ptg);
+        ptg = NULL;
+        free((void *)ptgLocaleName);
+        ptgLocaleName = NULL;
+    };
+    pthread_mutex_lock(&ptgLock);
+    if (ptgLocaleName && strcmp(ptgLocaleName, localeName) != 0) {
+        flushCache();
+    }
+    UErrorCode status = U_ZERO_ERROR;
+    if (!ptg) {
+        ptg = __cficu_udatpg_open(localeName, &status);
+        if (ptg && !U_FAILURE(status)) {
+            ptgLocaleName = strdup(localeName);
+        }
+    }
+    Boolean result = (NULL != ptg && !U_FAILURE(status));
+    if (result && work) {
+        work(ptg);
+    }
+    pthread_mutex_unlock(&ptgLock);
+    return result;
+}
+    
+
 CFStringRef CFDateFormatterCreateDateFormatFromTemplate(CFAllocatorRef allocator, CFStringRef tmplate, CFOptionFlags options, CFLocaleRef locale) {
     if (allocator) __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     if (locale) __CFGenericValidateType(locale, CFLocaleGetTypeID());
@@ -88,62 +118,63 @@ CFStringRef CFDateFormatterCreateDateFormatFromTemplate(CFAllocatorRef allocator
     if (NULL == cstr) {
         return NULL;
     }
-
-    UErrorCode status = U_ZERO_ERROR;
-    UDateTimePatternGenerator *ptg = udatpg_open(cstr, &status);
-    if (NULL == ptg || U_FAILURE(status)) {
-       return NULL;
-    }
-
-    CFTypeRef result = tmplateIsString ? NULL : (CFTypeRef)CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
-
-    for (CFIndex idx = 0, cnt = tmplateIsString ? 1 : CFArrayGetCount((CFArrayRef)tmplate); idx < cnt; idx++) {
-        CFStringRef tmplateString = tmplateIsString ? (CFStringRef)tmplate : (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)tmplate, idx);
-        CFStringRef resultString = NULL;
-
-        tmplateString = __CFDateFormatterCreateForcedTemplate(locale ? locale : CFLocaleGetSystem(), tmplateString);
-
-        CFIndex jCount = 0; // the only interesting cases are 0, 1, and 2 (adjacent)
-        CFRange r = CFStringFind(tmplateString, CFSTR("j"), 0);
-        if (kCFNotFound != r.location) {
-            jCount++;
-            if ((r.location + 1 < CFStringGetLength(tmplateString)) && ('j' == CFStringGetCharacterAtIndex(tmplateString, r.location + 1))) {
+    
+    __block CFTypeRef result = tmplateIsString ? NULL : (CFTypeRef)CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+
+    Boolean success = useTemplatePatternGenerator(cstr, ^(UDateTimePatternGenerator *ptg) {
+        
+        
+        for (CFIndex idx = 0, cnt = tmplateIsString ? 1 : CFArrayGetCount((CFArrayRef)tmplate); idx < cnt; idx++) {
+            CFStringRef tmplateString = tmplateIsString ? (CFStringRef)tmplate : (CFStringRef)CFArrayGetValueAtIndex((CFArrayRef)tmplate, idx);
+            CFStringRef resultString = NULL;
+            
+            tmplateString = __CFDateFormatterCreateForcedTemplate(locale ? locale : CFLocaleGetSystem(), tmplateString);
+            
+            CFIndex jCount = 0; // the only interesting cases are 0, 1, and 2 (adjacent)
+            CFRange r = CFStringFind(tmplateString, CFSTR("j"), 0);
+            if (kCFNotFound != r.location) {
                 jCount++;
+                if ((r.location + 1 < CFStringGetLength(tmplateString)) && ('j' == CFStringGetCharacterAtIndex(tmplateString, r.location + 1))) {
+                    jCount++;
+                }
             }
-        }
-
-        UChar pattern[BUFFER_SIZE], skel[BUFFER_SIZE], bpat[BUFFER_SIZE];
-        CFIndex tmpltLen = CFStringGetLength(tmplateString);
-        if (BUFFER_SIZE < tmpltLen) tmpltLen = BUFFER_SIZE;
-        CFStringGetCharacters(tmplateString, CFRangeMake(0, tmpltLen), (UniChar *)pattern);
-        CFRelease(tmplateString);
-
-        int32_t patlen = tmpltLen;
-        status = U_ZERO_ERROR;
-        int32_t skellen = udatpg_getSkeleton(ptg, pattern, patlen, skel, sizeof(skel) / sizeof(skel[0]), &status);
-        if (!U_FAILURE(status)) {
-            if ((0 < jCount) && (skellen + jCount < (sizeof(skel) / sizeof(skel[0])))) {
-                skel[skellen++] = 'j';
-                if (1 < jCount) skel[skellen++] = 'j';
-            }
-
-            status = U_ZERO_ERROR;
-            int32_t bpatlen = udatpg_getBestPattern(ptg, skel, skellen, bpat, sizeof(bpat) / sizeof(bpat[0]), &status);
+            
+            UChar pattern[BUFFER_SIZE], skel[BUFFER_SIZE], bpat[BUFFER_SIZE];
+            CFIndex tmpltLen = CFStringGetLength(tmplateString);
+            if (BUFFER_SIZE < tmpltLen) tmpltLen = BUFFER_SIZE;
+            CFStringGetCharacters(tmplateString, CFRangeMake(0, tmpltLen), (UniChar *)pattern);
+            CFRelease(tmplateString);
+            
+            int32_t patlen = tmpltLen;
+            UErrorCode status = U_ZERO_ERROR;
+            int32_t skellen = __cficu_udatpg_getSkeleton(ptg, pattern, patlen, skel, sizeof(skel) / sizeof(skel[0]), &status);
             if (!U_FAILURE(status)) {
-                resultString = CFStringCreateWithCharacters(allocator, (const UniChar *)bpat, bpatlen);
+                if ((0 < jCount) && (skellen + jCount < (sizeof(skel) / sizeof(skel[0])))) {
+                    skel[skellen++] = 'j';
+                    if (1 < jCount) skel[skellen++] = 'j';
+                }
+                
+                status = U_ZERO_ERROR;
+                int32_t bpatlen = __cficu_udatpg_getBestPattern(ptg, skel, skellen, bpat, sizeof(bpat) / sizeof(bpat[0]), &status);
+                if (!U_FAILURE(status)) {
+                    resultString = CFStringCreateWithCharacters(allocator, (const UniChar *)bpat, bpatlen);
+                }
+            }
+            
+            if (tmplateIsString) {
+                result = (CFTypeRef)resultString;
+            } else {
+                CFArrayAppendValue((CFMutableArrayRef)result, resultString ? (CFTypeRef)resultString : (CFTypeRef)kCFNull);
+                if (resultString) CFRelease(resultString);
             }
         }
-
-        if (tmplateIsString) {
-            result = (CFTypeRef)resultString;
-        } else {
-            CFArrayAppendValue((CFMutableArrayRef)result, resultString ? (CFTypeRef)resultString : (CFTypeRef)kCFNull);
-            if (resultString) CFRelease(resultString);
-        }
+    });
+    
+    if (!success) {
+        CFRelease(result);
+        result = NULL;
     }
-
-    udatpg_close(ptg);
-
+    
     return (CFStringRef)result;
 }
 
@@ -186,6 +217,36 @@ struct __CFDateFormatter {
         CFStringRef _AMSymbol;
         CFStringRef _PMSymbol;
         CFNumberRef _AmbiguousYearStrategy;
+        CFBooleanRef _UsesCharacterDirection;
+        
+        // the following are from preferences
+        CFArrayRef _CustomEraSymbols;
+        CFArrayRef _CustomLongEraSymbols;
+        CFArrayRef _CustomMonthSymbols;
+        CFArrayRef _CustomShortMonthSymbols;
+        CFArrayRef _CustomVeryShortMonthSymbols;
+        CFArrayRef _CustomStandaloneMonthSymbols;
+        CFArrayRef _CustomShortStandaloneMonthSymbols;
+        CFArrayRef _CustomVeryShortStandaloneMonthSymbols;
+        CFArrayRef _CustomWeekdaySymbols;
+        CFArrayRef _CustomShortWeekdaySymbols;
+        CFArrayRef _CustomVeryShortWeekdaySymbols;
+        CFArrayRef _CustomStandaloneWeekdaySymbols;
+        CFArrayRef _CustomShortStandaloneWeekdaySymbols;
+        CFArrayRef _CustomVeryShortStandaloneWeekdaySymbols;
+        CFArrayRef _CustomQuarterSymbols;
+        CFArrayRef _CustomShortQuarterSymbols;
+        CFArrayRef _CustomStandaloneQuarterSymbols;
+        CFArrayRef _CustomShortStandaloneQuarterSymbols;
+        CFStringRef _CustomDateFormat;
+        CFStringRef _CustomTimeFormat;
+        CFBooleanRef _Custom24Hour;
+        CFBooleanRef _Custom12Hour;
+        CFStringRef _CustomAMSymbol;
+        CFStringRef _CustomPMSymbol;
+        CFDictionaryRef _CustomFirstWeekday;
+        CFDictionaryRef _CustomMinDaysInFirstWeek;
+        
     } _property;
 };
 
@@ -196,7 +257,7 @@ static CFStringRef __CFDateFormatterCopyDescription(CFTypeRef cf) {
 
 static void __CFDateFormatterDeallocate(CFTypeRef cf) {
     CFDateFormatterRef formatter = (CFDateFormatterRef)cf;
-    if (formatter->_df) udat_close(formatter->_df);
+    if (formatter->_df) __cficu_udat_close(formatter->_df);
     if (formatter->_locale) CFRelease(formatter->_locale);
     if (formatter->_format) CFRelease(formatter->_format);
     if (formatter->_defformat) CFRelease(formatter->_defformat);
@@ -229,19 +290,275 @@ static void __CFDateFormatterDeallocate(CFTypeRef cf) {
     CFReleaseIfNotNull(formatter->_property._AMSymbol);
     CFReleaseIfNotNull(formatter->_property._PMSymbol);
     CFReleaseIfNotNull(formatter->_property._AmbiguousYearStrategy);
+    CFReleaseIfNotNull(formatter->_property._UsesCharacterDirection);
+    CFReleaseIfNotNull(formatter->_property._CustomEraSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomLongEraSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomVeryShortMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomVeryShortWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomStandaloneMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortStandaloneMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomVeryShortStandaloneMonthSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomStandaloneWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortStandaloneWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomVeryShortStandaloneWeekdaySymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomQuarterSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortQuarterSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomShortStandaloneQuarterSymbols);
+    CFReleaseIfNotNull(formatter->_property._CustomDateFormat);
+    CFReleaseIfNotNull(formatter->_property._CustomTimeFormat);
+    CFReleaseIfNotNull(formatter->_property._Custom24Hour);
+    CFReleaseIfNotNull(formatter->_property._Custom12Hour);
+    CFReleaseIfNotNull(formatter->_property._CustomAMSymbol);
+    CFReleaseIfNotNull(formatter->_property._CustomPMSymbol);
+    CFReleaseIfNotNull(formatter->_property._CustomFirstWeekday);
+    CFReleaseIfNotNull(formatter->_property._CustomMinDaysInFirstWeek);
 }
 
 static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef formatter, CFStringRef inString);
 
 static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringRef key, CFTypeRef value, Boolean directToICU);
-
+static void __CFDateFormatterStoreSymbolPrefs(const void *key, const void *value, void *context);
+extern CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale);
+static void __substituteFormatStringFromPrefsDFRelative(CFDateFormatterRef formatter);
+static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bool doTime);
+static void __CFDateFormatterSetSymbolsArray(UDateFormat *icudf, int32_t icucode, int index_base, CFTypeRef value);
+    
+static void __ReadCustomUDateFormatProperty(CFDateFormatterRef formatter) {
+    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
+    CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateTimeSymbols")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
+        CFDictionaryApplyFunction((CFDictionaryRef)metapref, __CFDateFormatterStoreSymbolPrefs, formatter);
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleFirstWeekday")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
+        formatter->_property._CustomFirstWeekday = (CFDictionaryRef)CFRetain(metapref);
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleMinDaysInFirstWeek")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
+        formatter->_property._CustomMinDaysInFirstWeek = (CFDictionaryRef)CFRetain(metapref);
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUForce24HourTime")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFBooleanGetTypeID()) {
+        formatter->_property._Custom24Hour = (CFBooleanRef)CFRetain(metapref);
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUForce12HourTime")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFBooleanGetTypeID()) {
+        formatter->_property._Custom12Hour = (CFBooleanRef)CFRetain(metapref);
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateFormatStrings")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
+        CFStringRef key;
+        switch (formatter->_dateStyle) {
+            case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
+            case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
+            case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
+            case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
+            default: key = CFSTR("0"); break;
+        }
+        CFStringRef dateFormat = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
+        if (NULL != dateFormat && CFGetTypeID(dateFormat) == CFStringGetTypeID()) {
+            formatter->_property._CustomDateFormat = (CFStringRef)CFRetain(dateFormat);
+        }
+    }
+    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUTimeFormatStrings")) : NULL;
+    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
+        CFStringRef key;
+        switch (formatter->_timeStyle) {
+            case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
+            case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
+            case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
+            case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
+            default: key = CFSTR("0"); break;
+        }
+        CFStringRef timeFormat = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
+        if (NULL != timeFormat && CFGetTypeID(timeFormat) == CFStringGetTypeID()) {
+            formatter->_property._CustomTimeFormat = (CFStringRef)CFRetain(timeFormat);
+        }
+    }
+}
+    
+static void __ApplyUDateFormatSymbol(CFDateFormatterRef formatter) {
+    UDateFormatSymbolType types[18] = {UDAT_ERAS,
+                                     UDAT_ERA_NAMES,
+                                     UDAT_MONTHS,
+                                     UDAT_SHORT_MONTHS,
+                                     UDAT_NARROW_MONTHS,
+                                     UDAT_STANDALONE_MONTHS,
+                                     UDAT_STANDALONE_SHORT_MONTHS,
+                                     UDAT_STANDALONE_NARROW_MONTHS,
+                                     UDAT_WEEKDAYS,
+                                     UDAT_SHORT_WEEKDAYS,
+                                     UDAT_NARROW_WEEKDAYS,
+                                     UDAT_STANDALONE_WEEKDAYS,
+                                     UDAT_STANDALONE_SHORT_WEEKDAYS,
+                                     UDAT_STANDALONE_NARROW_WEEKDAYS,
+                                     UDAT_QUARTERS,
+                                     UDAT_SHORT_QUARTERS,
+                                     UDAT_STANDALONE_QUARTERS,
+                                     UDAT_STANDALONE_SHORT_QUARTERS};
+    int offsets[18] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0};
+    CFArrayRef symbols[18] = {formatter->_property._EraSymbols,
+                              formatter->_property._LongEraSymbols,
+                              formatter->_property._MonthSymbols,
+                              formatter->_property._ShortMonthSymbols,
+                              formatter->_property._VeryShortMonthSymbols,
+                              formatter->_property._StandaloneMonthSymbols,
+                              formatter->_property._ShortStandaloneMonthSymbols,
+                              formatter->_property._VeryShortStandaloneMonthSymbols,
+                              formatter->_property._WeekdaySymbols,
+                              formatter->_property._ShortWeekdaySymbols,
+                              formatter->_property._VeryShortWeekdaySymbols,
+                              formatter->_property._StandaloneWeekdaySymbols,
+                              formatter->_property._ShortStandaloneWeekdaySymbols,
+                              formatter->_property._VeryShortStandaloneWeekdaySymbols,
+                              formatter->_property._QuarterSymbols,
+                              formatter->_property._ShortQuarterSymbols,
+                              formatter->_property._StandaloneQuarterSymbols,
+                              formatter->_property._ShortStandaloneQuarterSymbols
+    };
+    CFArrayRef customSymbols[18] = {formatter->_property._CustomEraSymbols,
+        formatter->_property._CustomLongEraSymbols,
+        formatter->_property._CustomMonthSymbols,
+        formatter->_property._CustomShortMonthSymbols,
+        formatter->_property._CustomVeryShortMonthSymbols,
+        formatter->_property._CustomStandaloneMonthSymbols,
+        formatter->_property._CustomShortStandaloneMonthSymbols,
+        formatter->_property._CustomVeryShortStandaloneMonthSymbols,
+        formatter->_property._CustomWeekdaySymbols,
+        formatter->_property._CustomShortWeekdaySymbols,
+        formatter->_property._CustomVeryShortWeekdaySymbols,
+        formatter->_property._CustomStandaloneWeekdaySymbols,
+        formatter->_property._CustomShortStandaloneWeekdaySymbols,
+        formatter->_property._CustomVeryShortStandaloneWeekdaySymbols,
+        formatter->_property._CustomQuarterSymbols,
+        formatter->_property._CustomShortQuarterSymbols,
+        formatter->_property._CustomStandaloneQuarterSymbols,
+        formatter->_property._CustomShortStandaloneQuarterSymbols
+    };
+    
+    for (CFIndex i = 0; i < 18; i++) {
+        if (symbols[i] != NULL) {
+            __CFDateFormatterSetSymbolsArray(formatter->_df, types[i], offsets[i], symbols[i]);
+        } else if (customSymbols[i] != NULL) {
+            __CFDateFormatterSetSymbolsArray(formatter->_df, types[i], offsets[i], customSymbols[i]);
+        }
+    }
+    
+    CFStringRef ampm[2];
+    ampm[0] = NULL;
+    ampm[1] = NULL;
+    
+    if (formatter->_property._AMSymbol != NULL) {
+        ampm[0] = formatter->_property._AMSymbol;
+    } else if (formatter->_property._CustomAMSymbol != NULL) {
+        ampm[0] = formatter->_property._CustomAMSymbol;
+    }
+    if (formatter->_property._PMSymbol != NULL) {
+        ampm[1] = formatter->_property._PMSymbol;
+    } else if (formatter->_property._CustomPMSymbol != NULL) {
+        ampm[1] = formatter->_property._CustomPMSymbol;
+    }
+    for (CFIndex i = 0; i < 2; i++) {
+        CFStringRef sym = ampm[i];
+        if (sym != NULL) {
+            CFIndex item_cnt = CFStringGetLength(sym);
+            STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt));
+            UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(sym);
+            if (NULL == item_ustr) {
+                item_cnt = __CFMin(BUFFER_SIZE, item_cnt);
+                CFStringGetCharacters(sym, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
+                item_ustr = item_buffer;
+            }
+            UErrorCode status = U_ZERO_ERROR;
+            __cficu_udat_setSymbols(formatter->_df, UDAT_AM_PMS, i, item_ustr, item_cnt, &status);
+        }
+    }
+}
+    
+static void __SetCalendarProperties(CFDateFormatterRef df) {
+    CFStringRef calName = df->_property._CalendarName ? (df->_property._CalendarName) : NULL;
+    if (!calName) {
+        calName = (CFStringRef)CFLocaleGetValue(df->_locale, kCFLocaleCalendarIdentifierKey);
+    }
+    UErrorCode status = U_ZERO_ERROR;
+    const UCalendar *cal = __cficu_udat_getCalendar(df->_df);
+    UCalendar *new_cal = NULL;
+    
+    if (df->_property._Calendar != NULL || df->_property._CalendarName != NULL) {
+        UCalendar *caltmp = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(df->_locale), df->_property._TimeZone);
+        if (caltmp) {
+            new_cal = caltmp;
+        }
+    }
+    if (new_cal == NULL) {
+        new_cal = __cficu_ucal_clone(cal, &status);
+    }
+    
+    if (df->_property._IsLenient != NULL) {
+        status = U_ZERO_ERROR;
+        CFBooleanRef value = df->_property._IsLenient;
+        __cficu_ucal_setAttribute(new_cal, UCAL_LENIENT, (kCFBooleanTrue == value));
+    }
+    if (df->_property._TimeZone != NULL) {
+        status = U_ZERO_ERROR;
+        UChar ubuffer[BUFFER_SIZE];
+        CFStringRef tznam = CFTimeZoneGetName(df->_property._TimeZone);
+        CFIndex ucnt = CFStringGetLength(tznam);
+        if (BUFFER_SIZE < ucnt) ucnt = BUFFER_SIZE;
+        CFStringGetCharacters(tznam, CFRangeMake(0, ucnt), (UniChar *)ubuffer);
+        __cficu_ucal_setTimeZone(new_cal, ubuffer, ucnt, &status);
+    }
+    if (df->_property._GregorianStartDate != NULL) {
+        status = U_ZERO_ERROR;
+        CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)df->_property._GregorianStartDate);
+        UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
+        __cficu_ucal_setGregorianChange(new_cal, udate, &status);
+    } else if (calName && CFEqual(calName, kCFCalendarIdentifierGregorian)) {
+        status = U_ZERO_ERROR;
+        UDate udate = __cficu_ucal_getGregorianChange(cal, &status);
+        CFAbsoluteTime at = U_SUCCESS(status) ? (udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970) : -13197600000.0; // Oct 15, 1582
+        udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
+        status = U_ZERO_ERROR;
+        __cficu_ucal_setGregorianChange(new_cal, udate, &status);
+    }
+    if (df->_property._Calendar != NULL) {
+        __cficu_ucal_setAttribute(new_cal, UCAL_FIRST_DAY_OF_WEEK, CFCalendarGetFirstWeekday((CFCalendarRef)df->_property._Calendar));
+    } else if (df->_property._CustomFirstWeekday != NULL) {
+        CFNumberRef firstWeekday = (CFNumberRef)CFDictionaryGetValue(df->_property._CustomFirstWeekday, calName);
+        if (NULL != firstWeekday && CFGetTypeID(firstWeekday) == CFNumberGetTypeID()) {
+            CFIndex wkdy;
+            if (CFNumberGetValue((CFNumberRef)firstWeekday, kCFNumberCFIndexType, &wkdy)) {
+                status = U_ZERO_ERROR;
+                __cficu_ucal_setAttribute(new_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy);
+            }
+        }
+    }
+    
+    if (df->_property._Calendar != NULL) {
+        __cficu_ucal_setAttribute(new_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, CFCalendarGetMinimumDaysInFirstWeek((CFCalendarRef)df->_property._Calendar));
+    } else if (df->_property._CustomMinDaysInFirstWeek != NULL) {
+        CFNumberRef minDays = (CFNumberRef)CFDictionaryGetValue(df->_property._CustomMinDaysInFirstWeek, calName);
+        if (NULL != minDays && CFGetTypeID(minDays) == CFNumberGetTypeID()) {
+            CFIndex mwd;
+            if (CFNumberGetValue((CFNumberRef)minDays, kCFNumberCFIndexType, &mwd)) {
+                status = U_ZERO_ERROR;
+                __cficu_ucal_setAttribute(new_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd);
+            }
+        }
+    }
+    __cficu_udat_setCalendar(df->_df, new_cal);
+    __cficu_ucal_close(new_cal);
+}
+    
 #define RESET_PROPERTY(C, K) \
     if (df->_property. C) __CFDateFormatterSetProperty(df, K, df->_property. C, true);
 
-// This blows away any custom format string the client may have set
-// on the date formatter with CFDateFormatterSetFormat().
 static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomFormat) {
-    if (df->_df) udat_close(df->_df);
+    if (df->_df) __cficu_udat_close(df->_df);
     df->_df = NULL;
 
     // uses _timeStyle, _dateStyle, _locale, _property._TimeZone; sets _df, _format, _defformat
@@ -255,9 +572,7 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     CFStringRef tmpTZName = df->_property._TimeZone ? CFTimeZoneGetName(df->_property._TimeZone) : CFSTR("GMT");
     CFStringGetCharacters(tmpTZName, CFRangeMake(0, CFStringGetLength(tmpTZName)), (UniChar *)tz_buffer);
 
-    df->_property._HasCustomFormat = NULL;
-
-    int32_t udstyle = 0, utstyle = 0;
+    int32_t udstyle = 0, utstyle = 0; // effectively this makes UDAT_FULL the default for unknown dateStyle/timeStyle values
     switch (df->_dateStyle) {
     case kCFDateFormatterNoStyle: udstyle = UDAT_NONE; break;
     case kCFDateFormatterShortStyle: udstyle = UDAT_SHORT; break;
@@ -279,34 +594,61 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     }
 
     UErrorCode status = U_ZERO_ERROR;
-    UDateFormat *icudf = udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, loc_buffer, tz_buffer, CFStringGetLength(tmpTZName), NULL, 0, &status);
+    UDateFormat *icudf = __cficu_udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, loc_buffer, tz_buffer, CFStringGetLength(tmpTZName), NULL, 0, &status);
     if (NULL == icudf || U_FAILURE(status)) {
         return;
     }
-    udat_setLenient(icudf, 0);
+    if (df->_property._IsLenient != NULL) {
+        __cficu_udat_setLenient(icudf, (kCFBooleanTrue == df->_property._IsLenient));
+    } else {
+        __cficu_udat_setLenient(icudf, 0);
+    }
     if (kCFDateFormatterNoStyle == df->_dateStyle && kCFDateFormatterNoStyle == df->_timeStyle) {
         if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) {
             UErrorCode s = U_ZERO_ERROR;
-            udat_applyPatternRelative(icudf, NULL, 0, NULL, 0, &s);
+            __cficu_udat_applyPatternRelative(icudf, NULL, 0, NULL, 0, &s);
         } else {
-            udat_applyPattern(icudf, false, NULL, 0);
+            __cficu_udat_applyPattern(icudf, false, NULL, 0);
         }
     }
+    if (!wantRelative && df->_property._HasCustomFormat == kCFBooleanTrue) {
+        CFIndex cnt = CFStringGetLength(df->_format);
+        STACK_BUFFER_DECL(UChar, ubuffer, cnt);
+        const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)df->_format);
+        if (NULL == ustr) {
+            CFStringGetCharacters(df->_format, CFRangeMake(0, cnt), (UniChar *)ubuffer);
+            ustr = ubuffer;
+        }
+        __cficu_udat_applyPattern(icudf, false, ustr, cnt);
+    }
+    
     CFStringRef calident = (CFStringRef)CFLocaleGetValue(df->_locale, kCFLocaleCalendarIdentifierKey);
     if (calident && CFEqual(calident, kCFCalendarIdentifierGregorian)) {
         status = U_ZERO_ERROR;
-        udat_set2DigitYearStart(icudf, -631152000000.0, &status); // 1950-01-01 00:00:00 GMT
+        __cficu_udat_set2DigitYearStart(icudf, -631152000000.0, &status); // 1950-01-01 00:00:00 GMT
     }
     df->_df = icudf;
+    
+    __ReadCustomUDateFormatProperty(df);
+    __SetCalendarProperties(df);
+    
+    if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) {
+        __substituteFormatStringFromPrefsDFRelative(df);
+    } else {
+        __substituteFormatStringFromPrefsDF(df, false);
+        __substituteFormatStringFromPrefsDF(df, true);
+    }
 
-    __CFDateFormatterCustomize(df);
+    __ApplyUDateFormatSymbol(df);
+    
 
     if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) {
         UChar dateBuffer[BUFFER_SIZE];
         UChar timeBuffer[BUFFER_SIZE];
         status = U_ZERO_ERROR;
-        CFIndex dateLen = udat_toPatternRelativeDate(icudf, dateBuffer, BUFFER_SIZE, &status);
-        CFIndex timeLen = (utstyle != UDAT_NONE) ? udat_toPatternRelativeTime(icudf, timeBuffer, BUFFER_SIZE, &status) : 0;
+        CFIndex dateLen = __cficu_udat_toPatternRelativeDate(icudf, dateBuffer, BUFFER_SIZE, &status);
+        CFIndex timeLen = (utstyle != UDAT_NONE) ? __cficu_udat_toPatternRelativeTime(icudf, timeBuffer, BUFFER_SIZE, &status) : 0;
         if (U_SUCCESS(status) && dateLen <= BUFFER_SIZE && timeLen <= BUFFER_SIZE) {
             // We assume that the 12/24-hour forcing preferences only affect the Time component
             CFStringRef newFormat = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)timeBuffer, timeLen);
@@ -317,12 +659,12 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
                 CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)timeBuffer);
                 timeLen = cnt;
                 status = U_ZERO_ERROR;
-                udat_applyPatternRelative(icudf, dateBuffer, dateLen, timeBuffer, timeLen, &status);
+                __cficu_udat_applyPatternRelative(icudf, dateBuffer, dateLen, timeBuffer, timeLen, &status);
                 // ignore error and proceed anyway, what else can be done?
 
                 UChar ubuffer[BUFFER_SIZE];
                 status = U_ZERO_ERROR;
-                int32_t ret = udat_toPattern(icudf, false, ubuffer, BUFFER_SIZE, &status); // read out current pattern
+                int32_t ret = __cficu_udat_toPattern(icudf, false, ubuffer, BUFFER_SIZE, &status); // read out current pattern
                 if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
                     if (df->_format) CFRelease(df->_format);
                     df->_format = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, ret);
@@ -334,7 +676,7 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     } else {
         UChar ubuffer[BUFFER_SIZE];
         status = U_ZERO_ERROR;
-        int32_t ret = udat_toPattern(icudf, false, ubuffer, BUFFER_SIZE, &status);
+        int32_t ret = __cficu_udat_toPattern(icudf, false, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
             CFStringRef newFormat = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, ret);
             CFStringRef formatString = __CFDateFormatterCreateForcedString(df, newFormat);
@@ -348,8 +690,8 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
                     ustr = ubuffer;
                 }
                 UErrorCode status = U_ZERO_ERROR;
-//            udat_applyPattern(df->_df, false, ustr, cnt, &status);
-                udat_applyPattern(df->_df, false, ustr, cnt);
+//            __cficu_udat_applyPattern(df->_df, false, ustr, cnt, &status);
+                __cficu_udat_applyPattern(df->_df, false, ustr, cnt);
                 if (U_SUCCESS(status)) {
                     if (df->_format) CFRelease(df->_format);
                     df->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(df), formatString);
@@ -362,20 +704,6 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     if (df->_defformat) CFRelease(df->_defformat);
     df->_defformat = df->_format ? (CFStringRef)CFRetain(df->_format) : NULL;
 
-    CFStringRef calName = df->_property._CalendarName ? (df->_property._CalendarName) : NULL;
-    if (!calName) {
-        calName = (CFStringRef)CFLocaleGetValue(df->_locale, kCFLocaleCalendarIdentifierKey);
-    }
-    if (calName && CFEqual(calName, kCFCalendarIdentifierGregorian)) {
-        UCalendar *cal = (UCalendar *)udat_getCalendar(df->_df);
-        status = U_ZERO_ERROR;
-        UDate udate = ucal_getGregorianChange(cal, &status);
-        CFAbsoluteTime at = U_SUCCESS(status) ? (udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970) : -13197600000.0; // Oct 15, 1582
-        udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
-        status = U_ZERO_ERROR;
-        ucal_setGregorianChange(cal, udate, &status);
-    }
-
     RESET_PROPERTY(_IsLenient, kCFDateFormatterIsLenientKey);
     RESET_PROPERTY(_DoesRelativeDateFormatting, kCFDateFormatterDoesRelativeDateFormattingKey);
     RESET_PROPERTY(_Calendar, kCFDateFormatterCalendarKey);
@@ -384,27 +712,8 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     RESET_PROPERTY(_TwoDigitStartDate, kCFDateFormatterTwoDigitStartDateKey);
     RESET_PROPERTY(_DefaultDate, kCFDateFormatterDefaultDateKey);
     RESET_PROPERTY(_GregorianStartDate, kCFDateFormatterGregorianStartDateKey);
-    RESET_PROPERTY(_EraSymbols, kCFDateFormatterEraSymbolsKey);
-    RESET_PROPERTY(_LongEraSymbols, kCFDateFormatterLongEraSymbolsKey);
-    RESET_PROPERTY(_MonthSymbols, kCFDateFormatterMonthSymbolsKey);
-    RESET_PROPERTY(_ShortMonthSymbols, kCFDateFormatterShortMonthSymbolsKey);
-    RESET_PROPERTY(_VeryShortMonthSymbols, kCFDateFormatterVeryShortMonthSymbolsKey);
-    RESET_PROPERTY(_StandaloneMonthSymbols, kCFDateFormatterStandaloneMonthSymbolsKey);
-    RESET_PROPERTY(_ShortStandaloneMonthSymbols, kCFDateFormatterShortStandaloneMonthSymbolsKey);
-    RESET_PROPERTY(_VeryShortStandaloneMonthSymbols, kCFDateFormatterVeryShortStandaloneMonthSymbolsKey);
-    RESET_PROPERTY(_WeekdaySymbols, kCFDateFormatterWeekdaySymbolsKey);
-    RESET_PROPERTY(_ShortWeekdaySymbols, kCFDateFormatterShortWeekdaySymbolsKey);
-    RESET_PROPERTY(_VeryShortWeekdaySymbols, kCFDateFormatterVeryShortWeekdaySymbolsKey);
-    RESET_PROPERTY(_StandaloneWeekdaySymbols, kCFDateFormatterStandaloneWeekdaySymbolsKey);
-    RESET_PROPERTY(_ShortStandaloneWeekdaySymbols, kCFDateFormatterShortStandaloneWeekdaySymbolsKey);
-    RESET_PROPERTY(_VeryShortStandaloneWeekdaySymbols, kCFDateFormatterVeryShortStandaloneWeekdaySymbolsKey);
-    RESET_PROPERTY(_QuarterSymbols, kCFDateFormatterQuarterSymbolsKey);
-    RESET_PROPERTY(_ShortQuarterSymbols, kCFDateFormatterShortQuarterSymbolsKey);
-    RESET_PROPERTY(_StandaloneQuarterSymbols, kCFDateFormatterStandaloneQuarterSymbolsKey);
-    RESET_PROPERTY(_ShortStandaloneQuarterSymbols, kCFDateFormatterShortStandaloneQuarterSymbolsKey);
-    RESET_PROPERTY(_AMSymbol, kCFDateFormatterAMSymbolKey);
-    RESET_PROPERTY(_PMSymbol, kCFDateFormatterPMSymbolKey);
     RESET_PROPERTY(_AmbiguousYearStrategy, kCFDateFormatterAmbiguousYearStrategyKey);
+    RESET_PROPERTY(_UsesCharacterDirection, kCFDateFormatterUsesCharacterDirectionKey);
 }
 
 static CFTypeID __kCFDateFormatterTypeID = _kCFRuntimeNotATypeID;
@@ -476,6 +785,33 @@ CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef l
     memory->_property._AMSymbol = NULL;
     memory->_property._PMSymbol = NULL;
     memory->_property._AmbiguousYearStrategy = NULL;
+    memory->_property._UsesCharacterDirection = NULL;
+    memory->_property._CustomEraSymbols = NULL;
+    memory->_property._CustomMonthSymbols = NULL;
+    memory->_property._CustomShortMonthSymbols = NULL;
+    memory->_property._CustomWeekdaySymbols = NULL;
+    memory->_property._CustomShortWeekdaySymbols = NULL;
+    memory->_property._CustomLongEraSymbols = NULL;
+    memory->_property._CustomVeryShortMonthSymbols = NULL;
+    memory->_property._CustomVeryShortWeekdaySymbols = NULL;
+    memory->_property._CustomStandaloneMonthSymbols = NULL;
+    memory->_property._CustomShortStandaloneMonthSymbols = NULL;
+    memory->_property._CustomVeryShortStandaloneMonthSymbols = NULL;
+    memory->_property._CustomStandaloneWeekdaySymbols = NULL;
+    memory->_property._CustomShortStandaloneWeekdaySymbols = NULL;
+    memory->_property._CustomVeryShortStandaloneWeekdaySymbols = NULL;
+    memory->_property._CustomQuarterSymbols = NULL;
+    memory->_property._CustomShortQuarterSymbols = NULL;
+    memory->_property._CustomStandaloneQuarterSymbols = NULL;
+    memory->_property._CustomShortStandaloneQuarterSymbols = NULL;
+    memory->_property._CustomDateFormat = NULL;
+    memory->_property._CustomTimeFormat = NULL;
+    memory->_property._Custom24Hour = NULL;
+    memory->_property._Custom12Hour = NULL;
+    memory->_property._CustomAMSymbol = NULL;
+    memory->_property._CustomPMSymbol = NULL;
+    memory->_property._CustomFirstWeekday = NULL;
+    memory->_property._CustomMinDaysInFirstWeek = NULL;
 
     switch (dateStyle) {
     case kCFDateFormatterNoStyle:
@@ -502,6 +838,12 @@ CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef l
 
     memory->_locale = locale ? CFLocaleCreateCopy(allocator, locale) : (CFLocaleRef)CFRetain(CFLocaleGetSystem());
     memory->_property._TimeZone = CFTimeZoneCopyDefault();
+    
+    CFStringRef calident = (CFStringRef)CFLocaleGetValue(memory->_locale, kCFLocaleCalendarIdentifierKey);
+    if (calident && CFEqual(calident, kCFCalendarIdentifierGregorian)) {
+        memory->_property._TwoDigitStartDate = CFDateCreate(kCFAllocatorSystemDefault, -1609459200.0); // 1950-01-01 00:00:00 +0000
+    }
+    
     __ResetUDateFormat(memory, false);
     if (!memory->_df) {
         CFRelease(memory);
@@ -510,34 +852,19 @@ CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef l
     return (CFDateFormatterRef)memory;
 }
 
-extern CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale);
-
 static void __substituteFormatStringFromPrefsDFRelative(CFDateFormatterRef formatter) {
-    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
 
     CFIndex dateLen = -1;
     UChar dateBuffer[BUFFER_SIZE];
     if (kCFDateFormatterNoStyle != formatter->_dateStyle) {
-        CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateFormatStrings")) : NULL;
-        if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-            CFStringRef key;
-            switch (formatter->_dateStyle) {
-            case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
-            case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
-            case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
-            case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
-            default: key = CFSTR("0"); break;
-            }
-            CFStringRef pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
-            if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) {
-                dateLen = __CFMin(CFStringGetLength(pref), BUFFER_SIZE);
-                CFStringGetCharacters(pref, CFRangeMake(0, dateLen), (UniChar *)dateBuffer);
-            }
+        if (formatter->_property._CustomDateFormat != NULL) {
+            dateLen = __CFMin(CFStringGetLength(formatter->_property._CustomDateFormat), BUFFER_SIZE);
+            CFStringGetCharacters(formatter->_property._CustomDateFormat, CFRangeMake(0, dateLen), (UniChar *)dateBuffer);
         }
     }
     if (-1 == dateLen) {
         UErrorCode status = U_ZERO_ERROR;
-        int32_t ret = udat_toPatternRelativeDate(formatter->_df, dateBuffer, BUFFER_SIZE, &status);
+        int32_t ret = __cficu_udat_toPatternRelativeDate(formatter->_df, dateBuffer, BUFFER_SIZE, &status);
         if (!U_FAILURE(status)) {
             dateLen = ret;
         }
@@ -546,54 +873,28 @@ static void __substituteFormatStringFromPrefsDFRelative(CFDateFormatterRef forma
     CFIndex timeLen = -1;
     UChar timeBuffer[BUFFER_SIZE];
     if (kCFDateFormatterNoStyle != formatter->_timeStyle) {
-        CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUTimeFormatStrings")) : NULL;
-        if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-            CFStringRef key;
-            switch (formatter->_timeStyle) {
-            case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
-            case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
-            case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
-            case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
-            default: key = CFSTR("0"); break;
-            }
-            CFStringRef pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
-            if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) {
-                timeLen = __CFMin(CFStringGetLength(pref), BUFFER_SIZE);
-                CFStringGetCharacters(pref, CFRangeMake(0, timeLen), (UniChar *)timeBuffer);
-            }
+        if (formatter->_property._CustomTimeFormat != NULL) {
+            timeLen = __CFMin(CFStringGetLength(formatter->_property._CustomTimeFormat), BUFFER_SIZE);
+            CFStringGetCharacters(formatter->_property._CustomTimeFormat, CFRangeMake(0, timeLen), (UniChar *)timeBuffer);
         }
     }
     if (-1 == timeLen) {
         UErrorCode status = U_ZERO_ERROR;
-        int32_t ret = udat_toPatternRelativeTime(formatter->_df, timeBuffer, BUFFER_SIZE, &status);
+        int32_t ret = __cficu_udat_toPatternRelativeTime(formatter->_df, timeBuffer, BUFFER_SIZE, &status);
         if (!U_FAILURE(status)) {
             timeLen = ret;
         }
     }
 
     UErrorCode status = U_ZERO_ERROR;
-    udat_applyPatternRelative(formatter->_df, (0 <= dateLen) ? dateBuffer : NULL, (0 <= dateLen) ? dateLen : 0, (0 <= timeLen) ? timeBuffer : NULL, (0 <= timeLen) ? timeLen : 0, &status);
+    __cficu_udat_applyPatternRelative(formatter->_df, (0 <= dateLen) ? dateBuffer : NULL, (0 <= dateLen) ? dateLen : 0, (0 <= timeLen) ? timeBuffer : NULL, (0 <= timeLen) ? timeLen : 0, &status);
 }
 
 static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bool doTime) {
     CFIndex formatStyle = doTime ? formatter->_timeStyle : formatter->_dateStyle;
-    CFStringRef prefName = doTime ? CFSTR("AppleICUTimeFormatStrings") : CFSTR("AppleICUDateFormatStrings");
+    CFStringRef pref = doTime ? formatter->_property._CustomTimeFormat : formatter->_property._CustomDateFormat;
     if (kCFDateFormatterNoStyle != formatStyle) {
-        CFStringRef pref = NULL;
-        CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
-        CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, prefName) : NULL;
-        if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-            CFStringRef key;
-            switch (formatStyle) {
-            case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
-            case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
-            case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
-            case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
-            default: key = CFSTR("0"); break;
-            }
-            pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
-        }
-        if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) {
+        if (NULL != pref) {
             int32_t icustyle = UDAT_NONE;
             switch (formatStyle) {
             case kCFDateFormatterShortStyle: icustyle = UDAT_SHORT; break;
@@ -608,15 +909,15 @@ static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bo
                 if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
             }
             UErrorCode status = U_ZERO_ERROR;
-            UDateFormat *df = udat_open((UDateFormatStyle)(doTime ? icustyle : UDAT_NONE), (UDateFormatStyle)(doTime ? UDAT_NONE : icustyle), cstr, NULL, 0, NULL, 0, &status);
+            UDateFormat *df = __cficu_udat_open((UDateFormatStyle)(doTime ? icustyle : UDAT_NONE), (UDateFormatStyle)(doTime ? UDAT_NONE : icustyle), cstr, NULL, 0, NULL, 0, &status);
             if (NULL != df) {
                 UChar ubuffer[BUFFER_SIZE];
                 status = U_ZERO_ERROR;
-                int32_t date_len = udat_toPattern(df, false, ubuffer, BUFFER_SIZE, &status);
+                int32_t date_len = __cficu_udat_toPattern(df, false, ubuffer, BUFFER_SIZE, &status);
                 if (U_SUCCESS(status) && date_len <= BUFFER_SIZE) {
                     CFStringRef dateString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)ubuffer, date_len);
                     status = U_ZERO_ERROR;
-                    int32_t formatter_len = udat_toPattern(formatter->_df, false, ubuffer, BUFFER_SIZE, &status);
+                    int32_t formatter_len = __cficu_udat_toPattern(formatter->_df, false, ubuffer, BUFFER_SIZE, &status);
                     if (U_SUCCESS(status) && formatter_len <= BUFFER_SIZE) {
                         CFMutableStringRef formatString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
                         CFStringAppendCharacters(formatString, (UniChar *)ubuffer, formatter_len);
@@ -632,45 +933,102 @@ static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bo
                                 new_ustr = new_buffer;
                                 }
                             status = U_ZERO_ERROR;
-//                            udat_applyPattern(formatter->_df, false, new_ustr, new_len, &status);
-                            udat_applyPattern(formatter->_df, false, new_ustr, new_len);
+//                            __cficu_udat_applyPattern(formatter->_df, false, new_ustr, new_len, &status);
+                            __cficu_udat_applyPattern(formatter->_df, false, new_ustr, new_len);
                         }
                         CFRelease(formatString);
                     }
                     CFRelease(dateString);
                 }
-                udat_close(df);
+                __cficu_udat_close(df);
             }
         }
     }
 }
 
-static void __CFDateFormatterApplySymbolPrefs(const void *key, const void *value, void *context) {
+static void __CFDateFormatterStoreSymbolPrefs(const void *key, const void *value, void *context) {
     if (CFGetTypeID(key) == CFStringGetTypeID() && CFGetTypeID(value) == CFArrayGetTypeID()) {
         CFDateFormatterRef formatter = (CFDateFormatterRef)context;
         UDateFormatSymbolType sym = (UDateFormatSymbolType)CFStringGetIntValue((CFStringRef)key);
         CFArrayRef array = (CFArrayRef)value;
         CFIndex idx, cnt = CFArrayGetCount(array);
-        for (idx = 0; idx < cnt; idx++) {
-            CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx);
-            if (CFGetTypeID(item) != CFStringGetTypeID()) continue;
-            CFIndex item_cnt = CFStringGetLength(item);
-            STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt));
-            UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item);
-            if (NULL == item_ustr) {
-                item_cnt = __CFMin(BUFFER_SIZE, item_cnt);
-                CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
-                item_ustr = item_buffer;
-            }
-            UErrorCode status = U_ZERO_ERROR;
-            udat_setSymbols(formatter->_df, sym, idx, item_ustr, item_cnt, &status);
+        switch (sym) {
+            case UDAT_ERAS:
+                formatter->_property._CustomEraSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_MONTHS:
+                formatter->_property._CustomMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_SHORT_MONTHS:
+                formatter->_property._CustomShortMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_WEEKDAYS:
+                formatter->_property._CustomWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_SHORT_WEEKDAYS:
+                formatter->_property._CustomShortWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_AM_PMS:
+                {
+                    for (idx = 0; idx < cnt; idx++) {
+                        CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx);
+                        if (CFGetTypeID(item) != CFStringGetTypeID()) continue;
+                        if (idx == 0) {
+                            formatter->_property._CustomAMSymbol = (CFStringRef)CFRetain(item);
+                        } else if (idx == 1) {
+                            formatter->_property._CustomPMSymbol = (CFStringRef)CFRetain(item);
+                        }
+                    }
+                }
+                break;
+            case UDAT_ERA_NAMES:
+                formatter->_property._CustomLongEraSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_NARROW_MONTHS:
+                formatter->_property._CustomVeryShortMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_NARROW_WEEKDAYS:
+                formatter->_property._CustomVeryShortWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_MONTHS:
+                formatter->_property._CustomStandaloneMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_SHORT_MONTHS:
+                formatter->_property._CustomShortStandaloneMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_NARROW_MONTHS:
+                formatter->_property._CustomVeryShortStandaloneMonthSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_WEEKDAYS:
+                formatter->_property._CustomStandaloneWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_SHORT_WEEKDAYS:
+                formatter->_property._CustomShortStandaloneWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_NARROW_WEEKDAYS:
+                formatter->_property._CustomVeryShortStandaloneWeekdaySymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_QUARTERS:
+                formatter->_property._CustomQuarterSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_SHORT_QUARTERS:
+                formatter->_property._CustomShortQuarterSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_QUARTERS:
+                formatter->_property._CustomStandaloneQuarterSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            case UDAT_STANDALONE_SHORT_QUARTERS:
+                formatter->_property._CustomShortStandaloneQuarterSymbols = (CFArrayRef)CFRetain(array);
+                break;
+            default:
+                break;
         }
     }
 }
 
 static CFStringRef __CFDateFormatterCreateForcedTemplate(CFLocaleRef locale, CFStringRef inString) {
     if (!inString) return NULL;
-
+    
     Boolean doForce24 = false, doForce12 = false;
     CFDictionaryRef prefs = __CFLocaleGetPrefs(locale);
     CFPropertyListRef pref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUForce24HourTime")) : NULL;
@@ -683,7 +1041,7 @@ static CFStringRef __CFDateFormatterCreateForcedTemplate(CFLocaleRef locale, CFS
     }
     if (doForce24) doForce12 = false; // if both are set, Force24 wins, period
     if (!doForce24 && !doForce12) return (CFStringRef)CFRetain(inString);
-
+    
     CFMutableStringRef outString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
     CFIndex cnt = CFStringGetLength(inString);
     CFIndex lastSecond = -1, lastMinute = -1, firstHour = -1;
@@ -692,39 +1050,115 @@ static CFStringRef __CFDateFormatterCreateForcedTemplate(CFLocaleRef locale, CFS
         Boolean emit = true;
         UniChar ch = CFStringGetCharacterAtIndex(inString, idx);
         switch (ch) {
-        case '\'': isInQuote = !isInQuote; break;
-        case 'j': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); if (doForce24) ch = 'H'; else ch = 'h';} break;
-        case 'h': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'H';} break; // switch 12-hour to 24-hour
-        case 'K': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'k';} break; // switch 12-hour to 24-hour
-        case 'H': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'h';} break; // switch 24-hour to 12-hour
-        case 'k': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'K';} break; // switch 24-hour to 12-hour
-        case 'm': if (!isInQuote) lastMinute = CFStringGetLength(outString); break;
-        case 's': if (!isInQuote) lastSecond = CFStringGetLength(outString); break;
-        case 'a': if (!isInQuote) {hasA = true; if (doForce24) emit = false;} break;
-            break;
+            case '\'': isInQuote = !isInQuote; break;
+            case 'j': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); if (doForce24) ch = 'H'; else ch = 'h';} break;
+            case 'h': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'H';} break; // switch 12-hour to 24-hour
+            case 'K': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'k';} break; // switch 12-hour to 24-hour
+            case 'H': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'h';} break; // switch 24-hour to 12-hour
+            case 'k': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'K';} break; // switch 24-hour to 12-hour
+            case 'm': if (!isInQuote) lastMinute = CFStringGetLength(outString); break;
+            case 's': if (!isInQuote) lastSecond = CFStringGetLength(outString); break;
+            case 'a': if (!isInQuote) {hasA = true; if (doForce24) emit = false;} break;
+                break;
         }
         if (emit) CFStringAppendCharacters(outString, &ch, 1);
     }
-
+    
     return outString;
 }
 
+/*
+ Mapping H<->h and K<->k is not correct in all locales; Japanese 12 hour, for example, uses H<->k
+ This gets an approximately correct replacement character for the locale and forcing direction in question
+ <rdar://problem/14062096> [iCal] Incorrect time format is used for current time indicator line
+ */
+static UChar __CFDateFormatterForcedHourCharacterForLocale(CFLocaleRef locale, Boolean doForce24, Boolean doForce12, Boolean *succeeded) {
+    if (doForce24) doForce12 = false; // if both are set, Force24 wins, period
+    if (!locale || (!doForce24 && !doForce12)) {
+        *succeeded = false;
+        return '\0';
+    }
+    CFStringRef localeName = locale ? CFLocaleGetIdentifier(locale) : CFSTR("");
+    char buffer[BUFFER_SIZE] = {0};
+    const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
+    if (NULL == cstr) {
+        if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
+    }
+    
+    __block UChar hourPatternChar = '\0';
+    
+    useTemplatePatternGenerator(cstr, ^(UDateTimePatternGenerator *ptg) {
+        UChar hourPattern[256] = {0};
+        int32_t patternLen = -1;
+        if (ptg) {
+            UErrorCode errorCode = U_ZERO_ERROR;
+            patternLen = __cficu_udatpg_getBestPattern(ptg, (const UChar *)(doForce12 ? "h" : "H"), 1, hourPattern, sizeof(hourPattern) / sizeof(UChar), &errorCode);
+            if (errorCode != U_ZERO_ERROR) {
+                memset(hourPattern, 0, sizeof(hourPattern)); //make sure there's nothing there if we failed
+                patternLen = -1;
+            }
+        }
+        
+        /*
+         Blindly replacing HHHH with four copies of the entire udatpg_getBestPattern result is not going to work. Search for the first [hHkK] in the result and use just that
+         */
+        if (patternLen > 0) {
+            for (CFIndex idx = 0; hourPattern[idx] != '\0' && idx < patternLen && idx < sizeof(hourPattern) / sizeof(UChar); idx++) {
+                if (hourPattern[idx] == 'k' || hourPattern[idx] == 'K' || hourPattern[idx] == 'h' || hourPattern[idx] == 'H') {
+                    hourPatternChar = hourPattern[idx];
+                    break;
+                }
+            }
+        }
+    });
+
+    *succeeded = hourPatternChar != '\0';
+    return hourPatternChar;
+}
+    
+#define FORCE_CHAR(replacement, oldType, newType) do { \
+    if (!isInQuote) {\
+        if (-1 == firstHour) {\
+            firstHour = CFStringGetLength(outString);\
+        }\
+        had##oldType##Hour = true;\
+        if (doForce##newType) {\
+            ch = useSpecialHourChar ? hourPatternChar : replacement;\
+        }\
+    }\
+}while(0)
+#define FORCE_CHAR_12(replacement) FORCE_CHAR(replacement, 12, 24)
+#define FORCE_CHAR_24(replacement) FORCE_CHAR(replacement, 24, 12)
+
 static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef formatter, CFStringRef inString) {
     if (!inString) return NULL;
 
     Boolean doForce24 = false, doForce12 = false;
-    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
-    CFPropertyListRef pref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUForce24HourTime")) : NULL;
-    if (NULL != pref && CFGetTypeID(pref) == CFBooleanGetTypeID()) {
-        doForce24 = CFBooleanGetValue((CFBooleanRef)pref);
+    if (formatter->_property._Custom24Hour != NULL) {
+        doForce24 = CFBooleanGetValue((CFBooleanRef)formatter->_property._Custom24Hour);
     }
-    pref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUForce12HourTime")) : NULL;
-    if (NULL != pref && CFGetTypeID(pref) == CFBooleanGetTypeID()) {
-        doForce12 = CFBooleanGetValue((CFBooleanRef)pref);
+    if (formatter->_property._Custom12Hour != NULL) {
+        doForce12 = CFBooleanGetValue((CFBooleanRef)formatter->_property._Custom12Hour);
     }
     if (doForce24) doForce12 = false; // if both are set, Force24 wins, period
+    
+    static CFCharacterSetRef hourCharacters;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        hourCharacters = CFCharacterSetCreateWithCharactersInString(kCFAllocatorSystemDefault, CFSTR("hHkK"));
+    });
+    
+    CFRange hourRange = CFRangeMake(kCFNotFound, 0);
+    if (!CFStringFindCharacterFromSet(inString, hourCharacters, CFRangeMake(0, CFStringGetLength(inString)), 0, &hourRange) || hourRange.location == kCFNotFound) {
+        doForce12 = false;
+        doForce24 = false;
+    }
+    
     if (!doForce24 && !doForce12) return (CFStringRef)CFRetain(inString);
-
+    
+    Boolean useSpecialHourChar = false;
+    UChar hourPatternChar = __CFDateFormatterForcedHourCharacterForLocale(formatter->_locale, doForce24, doForce12, &useSpecialHourChar);
+    
     CFMutableStringRef outString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
     CFIndex cnt = CFStringGetLength(inString);
     CFIndex lastSecond = -1, lastMinute = -1, firstHour = -1;
@@ -734,10 +1168,10 @@ static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef format
         UniChar ch = CFStringGetCharacterAtIndex(inString, idx);
         switch (ch) {
         case '\'': isInQuote = !isInQuote; break;
-        case 'h': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'H';} break; // switch 12-hour to 24-hour
-        case 'K': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had12Hour = true; if (doForce24) ch = 'k';} break; // switch 12-hour to 24-hour
-        case 'H': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'h';} break; // switch 24-hour to 12-hour
-        case 'k': if (!isInQuote) {if (-1 == firstHour) firstHour = CFStringGetLength(outString); had24Hour = true; if (doForce12) ch = 'K';} break; // switch 24-hour to 12-hour
+        case 'h': FORCE_CHAR_12('H'); break; // switch 12-hour to 24-hour
+        case 'k': FORCE_CHAR_24('K'); break; // switch 24-hour to 12-hour
+        case 'H': FORCE_CHAR_24('h'); break; // switch 24-hour to 12-hour
+        case 'K': FORCE_CHAR_12('k'); break; // switch 12-hour to 24-hour
         case 'm': if (!isInQuote) lastMinute = CFStringGetLength(outString); break;
         case 's': if (!isInQuote) lastSecond = CFStringGetLength(outString); break;
         case 'a': if (!isInQuote) hasA = true;
@@ -791,45 +1225,6 @@ static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef format
     return outString;
 }
 
-static void __CFDateFormatterCustomize(CFDateFormatterRef formatter) {
-    Boolean wantRelative = (NULL != formatter->_property._DoesRelativeDateFormatting && formatter->_property._DoesRelativeDateFormatting == kCFBooleanTrue);
-    Boolean hasFormat = (NULL != formatter->_property._HasCustomFormat && formatter->_property._HasCustomFormat == kCFBooleanTrue);
-    if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != formatter->_dateStyle) {
-        __substituteFormatStringFromPrefsDFRelative(formatter);
-    } else {
-        __substituteFormatStringFromPrefsDF(formatter, false);
-        __substituteFormatStringFromPrefsDF(formatter, true);
-    }
-    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
-    CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateTimeSymbols")) : NULL;
-    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-        CFDictionaryApplyFunction((CFDictionaryRef)metapref, __CFDateFormatterApplySymbolPrefs, formatter);
-    }
-    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleFirstWeekday")) : NULL;
-    CFStringRef calID = (CFStringRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendarIdentifierKey);
-    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-        metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calID);
-    }
-    if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) {
-        CFIndex wkdy;
-        if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &wkdy)) {
-            UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-            if (cal) ucal_setAttribute(cal, UCAL_FIRST_DAY_OF_WEEK, wkdy);
-        }
-    }
-    metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleMinDaysInFirstWeek")) : NULL;
-    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
-        metapref = (CFNumberRef)CFDictionaryGetValue((CFDictionaryRef)metapref, calID);
-    }
-    if (NULL != metapref && CFGetTypeID(metapref) == CFNumberGetTypeID()) {
-        CFIndex mwd;
-        if (CFNumberGetValue((CFNumberRef)metapref, kCFNumberCFIndexType, &mwd)) {
-            UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-            if (cal) ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd);
-        }
-    }
-}
-
 CFLocaleRef CFDateFormatterGetLocale(CFDateFormatterRef formatter) {
     __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
     return formatter->_locale;
@@ -871,8 +1266,8 @@ void CFDateFormatterSetFormat(CFDateFormatterRef formatter, CFStringRef formatSt
             ustr = ubuffer;
         }
         UErrorCode status = U_ZERO_ERROR;
-//        udat_applyPattern(formatter->_df, false, ustr, cnt, &status);
-        udat_applyPattern(formatter->_df, false, ustr, cnt);
+//        __cficu_udat_applyPattern(formatter->_df, false, ustr, cnt, &status);
+        __cficu_udat_applyPattern(formatter->_df, false, ustr, cnt);
         if (U_SUCCESS(status)) {
             if (formatter->_format) CFRelease(formatter->_format);
             formatter->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(formatter), formatString);
@@ -894,37 +1289,46 @@ CFStringRef CFDateFormatterCreateStringWithAbsoluteTime(CFAllocatorRef allocator
     if (allocator == NULL) allocator = __CFGetDefaultAllocator();
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
-    UChar *ustr = NULL, ubuffer[BUFFER_SIZE];
+    UChar *ustr = NULL, ubuffer[BUFFER_SIZE + 1];
     UErrorCode status = U_ZERO_ERROR;
     CFIndex used, cnt = BUFFER_SIZE;
     UDate ud = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0 + 0.5;
-    used = udat_format(formatter->_df, ud, ubuffer, cnt, NULL, &status);
+    used = __cficu_udat_format(formatter->_df, ud, ubuffer + 1, cnt, NULL, &status);
     if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {
-        cnt = used + 1;
+        cnt = used + 1 + 1; // leave room for RTL marker if needed
         ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0);
         status = U_ZERO_ERROR;
-        used = udat_format(formatter->_df, ud, ustr, cnt, NULL, &status);
+        used = __cficu_udat_format(formatter->_df, ud, ustr + 1, cnt, NULL, &status);
     }
     CFStringRef string = NULL;
     if (U_SUCCESS(status)) {
-        string = CFStringCreateWithCharacters(allocator, (const UniChar *)(ustr ? ustr : ubuffer), used);
+        UniChar *bufferToUse = ustr ? (UniChar *)ustr : (UniChar *)ubuffer;
+        if (formatter->_property._UsesCharacterDirection == kCFBooleanTrue && CFLocaleGetLanguageCharacterDirection(CFLocaleGetIdentifier(formatter->_locale)) == kCFLocaleLanguageDirectionRightToLeft) {
+            // Insert Unicode RTL marker
+            bufferToUse[0] = 0x200F;
+            used++;
+        } else {
+            // Move past direction marker
+            bufferToUse++;
+        }
+        string = CFStringCreateWithCharacters(allocator, bufferToUse, used);
     }
     if (ustr) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ustr);
     return string;
 }
 
 static UDate __CFDateFormatterCorrectTimeWithTarget(UCalendar *calendar, UDate at, int32_t target, Boolean isEra, UErrorCode *status) {
-    ucal_setMillis(calendar, at, status);
+    __cficu_ucal_setMillis(calendar, at, status);
     UCalendarDateFields field = isEra ? UCAL_ERA : UCAL_YEAR;
-    ucal_set(calendar, field, target);
-    return ucal_getMillis(calendar, status);
+    __cficu_ucal_set(calendar, field, target);
+    return __cficu_ucal_getMillis(calendar, status);
 }
 
 static UDate __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(UCalendar *calendar, UDate at, CFIndex period, CFIndex pastYears, CFIndex futureYears, Boolean isEra, UErrorCode *status) {
-    ucal_setMillis(calendar, ucal_getNow(), status);
-    int32_t currYear = ucal_get(calendar, UCAL_YEAR, status);
+    __cficu_ucal_setMillis(calendar, __cficu_ucal_getNow(), status);
+    int32_t currYear = __cficu_ucal_get(calendar, UCAL_YEAR, status);
     UCalendarDateFields field = isEra ? UCAL_ERA : UCAL_YEAR;
-    int32_t currEraOrCentury = ucal_get(calendar, field, status);
+    int32_t currEraOrCentury = __cficu_ucal_get(calendar, field, status);
     if (!isEra) {
         currYear %= 100;
         currEraOrCentury = currEraOrCentury / 100 * 100; // get century
@@ -968,8 +1372,8 @@ static UDate __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(UCalendar *ca
     }
     currRange.length = period - pastRange.length - futureRange.length;
 
-    ucal_setMillis(calendar, at, status);
-    int32_t atYear = ucal_get(calendar, UCAL_YEAR, status);
+    __cficu_ucal_setMillis(calendar, at, status);
+    int32_t atYear = __cficu_ucal_get(calendar, UCAL_YEAR, status);
     if (!isEra) {
         atYear %= 100;
         currEraOrCentury += atYear;
@@ -985,15 +1389,17 @@ static UDate __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(UCalendar *ca
     return __CFDateFormatterCorrectTimeWithTarget(calendar, at, currEraOrCentury+offset, isEra, status);
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
 static int32_t __CFDateFormatterGetMaxYearGivenJapaneseEra(UCalendar *calendar, int32_t era, UErrorCode *status) {
     int32_t years = 0;
-    ucal_clear(calendar);
-    ucal_set(calendar, UCAL_ERA, era+1);
-    UDate target = ucal_getMillis(calendar, status);
-    ucal_set(calendar, UCAL_ERA, era);
-    years = ucal_getFieldDifference(calendar, target, UCAL_YEAR, status);
+    __cficu_ucal_clear(calendar);
+    __cficu_ucal_set(calendar, UCAL_ERA, era+1);
+    UDate target = __cficu_ucal_getMillis(calendar, status);
+    __cficu_ucal_set(calendar, UCAL_ERA, era);
+    years = __cficu_ucal_getFieldDifference(calendar, target, UCAL_YEAR, status);
     return years+1;
 }
+#endif
 
 static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter, CFStringRef calendar_id, UDateFormat *df, UCalendar *cal, UDate *at, const UChar *ustr, CFIndex length, UErrorCode *status) {
     Boolean success = true;
@@ -1004,14 +1410,14 @@ static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter
     if (calendar_id == kCFCalendarIdentifierChinese) {
         // we default to era 1 if era is missing, however, we cannot just test if the era is 1 becuase we may get era 2 or larger if the year in the string is greater than 60
         // now I just assume that the year will not be greater than 600 in the string
-        if (ucal_get(cal, UCAL_ERA, status) < 10) {
+        if (__cficu_ucal_get(cal, UCAL_ERA, status) < 10) {
             switch (ambigStrat) {
                 case kCFDateFormatterAmbiguousYearFailToParse:
                     success = false;
                     break;
                 case kCFDateFormatterAmbiguousYearAssumeToCurrent: {
-                    ucal_setMillis(cal, ucal_getNow(), status);
-                    int32_t currEra = ucal_get(cal, UCAL_ERA, status);
+                    __cficu_ucal_setMillis(cal, __cficu_ucal_getNow(), status);
+                    int32_t currEra = __cficu_ucal_get(cal, UCAL_ERA, status);
                     *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
                     break;
                     }
@@ -1036,16 +1442,17 @@ static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter
             }
         }
     } else if (calendar_id == kCFCalendarIdentifierJapanese) { // ??? need more work
-        ucal_clear(cal);
-        ucal_set(cal, UCAL_ERA, 1);
-        udat_parseCalendar(df, cal, ustr, length, NULL, status);
-        UDate test = ucal_getMillis(cal, status);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
+        __cficu_ucal_clear(cal);
+        __cficu_ucal_set(cal, UCAL_ERA, 1);
+        __cficu_udat_parseCalendar(df, cal, ustr, length, NULL, status);
+        UDate test = __cficu_ucal_getMillis(cal, status);
         if (test != *at) { // missing era
-            ucal_setMillis(cal, *at, status);
-            int32_t givenYear = ucal_get(cal, UCAL_YEAR, status);
-            ucal_setMillis(cal, ucal_getNow(), status);
-            int32_t currYear = ucal_get(cal, UCAL_YEAR, status);
-            int32_t currEra = ucal_get(cal, UCAL_ERA, status);
+            __cficu_ucal_setMillis(cal, *at, status);
+            int32_t givenYear = __cficu_ucal_get(cal, UCAL_YEAR, status);
+            __cficu_ucal_setMillis(cal, __cficu_ucal_getNow(), status);
+            int32_t currYear = __cficu_ucal_get(cal, UCAL_YEAR, status);
+            int32_t currEra = __cficu_ucal_get(cal, UCAL_ERA, status);
             switch (ambigStrat) {
                 case kCFDateFormatterAmbiguousYearFailToParse:
                     success = false;
@@ -1053,20 +1460,6 @@ static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter
                 case kCFDateFormatterAmbiguousYearAssumeToCurrent:
                     *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
                     break;
-                case kCFDateFormatterAmbiguousYearAssumeToCenteredAroundCurrentDate:
-                    // we allow the ball up to 30 years
-                    // if the given year is larger than the current year + 30 years, we check the previous era
-                    if (givenYear > currYear + 30) {
-                        success = false; // if the previous era cannot have the given year, fail the parse
-                        int32_t years = __CFDateFormatterGetMaxYearGivenJapaneseEra(cal, currEra-1, status);
-                        if (givenYear <= years) {
-                            success = true;
-                            *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra-1, true, status);
-                        }
-                    } else { // current era
-                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
-                    }
-                    break;
                 case kCFDateFormatterAmbiguousYearAssumeToFuture:
                     if (givenYear < currYear) { // we only consider current or the future
                         success = false;
@@ -1122,43 +1515,76 @@ static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter
                     break; // do nothing
             }
         }
+#else
+        success = false;
+#endif
     } else { // calenders other than chinese and japanese
-        int32_t parsedYear = ucal_get(cal, UCAL_YEAR, status);
-        ucal_setMillis(cal, ucal_getNow(), status);
-        int32_t currYear = ucal_get(cal, UCAL_YEAR, status);
-        if (currYear + 1500 < parsedYear) { // most likely that the parsed string had a 2-digits year
-            switch (ambigStrat) {
-            case kCFDateFormatterAmbiguousYearFailToParse:
-                success = false;
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToCurrent:
-                *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, (currYear / 100 * 100) + parsedYear % 100, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToCenteredAroundCurrentDate:
-                *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 50, 49, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToFuture:
-                *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 0, 99, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToPast:
-                *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 99, 0, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToLikelyFuture:
-                *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 9, 90, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToLikelyPast:
-                *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 90, 9, false, status);
-                break;
-            case kCFDateFormatterAmbiguousYearAssumeToNone:
-            default:
-                if (calendar_id == kCFCalendarIdentifierGregorian) { // historical default behavior of 1950 - 2049
-                    int32_t twoDigits = parsedYear % 100;
-                    *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, ((twoDigits < 50) ? 2000 : 1900) + twoDigits, false, status);
+        int32_t parsedYear = __cficu_ucal_get(cal, UCAL_YEAR, status);
+        if (parsedYear >= 12000 && parsedYear <= 12099) { // most likely that the parsed string had a 2-digits year
+            if (formatter->_property._TwoDigitStartDate != NULL) {
+                UCalendar *tempCal = __cficu_ucal_clone(cal, status);
+                __cficu_ucal_clear(tempCal);
+                CFAbsoluteTime twoDigitAt = CFDateGetAbsoluteTime(formatter->_property._TwoDigitStartDate);
+                UDate targetUdate = (twoDigitAt + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
+                __cficu_ucal_setMillis(tempCal, targetUdate, status);
+                int targetYear = __cficu_ucal_get(tempCal, UCAL_YEAR, status);
+                parsedYear -= 12000;
+                int targetYearM100 = targetYear % 100;
+                if (targetYearM100 < parsedYear) {
+                    parsedYear = ((targetYear / 100) * 100) + parsedYear;
+                } else if (parsedYear < targetYearM100) {
+                    parsedYear = ((targetYear / 100) * 100) + 100 + parsedYear;
+                } else {
+                    __cficu_ucal_set(cal, UCAL_YEAR, targetYear);
+                    UDate parseUdate = __cficu_ucal_getMillis(cal, status);
+                    if (parseUdate >= targetUdate) {
+                        parsedYear = targetYear;
+                    } else {
+                        parsedYear = targetYear + 100;
+                    }
+                }
+                __cficu_ucal_close(tempCal);
+                __cficu_ucal_set(cal, UCAL_YEAR, parsedYear);
+                *at = __cficu_ucal_getMillis(cal, status);
+            } else {
+                switch (ambigStrat) {
+                    case kCFDateFormatterAmbiguousYearFailToParse:
+                        success = false;
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToCurrent:
+                    {
+                        // we can modify cal here because cal is just a temp cal from the caller
+                        __cficu_ucal_setMillis(cal, __cficu_ucal_getNow(), status);
+                        int32_t currYear = __cficu_ucal_get(cal, UCAL_YEAR, status);
+                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, (currYear / 100 * 100) + parsedYear % 100, false, status);
+                    }
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToCenteredAroundCurrentDate:
+                        *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 50, 49, false, status);
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToFuture:
+                        *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 0, 99, false, status);
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToPast:
+                        *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 99, 0, false, status);
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToLikelyFuture:
+                        *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 9, 90, false, status);
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToLikelyPast:
+                        *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 100, 90, 9, false, status);
+                        break;
+                    case kCFDateFormatterAmbiguousYearAssumeToNone:
+                    default:
+                        if (calendar_id == kCFCalendarIdentifierGregorian) { // historical default behavior of 1950 - 2049
+                            int32_t twoDigits = parsedYear % 100;
+                            *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, ((twoDigits < 50) ? 2000 : 1900) + twoDigits, false, status);
+                        }
+                        break; // do nothing
                 }
-                break; // do nothing
             }
-        }
 
+        }
     }
     return success;
 }
@@ -1196,53 +1622,43 @@ Boolean CFDateFormatterGetAbsoluteTimeFromString(CFDateFormatterRef formatter, C
     UDate udate;
     int32_t dpos = 0;
     UErrorCode status = U_ZERO_ERROR;
-    UDateFormat *df2 = udat_clone(formatter->_df, &status);
-    UCalendar *cal2 = (UCalendar *)udat_getCalendar(df2);
+    UDateFormat *df2 = __cficu_udat_clone(formatter->_df, &status);
+    const UCalendar *ucal2 = __cficu_udat_getCalendar(df2);
+    UCalendar *cal2 = __cficu_ucal_clone(ucal2, &status);
     CFStringRef calendar_id = (CFStringRef) CFDateFormatterCopyProperty(formatter, kCFDateFormatterCalendarIdentifierKey);
-    // we can do this direct comparison because locale in the formatter normalizes the identifier
-    if (formatter->_property._TwoDigitStartDate) {
-        // if set, don't use hint, leave it all to ICU, as historically
-    } else if (calendar_id != kCFCalendarIdentifierChinese && calendar_id != kCFCalendarIdentifierJapanese) {
-        ucal_setMillis(cal2, ucal_getNow(), &status);
-        int32_t newYear = ((ucal_get(cal2, UCAL_YEAR, &status) / 100) + 16) * 100; // move ahead 1501-1600 years, to the beginning of a century
-        ucal_set(cal2, UCAL_YEAR, newYear);
-        ucal_set(cal2, UCAL_MONTH, ucal_getLimit(cal2, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status));
-        ucal_set(cal2, UCAL_IS_LEAP_MONTH, 0);
-        ucal_set(cal2, UCAL_DAY_OF_MONTH, ucal_getLimit(cal2, UCAL_DAY_OF_MONTH, UCAL_ACTUAL_MINIMUM, &status));
-        ucal_set(cal2, UCAL_HOUR_OF_DAY, ucal_getLimit(cal2, UCAL_HOUR_OF_DAY, UCAL_ACTUAL_MINIMUM, &status));
-        ucal_set(cal2, UCAL_MINUTE, ucal_getLimit(cal2, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status));
-        ucal_set(cal2, UCAL_SECOND, ucal_getLimit(cal2, UCAL_SECOND, UCAL_ACTUAL_MINIMUM, &status));
-        ucal_set(cal2, UCAL_MILLISECOND, 0);
-        UDate future = ucal_getMillis(cal2, &status);
-        ucal_clear(cal2);
-        udat_set2DigitYearStart(df2, future, &status);
+    if (calendar_id != kCFCalendarIdentifierChinese && calendar_id != kCFCalendarIdentifierJapanese) {
+        __cficu_ucal_clear(cal2);
+        // set both year, and 2DigitYearStart to year 12000
+        __cficu_ucal_set(cal2, UCAL_YEAR, 12000);
+        __cficu_udat_set2DigitYearStart(df2, 316516204800.0 * 1000.0, &status);
     } else if (calendar_id == kCFCalendarIdentifierChinese) {
-        ucal_clear(cal2);
-        ucal_set(cal2, UCAL_ERA, 1); // default to era 1 if no era info in the string for chinese
+        __cficu_ucal_clear(cal2);
+        __cficu_ucal_set(cal2, UCAL_ERA, 1); // default to era 1 if no era info in the string for chinese
     } else if (calendar_id == kCFCalendarIdentifierJapanese) { // default to the current era
-        ucal_setMillis(cal2, ucal_getNow(), &status);
-        int32_t currEra = ucal_get(cal2, UCAL_ERA, &status);
-        ucal_clear(cal2);
-        ucal_set(cal2, UCAL_ERA, currEra);
+        __cficu_ucal_setMillis(cal2, __cficu_ucal_getNow(), &status);
+        int32_t currEra = __cficu_ucal_get(cal2, UCAL_ERA, &status);
+        __cficu_ucal_clear(cal2);
+        __cficu_ucal_set(cal2, UCAL_ERA, currEra);
     }
     if (formatter->_property._DefaultDate) {
         CFAbsoluteTime at = CFDateGetAbsoluteTime(formatter->_property._DefaultDate);
         udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
-        ucal_setMillis(cal2, udate, &status);
+        __cficu_ucal_setMillis(cal2, udate, &status);
     }
-    udat_parseCalendar(df2, cal2, ustr, range.length, &dpos, &status);
-    udate = ucal_getMillis(cal2, &status);
+    __cficu_udat_parseCalendar(df2, cal2, ustr, range.length, &dpos, &status);
+    udate = __cficu_ucal_getMillis(cal2, &status);
     if (rangep) rangep->length = dpos;
     Boolean success = false;
     // first status check is for parsing and the second status check is for the work done inside __CFDateFormatterHandleAmbiguousYear()
-    if (!U_FAILURE(status) && (formatter->_property._TwoDigitStartDate || __CFDateFormatterHandleAmbiguousYear(formatter, calendar_id, df2, cal2, &udate, ustr, range.length, &status)) && !U_FAILURE(status)) {
+    if (!U_FAILURE(status) && (__CFDateFormatterHandleAmbiguousYear(formatter, calendar_id, df2, cal2, &udate, ustr, range.length, &status)) && !U_FAILURE(status)) {
         if (atp) {
             *atp = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
         }
         success = true;
     }
     CFRelease(calendar_id);
-    udat_close(df2);
+    __cficu_udat_close(df2);
+    __cficu_ucal_close(cal2);
     return success;
 }
 
@@ -1263,13 +1679,13 @@ static void __CFDateFormatterSetSymbolsArray(UDateFormat *icudf, int32_t icucode
            item_ustr = item_buffer;
        }
        status = U_ZERO_ERROR;
-       udat_setSymbols(icudf, (UDateFormatSymbolType)icucode, idx + index_base, item_ustr, item_cnt, &status);
+       __cficu_udat_setSymbols(icudf, (UDateFormatSymbolType)icucode, idx + index_base, item_ustr, item_cnt, &status);
     }
 }
 
 static CFArrayRef __CFDateFormatterGetSymbolsArray(UDateFormat *icudf, int32_t icucode, int index_base) {
     UErrorCode status = U_ZERO_ERROR;
-    CFIndex idx, cnt = udat_countSymbols(icudf, (UDateFormatSymbolType)icucode);
+    CFIndex idx, cnt = __cficu_udat_countSymbols(icudf, (UDateFormatSymbolType)icucode);
     if (cnt <= index_base) return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
     cnt = cnt - index_base;
     STACK_BUFFER_DECL(CFStringRef, strings, cnt);
@@ -1277,7 +1693,7 @@ static CFArrayRef __CFDateFormatterGetSymbolsArray(UDateFormat *icudf, int32_t i
         UChar ubuffer[BUFFER_SIZE];
        CFStringRef str = NULL;
        status = U_ZERO_ERROR;
-       CFIndex ucnt = udat_getSymbols(icudf, (UDateFormatSymbolType)icucode, idx + index_base, ubuffer, BUFFER_SIZE, &status);
+       CFIndex ucnt = __cficu_udat_getSymbols(icudf, (UDateFormatSymbolType)icucode, idx + index_base, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            str = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, ucnt);
        }
@@ -1305,7 +1721,6 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
     __CFGenericValidateType(key, CFStringGetTypeID());
     CFTypeRef oldProperty = NULL;
     UErrorCode status = U_ZERO_ERROR;
-    UChar ubuffer[BUFFER_SIZE];
 
     if (kCFDateFormatterIsLenientKey == key) {
        if (!directToICU) {
@@ -1313,12 +1728,10 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
             formatter->_property. _IsLenient = NULL;
        }
         __CFGenericValidateType(value, CFBooleanGetTypeID());
-        udat_setLenient(formatter->_df, (kCFBooleanTrue == value));
-        UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-        if (cal) ucal_setAttribute(cal, UCAL_LENIENT, (kCFBooleanTrue == value));
-       if (!directToICU) {
-            formatter->_property. _IsLenient = (CFBooleanRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterIsLenientKey);
-       }
+        if (!directToICU) {
+            formatter->_property. _IsLenient = value ? (CFBooleanRef)CFRetain(value) : NULL;
+            __ResetUDateFormat(formatter, false);
+        }
     } else if (kCFDateFormatterDoesRelativeDateFormattingKey == key) {
        if (!directToICU) {
            oldProperty = formatter->_property. _DoesRelativeDateFormatting;
@@ -1344,17 +1757,14 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
         CFRelease(mcomponents);
         CFRelease(components);
         CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName);
+        // at this point, we should be setting the preferences if any into this new locale
         CFRelease(localeName);
         CFRelease(formatter->_locale);
         formatter->_locale = newLocale;
-        UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_property._TimeZone);
-        if (cal) ucal_setAttribute(cal, UCAL_FIRST_DAY_OF_WEEK, CFCalendarGetFirstWeekday((CFCalendarRef)value));
-        if (cal) ucal_setAttribute(cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, CFCalendarGetMinimumDaysInFirstWeek((CFCalendarRef)value));
-        if (cal) udat_setCalendar(formatter->_df, cal);
-        if (cal) ucal_close(cal);
-       if (!directToICU) {
+        if (!directToICU) {
             formatter->_property. _Calendar = (CFCalendarRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterCalendarKey);
-       }
+            __ResetUDateFormat(formatter, false);
+        }
     } else if (kCFDateFormatterCalendarIdentifierKey == key) {
        if (!directToICU) {
            oldProperty = formatter->_property. _CalendarName;
@@ -1369,15 +1779,14 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
         CFRelease(mcomponents);
         CFRelease(components);
         CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName);
+        // at this point, we should be setting the preferences if any into this new locale
         CFRelease(localeName);
         CFRelease(formatter->_locale);
         formatter->_locale = newLocale;
-        UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_property._TimeZone);
-        if (cal) udat_setCalendar(formatter->_df, cal);
-        if (cal) ucal_close(cal);
-       if (!directToICU) {
+        if (!directToICU) {
             formatter->_property. _CalendarName = (CFStringRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterCalendarIdentifierKey);
-       }
+            __ResetUDateFormat(formatter, false);
+        }
     } else if (kCFDateFormatterTimeZoneKey == key) {
        if (formatter->_property. _TimeZone != value) {
            if (!directToICU) {
@@ -1388,17 +1797,12 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
            CFTimeZoneRef old = formatter->_property._TimeZone;
            formatter->_property._TimeZone = value ? (CFTimeZoneRef)CFRetain(value) : CFTimeZoneCopyDefault();
            if (old) CFRelease(old);
-           CFStringRef tznam = CFTimeZoneGetName(formatter->_property._TimeZone);
-           UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-           CFIndex ucnt = CFStringGetLength(tznam);
-           if (BUFFER_SIZE < ucnt) ucnt = BUFFER_SIZE;
-           CFStringGetCharacters(tznam, CFRangeMake(0, ucnt), (UniChar *)ubuffer);
-           ucal_setTimeZone(cal, ubuffer, ucnt, &status);
-           if (!directToICU) {
-               old = formatter->_property._TimeZone;
-               formatter->_property. _TimeZone = (CFTimeZoneRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZoneKey);
-               if (old) CFRelease(old);
-           }
+        if (!directToICU) {
+            old = formatter->_property._TimeZone;
+            formatter->_property. _TimeZone = (CFTimeZoneRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTimeZoneKey);
+            __ResetUDateFormat(formatter, false);
+            if (old) CFRelease(old);
+        }
        }
     } else if (kCFDateFormatterDefaultFormatKey == key) {
         // read-only attribute
@@ -1408,11 +1812,8 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
             formatter->_property. _TwoDigitStartDate = NULL;
        }
         __CFGenericValidateType(value, CFDateGetTypeID());
-        CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value);
-        UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
-        udat_set2DigitYearStart(formatter->_df, udate, &status);
        if (!directToICU) {
-            formatter->_property. _TwoDigitStartDate = (CFDateRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterTwoDigitStartDateKey);
+            formatter->_property. _TwoDigitStartDate = value ? (CFDateRef)CFRetain(value) : NULL;
        }
     } else if (kCFDateFormatterDefaultDateKey == key) {
        if (!directToICU) {
@@ -1429,13 +1830,10 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
             formatter->_property. _GregorianStartDate = NULL;
        }
         __CFGenericValidateType(value, CFDateGetTypeID());
-        CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value);
-        UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
-        UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-        ucal_setGregorianChange(cal, udate, &status);
-       if (!directToICU) {
-            formatter->_property. _GregorianStartDate = (CFDateRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterGregorianStartDateKey);
-       }
+        if (!directToICU) {
+            formatter->_property. _GregorianStartDate = value ? (CFDateRef)CFRetain(value) : NULL;
+            __ResetUDateFormat(formatter, false);
+        }
     } else if (kCFDateFormatterEraSymbolsKey == key) {
        SET_SYMBOLS_ARRAY(UDAT_ERAS, 0, _EraSymbols)
     } else if (kCFDateFormatterLongEraSymbolsKey == key) {
@@ -1486,9 +1884,9 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
             CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
             item_ustr = item_buffer;
         }
-        udat_setSymbols(formatter->_df, UDAT_AM_PMS, 0, item_ustr, item_cnt, &status);
+        __cficu_udat_setSymbols(formatter->_df, UDAT_AM_PMS, 0, item_ustr, item_cnt, &status);
        if (!directToICU) {
-            formatter->_property. _AMSymbol = (CFStringRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterAMSymbolKey);
+            formatter->_property. _AMSymbol = value ? (CFStringRef)CFStringCreateCopy(NULL, value) : NULL;
        }
     } else if (kCFDateFormatterPMSymbolKey == key) {
        if (!directToICU) {
@@ -1504,15 +1902,19 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
             CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
             item_ustr = item_buffer;
         }
-        udat_setSymbols(formatter->_df, UDAT_AM_PMS, 1, item_ustr, item_cnt, &status);
+        __cficu_udat_setSymbols(formatter->_df, UDAT_AM_PMS, 1, item_ustr, item_cnt, &status);
        if (!directToICU) {
-            formatter->_property. _PMSymbol = (CFStringRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterPMSymbolKey);
+            formatter->_property. _PMSymbol = value ? (CFStringRef)CFStringCreateCopy(NULL, value) : NULL;
        }
     } else if (kCFDateFormatterAmbiguousYearStrategyKey == key) {
         oldProperty = formatter->_property._AmbiguousYearStrategy;
         formatter->_property._AmbiguousYearStrategy = NULL;
         __CFGenericValidateType(value, CFNumberGetTypeID());
         formatter->_property._AmbiguousYearStrategy = (CFNumberRef)CFRetain(value);
+    } else if (kCFDateFormatterUsesCharacterDirectionKey == key) {
+        __CFGenericValidateType(value, CFBooleanGetTypeID());
+        oldProperty = formatter->_property._UsesCharacterDirection;
+        formatter->_property._UsesCharacterDirection = (CFBooleanRef)CFRetain(value);
     } else {
         CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
     }
@@ -1531,7 +1933,7 @@ CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef
 
     if (kCFDateFormatterIsLenientKey == key) {
        if (formatter->_property._IsLenient) return CFRetain(formatter->_property._IsLenient);
-        return CFRetain(udat_isLenient(formatter->_df) ? kCFBooleanTrue : kCFBooleanFalse);
+        return CFRetain(__cficu_udat_isLenient(formatter->_df) ? kCFBooleanTrue : kCFBooleanFalse);
     } else if (kCFDateFormatterDoesRelativeDateFormattingKey == key) {
        if (formatter->_property._DoesRelativeDateFormatting) return CFRetain(formatter->_property._DoesRelativeDateFormatting);
         return CFRetain(kCFBooleanFalse);
@@ -1544,23 +1946,17 @@ CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef
         CFStringRef ident = (CFStringRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendarIdentifierKey);
         return ident ? CFRetain(ident) : NULL;
     } else if (kCFDateFormatterTimeZoneKey == key) {
-       if (formatter->_property._TwoDigitStartDate) return CFRetain(formatter->_property._TwoDigitStartDate);
-        return CFRetain(formatter->_property._TimeZone);
+        return formatter->_property._TimeZone ? CFRetain(formatter->_property._TimeZone) : NULL;
     } else if (kCFDateFormatterDefaultFormatKey == key) {
         return formatter->_defformat ? CFRetain(formatter->_defformat) : NULL;
     } else if (kCFDateFormatterTwoDigitStartDateKey == key) {
-       if (formatter->_property._TwoDigitStartDate) return CFRetain(formatter->_property._TwoDigitStartDate);
-        UDate udate = udat_get2DigitYearStart(formatter->_df, &status);
-        if (U_SUCCESS(status)) {
-            CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
-            return CFDateCreate(CFGetAllocator(formatter), at);
-        }
+        return formatter->_property._TwoDigitStartDate ? CFRetain(formatter->_property._TwoDigitStartDate) : NULL;
     } else if (kCFDateFormatterDefaultDateKey == key) {
         return formatter->_property._DefaultDate ? CFRetain(formatter->_property._DefaultDate) : NULL;
     } else if (kCFDateFormatterGregorianStartDateKey == key) {
        if (formatter->_property._GregorianStartDate) return CFRetain(formatter->_property._GregorianStartDate);
-        UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
-        UDate udate = ucal_getGregorianChange(cal, &status);
+        const UCalendar *cal = __cficu_udat_getCalendar(formatter->_df);
+        UDate udate = __cficu_ucal_getGregorianChange(cal, &status);
         if (U_SUCCESS(status)) {
             CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
             return CFDateCreate(CFGetAllocator(formatter), at);
@@ -1621,24 +2017,26 @@ CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef
         return __CFDateFormatterGetSymbolsArray(formatter->_df, UDAT_STANDALONE_SHORT_QUARTERS, 0);
     } else if (kCFDateFormatterAMSymbolKey == key) {
        if (formatter->_property._AMSymbol) return CFRetain(formatter->_property._AMSymbol);
-        CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS);
+        CFIndex cnt = __cficu_udat_countSymbols(formatter->_df, UDAT_AM_PMS);
         if (2 <= cnt) {
-            CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 0, ubuffer, BUFFER_SIZE, &status);
+            CFIndex ucnt = __cficu_udat_getSymbols(formatter->_df, UDAT_AM_PMS, 0, ubuffer, BUFFER_SIZE, &status);
             if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
                 return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt);
             }
         }
     } else if (kCFDateFormatterPMSymbolKey == key) {
        if (formatter->_property._PMSymbol) return CFRetain(formatter->_property._PMSymbol);
-        CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS);
+        CFIndex cnt = __cficu_udat_countSymbols(formatter->_df, UDAT_AM_PMS);
         if (2 <= cnt) {
-            CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 1, ubuffer, BUFFER_SIZE, &status);
+            CFIndex ucnt = __cficu_udat_getSymbols(formatter->_df, UDAT_AM_PMS, 1, ubuffer, BUFFER_SIZE, &status);
             if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
                 return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt);
             }
         }
     } else if (kCFDateFormatterAmbiguousYearStrategyKey == key) {
         if (formatter->_property._AmbiguousYearStrategy) return CFRetain(formatter->_property._AmbiguousYearStrategy);
+    } else if (kCFDateFormatterUsesCharacterDirectionKey == key) {
+        return formatter->_property._UsesCharacterDirection ? CFRetain(formatter->_property._UsesCharacterDirection) : CFRetain(kCFBooleanFalse);
     } else {
         CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
     }
index 49ca96887875e35570acfc795c2b38c420477542..d88a21226f08b9e81a1ac8b44cbbe1d2f6237b5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFDateFormatter.h
-       Copyright (c) 2003-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2003-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATEFORMATTER__)
index 173c0ae97d11ba6d7d6965d6c2b5d44070c620d9..b689e997d70277d80369ddbdbb45fcd5580a2782 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFDictionary.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -47,7 +47,6 @@
 const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFDictionaryKeyCallBacks kCFCopyStringDictionaryKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
-__private_extern__ const CFDictionaryValueCallBacks kCFTypeDictionaryValueCompactableCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
 static const CFDictionaryKeyCallBacks __kCFNullDictionaryKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
 static const CFDictionaryValueCallBacks __kCFNullDictionaryValueCallBacks = {0, NULL, NULL, NULL, NULL};
 
@@ -133,328 +132,131 @@ CFTypeID CFDictionaryGetTypeID(void) {
     return __kCFDictionaryTypeID;
 }
 
-#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
-#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
-
-static uintptr_t __CFDictionaryStandardRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0100) return stack_value;
-    return (CFBasicHashHasStrongValues(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_value) : (uintptr_t)CFRetain((CFTypeRef)stack_value);
-}
-
-static uintptr_t __CFDictionaryStandardRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0001) return stack_key;
-    return (CFBasicHashHasStrongKeys(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_key) : (uintptr_t)CFRetain((CFTypeRef)stack_key);
-}
-
-static void __CFDictionaryStandardReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0200) return;
-    if (CFBasicHashHasStrongValues(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_value); else CFRelease((CFTypeRef)stack_value);
-}
-
-static void __CFDictionaryStandardReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0002) return;
-    if (CFBasicHashHasStrongKeys(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_key); else CFRelease((CFTypeRef)stack_key);
-}
-
-static Boolean __CFDictionaryStandardEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0400) return coll_value1 == stack_value2;
-    return CFEqual((CFTypeRef)coll_value1, (CFTypeRef)stack_value2);
-}
-
-static Boolean __CFDictionaryStandardEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0004) return coll_key1 == stack_key2;
-    return CFEqual((CFTypeRef)coll_key1, (CFTypeRef)stack_key2);
-}
-
-static uintptr_t __CFDictionaryStandardHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0008) return stack_key;
-    return (uintptr_t)CFHash((CFTypeRef)stack_key);
-}
-
-static uintptr_t __CFDictionaryStandardGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFDictionaryStandardCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
-    return CFCopyDescription((CFTypeRef)stack_value);
-}
-
-static CFStringRef __CFDictionaryStandardCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
-    return CFCopyDescription((CFTypeRef)stack_key);
-}
-
-static CFBasicHashCallbacks *__CFDictionaryStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-static void __CFDictionaryStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-
-static const CFBasicHashCallbacks CFDictionaryStandardCallbacks = {
-    __CFDictionaryStandardCopyCallbacks,
-    __CFDictionaryStandardFreeCallbacks,
-    __CFDictionaryStandardRetainValue,
-    __CFDictionaryStandardRetainKey,
-    __CFDictionaryStandardReleaseValue,
-    __CFDictionaryStandardReleaseKey,
-    __CFDictionaryStandardEquateValues,
-    __CFDictionaryStandardEquateKeys,
-    __CFDictionaryStandardHashKey,
-    __CFDictionaryStandardGetIndirectKey,
-    __CFDictionaryStandardCopyValueDescription,
-    __CFDictionaryStandardCopyKeyDescription
-};
-
-static CFBasicHashCallbacks *__CFDictionaryStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    return (CFBasicHashCallbacks *)&CFDictionaryStandardCallbacks;
-}
-
-static void __CFDictionaryStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-}
-    
-
-static CFBasicHashCallbacks *__CFDictionaryCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    CFBasicHashCallbacks *newcb = NULL;
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-    } else {
-        newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
-    }
-    if (!newcb) return NULL;
-    memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
-    return newcb;
-}
-
-static void __CFDictionaryFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-    } else {
-       CFAllocatorDeallocate(allocator, cb);
-    }
-}
-    
-static uintptr_t __CFDictionaryRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
-    if (NULL == value_retain) return stack_value;
-    return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_value);
-}
-
-static uintptr_t __CFDictionaryRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
-    if (NULL == key_retain) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_key);
-}
-
-static void __CFDictionaryReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
-    if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t) stack_value);
-}
-
-static void __CFDictionaryReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
-    if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t) stack_key);
-}
-
-static Boolean __CFDictionaryEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
-    if (NULL == value_equal) return (coll_value1 == stack_value2);
-    return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t) coll_value1, (const_any_pointer_t) stack_value2) ? 1 : 0;
-}
-
-static Boolean __CFDictionaryEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
-    if (NULL == key_equal) return (coll_key1 == stack_key2);
-    return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t) coll_key1, (const_any_pointer_t) stack_key2) ? 1 : 0;
-}
-
-static uintptr_t __CFDictionaryHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
-    if (NULL == hash) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t) stack_key);
-}
-
-static uintptr_t __CFDictionaryGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFDictionaryCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
-    if (NULL == value_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_value);
-    return (CFStringRef)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t) stack_value);
-}
-
-static CFStringRef __CFDictionaryCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[9];
-    if (NULL == key_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_key);
-    return (CFStringRef)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t) stack_key);
-}
 
 static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
 
-    CFBasicHashCallbacks *cb = NULL;
-    Boolean std_cb = false;
-    uint16_t specialBits = 0;
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-
-    if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
-        Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
-        Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
-        Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
-        Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
-        Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
-
-        Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
-        Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
-        Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
-        Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
-
-        Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
-        Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
-        Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
-        Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
-        Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
-
-        Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
-        Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
-        Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
-        Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
-
-        if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
-            cb = (CFBasicHashCallbacks *)&CFDictionaryStandardCallbacks;
-            if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
-                std_cb = true;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) { // all this crap is just for figuring out two flags for GC in the way done historically; it probably simplifies down to three lines, but we let the compiler worry about that
+        Boolean set_cb = false;
+        Boolean std_cb = false;
+        const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+
+       if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
+           Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
+           Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
+           Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
+           Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
+           Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
+
+           Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
+           Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
+           Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
+           Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
+
+           Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
+           Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
+           Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
+           Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
+           Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
+
+           Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
+           Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
+           Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
+           Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
+
+           if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
+               set_cb = true;
+               if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
+                   std_cb = true;
+               } else {
+                   // just set these to tickle the GC Strong logic below in a way that mimics past practice
+                   key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+                   key_release = keyCallBacks ? keyCallBacks->release : NULL;
+                   if (useValueCB) {
+                       value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                       value_release = valueCallBacks ? valueCallBacks->release : NULL;
+                   } else {
+                       value_retain = key_retain;
+                       value_release = key_release;
+                   }
+               }
+           }
+       }
+
+        if (!set_cb) {
+            key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+            key_release = keyCallBacks ? keyCallBacks->release : NULL;
+            if (useValueCB) {
+                value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                value_release = valueCallBacks ? valueCallBacks->release : NULL;
             } else {
-                // just set these to tickle the GC Strong logic below in a way that mimics past practice
-                key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-                key_release = keyCallBacks ? keyCallBacks->release : NULL;
-                if (useValueCB) {
-                    value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-                    value_release = valueCallBacks ? valueCallBacks->release : NULL;
-                } else {
-                    value_retain = key_retain;
-                    value_release = key_release;
-                }
+                value_retain = key_retain;
+                value_release = key_release;
             }
-            if (keyRetainNull) specialBits |= 0x0001;
-            if (keyReleaseNull) specialBits |= 0x0002;
-            if (keyEquateNull) specialBits |= 0x0004;
-            if (keyHashNull) specialBits |= 0x0008;
-            if (keyDescribeNull) specialBits |= 0x0010;
-            if (valueRetainNull) specialBits |= 0x0100;
-            if (valueReleaseNull) specialBits |= 0x0200;
-            if (valueEquateNull) specialBits |= 0x0400;
-            if (valueDescribeNull) specialBits |= 0x0800;
-        }
-    }
-
-    if (!cb) {
-        Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        CFStringRef (*key_describe)(const_any_pointer_t) = NULL;
-        CFStringRef (*value_describe)(const_any_pointer_t) = NULL;
-        CFHashCode (*hash_key)(const_any_pointer_t) = NULL;
-        key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-        key_release = keyCallBacks ? keyCallBacks->release : NULL;
-        key_equal = keyCallBacks ? keyCallBacks->equal : NULL;
-        key_describe = keyCallBacks ? keyCallBacks->copyDescription : NULL;
-        if (useValueCB) {
-            value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-            value_release = valueCallBacks ? valueCallBacks->release : NULL;
-            value_equal = valueCallBacks ? valueCallBacks->equal : NULL;
-            value_describe = valueCallBacks ? valueCallBacks->copyDescription : NULL;
-        } else {
-            value_retain = key_retain;
-            value_release = key_release;
-            value_equal = key_equal;
-            value_describe = key_describe;
-        }
-        hash_key = keyCallBacks ? keyCallBacks->hash : NULL;
-
-        CFBasicHashCallbacks *newcb = NULL;
-        if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-        } else {
-            newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) return NULL;
-        newcb->copyCallbacks = __CFDictionaryCopyCallbacks;
-        newcb->freeCallbacks = __CFDictionaryFreeCallbacks;
-        newcb->retainValue = __CFDictionaryRetainValue;
-        newcb->retainKey = __CFDictionaryRetainKey;
-        newcb->releaseValue = __CFDictionaryReleaseValue;
-        newcb->releaseKey = __CFDictionaryReleaseKey;
-        newcb->equateValues = __CFDictionaryEquateValues;
-        newcb->equateKeys = __CFDictionaryEquateKeys;
-        newcb->hashKey = __CFDictionaryHashKey;
-        newcb->getIndirectKey = __CFDictionaryGetIndirectKey;
-        newcb->copyValueDescription = __CFDictionaryCopyValueDescription;
-        newcb->copyKeyDescription = __CFDictionaryCopyKeyDescription;
-        newcb->context[0] = (uintptr_t)value_retain;
-        newcb->context[1] = (uintptr_t)key_retain;
-        newcb->context[2] = (uintptr_t)value_release;
-        newcb->context[3] = (uintptr_t)key_release;
-        newcb->context[4] = (uintptr_t)value_equal;
-        newcb->context[5] = (uintptr_t)key_equal;
-        newcb->context[6] = (uintptr_t)hash_key;
-        newcb->context[8] = (uintptr_t)value_describe;
-        newcb->context[9] = (uintptr_t)key_describe;
-        cb = newcb;
-    }
 
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
         if (std_cb || value_retain != NULL || value_release != NULL) {
             flags |= kCFBasicHashStrongValues;
         }
         if (std_cb || key_retain != NULL || key_release != NULL) {
             flags |= kCFBasicHashStrongKeys;
         }
-#if CFDictionary
-        if (valueCallBacks == &kCFTypeDictionaryValueCompactableCallBacks) {
-            // Foundation allocated collections will have compactable values
-            flags |= kCFBasicHashCompactableValues;
-        }
-#endif
     }
 
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
-    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL;
+    callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL;
+    callbacks.equateKeys = keyCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks->equal : NULL;
+    callbacks.hashKey = keyCallBacks ? (CFHashCode (*)(uintptr_t))keyCallBacks->hash : NULL;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = keyCallBacks ? (CFStringRef (*)(uintptr_t))keyCallBacks->copyDescription : NULL;
+    callbacks.retainValue = useValueCB ? (valueCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))valueCallBacks->retain : NULL) : (callbacks.retainKey);
+    callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey);
+    callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys);
+    callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription);
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
     return ht;
 }
 
 #if CFDictionary
-__private_extern__ CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
 #endif
 #if CFSet || CFBag
-__private_extern__ CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFDictionaryCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
     const_any_pointer_t *vlist = klist;
 #endif
     CFTypeID typeID = CFDictionaryGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
-    CFBasicHashCallbacks *cb = (CFBasicHashCallbacks *)&CFDictionaryStandardCallbacks;
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, 0x0303);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryKeyCallBacks.retain;
+    callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryKeyCallBacks.release;
+    callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryKeyCallBacks.equal;
+    callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks.hash;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeDictionaryKeyCallBacks.copyDescription;
+    callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.retain : callbacks.retainKey;
+    callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeDictionaryValueCallBacks.release : callbacks.releaseKey;
+    callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeDictionaryValueCallBacks.equal : callbacks.equateKeys;
+    callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeDictionaryValueCallBacks.copyDescription : callbacks.copyKeyDescription;
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
+    CFBasicHashSuppressRC(ht);
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
-    CFBasicHashSetSpecialBits(ht, 0x0000);
+    CFBasicHashUnsuppressRC(ht);
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)");
     return (CFHashRef)ht;
 }
@@ -476,8 +278,7 @@ CFHashRef CFDictionaryCreate(CFAllocatorRef allocator, const_any_pointer_t *klis
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)");
     return (CFHashRef)ht;
 }
@@ -493,8 +294,7 @@ CFMutableHashRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex cap
     CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
     CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)");
     return (CFMutableHashRef)ht;
 }
@@ -528,8 +328,7 @@ CFHashRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     }
     if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (immutable)");
     return (CFHashRef)ht;
 }
@@ -563,8 +362,7 @@ CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)");
     return (CFMutableHashRef)ht;
 }
index 41c75d22da83112cf3aed63342f4df0bfa0f4fee..312f1d7422dc08abdf414592a1a2e51850f00bbe 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFDictionary.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*!
index d1cee849eccb00f396c2e599f5c53e7dab587c08..00db59599bf0b8a52103ecd72329d34aa72c53bd 100644 (file)
--- a/CFError.c
+++ b/CFError.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFError.c
-       Copyright (c) 2006-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2006-2013, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
@@ -160,7 +160,7 @@ static const CFRuntimeClass __CFErrorClass = {
     __CFErrorCopyDescription
 };
 
-__private_extern__ void __CFErrorInitialize(void) {
+CF_PRIVATE void __CFErrorInitialize(void) {
     __kCFErrorTypeID = _CFRuntimeRegisterClass(&__CFErrorClass);
 }
 
@@ -312,7 +312,7 @@ CFStringRef _CFErrorCreateDebugDescription(CFErrorRef err) {
     CFStringRef debugDesc = _CFErrorCopyUserInfoKey(err, kCFErrorDebugDescriptionKey);
     CFDictionaryRef userInfo = _CFErrorGetUserInfo(err);
     CFMutableStringRef result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
-    CFStringAppendFormat(result, NULL, CFSTR("Error Domain=%@ Code=%d"), CFErrorGetDomain(err), (long)CFErrorGetCode(err));
+    CFStringAppendFormat(result, NULL, CFSTR("Error Domain=%@ Code=%ld"), CFErrorGetDomain(err), (long)CFErrorGetCode(err));
     CFStringAppendFormat(result, NULL, CFSTR(" \"%@\""), desc);
     if (debugDesc && CFStringGetLength(debugDesc) > 0) CFStringAppendFormat(result, NULL, CFSTR(" (%@)"), debugDesc);
     if (userInfo && CFDictionaryGetCount(userInfo)) {
index 61ee8a123145073b4a8a01f9059f7595be496a72..8602290878619ca327e584b7dc04801e3a7ca2c8 100644 (file)
--- a/CFError.h
+++ b/CFError.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFError.h
-       Copyright (c) 2006-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2006-2013, Apple Inc. All rights reserved.
 */
 
 /*!
index 6a9b6ef65941aa02864f69d4325cd9a622aaf0d8..f370523beb19403f062e6a88d9b1cd113fc4eeae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFError_Private.h
-        Copyright (c) 2006-2012, Apple Inc. All rights reserved.
+        Copyright (c) 2006-2013, Apple Inc. All rights reserved.
        
        This is Apple-internal SPI for CFError.
 */
index 4334b0ee67f55df93b3a39e3bb163e12b2fc1236..9723263c9698f1e40f8e4741759828944f174b69 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFFileUtilities.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -74,33 +74,33 @@ CF_INLINE void closeAutoFSNoWait(int fd) {
     if (-1 != fd) close(fd);
 }
 
-__private_extern__ CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType) {
+CF_PRIVATE CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType) {
     return (abstractType ? (CFStringRef)CFRetain(abstractType) : NULL);
 }
 
 
-__private_extern__ Boolean _CFCreateDirectory(const char *path) {
+CF_PRIVATE Boolean _CFCreateDirectory(const char *path) {
     int no_hang_fd = openAutoFSNoWait();
     int ret = ((mkdir(path, 0777) == 0) ? true : false);
     closeAutoFSNoWait(no_hang_fd);
     return ret;
 }
 
-__private_extern__ Boolean _CFRemoveDirectory(const char *path) {
+CF_PRIVATE Boolean _CFRemoveDirectory(const char *path) {
     int no_hang_fd = openAutoFSNoWait();
     int ret = ((rmdir(path) == 0) ? true : false);
     closeAutoFSNoWait(no_hang_fd);
     return ret;
 }
 
-__private_extern__ Boolean _CFDeleteFile(const char *path) {
+CF_PRIVATE Boolean _CFDeleteFile(const char *path) {
     int no_hang_fd = openAutoFSNoWait();
     int ret = unlink(path) == 0;
     closeAutoFSNoWait(no_hang_fd);
     return ret;
 }
 
-__private_extern__ Boolean _CFReadBytesFromPathAndGetFD(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags, int *fd) {    // maxLength is the number of bytes desired, or 0 if the whole file is desired regardless of length.
+CF_PRIVATE Boolean _CFReadBytesFromPathAndGetFD(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags, int *fd) {    // maxLength is the number of bytes desired, or 0 if the whole file is desired regardless of length.
     struct statinfo statBuf;
     
     *bytes = NULL;
@@ -155,7 +155,7 @@ __private_extern__ Boolean _CFReadBytesFromPathAndGetFD(CFAllocatorRef alloc, co
     return true;
 }
 
-__private_extern__ Boolean _CFReadBytesFromPath(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags) {
+CF_PRIVATE Boolean _CFReadBytesFromPath(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags) {
     int fd = -1;
     Boolean result = _CFReadBytesFromPathAndGetFD(alloc, path, bytes, length, maxLength, extraOpenFlags, &fd);
     if (fd >= 0) {
@@ -163,7 +163,7 @@ __private_extern__ Boolean _CFReadBytesFromPath(CFAllocatorRef alloc, const char
     }
     return result;
 }
-__private_extern__ Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags) {
+CF_PRIVATE Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags) {
     // maxLength is the number of bytes desired, or 0 if the whole file is desired regardless of length.
     
     char path[CFMaxPathSize];
@@ -173,7 +173,7 @@ __private_extern__ Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef u
     return _CFReadBytesFromPath(alloc, (const char *)path, bytes, length, maxLength, extraOpenFlags);
 }
 
-__private_extern__ Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length) {
+CF_PRIVATE Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length) {
     int fd = -1;
     int mode;
     struct statinfo statBuf;
@@ -216,7 +216,7 @@ __private_extern__ Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes,
 /* On Mac OS 8/9, one of dirSpec and dirURL must be non-NULL.  On all other platforms, one of path and dirURL must be non-NULL
 If both are present, they are assumed to be in-synch; that is, they both refer to the same directory.  */
 /* Lately, dirSpec appears to be (rightfully) unused. */
-__private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) {
+CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType) {
     CFMutableArrayRef files = NULL;
     Boolean releaseBase = false;
     CFIndex pathLength = dirPath ? strlen(dirPath) : 0;
@@ -493,7 +493,7 @@ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc
     
 #else
     
-#error _CFContentsOfDirectory() unknown architecture, not implemented
+#error _CFCreateContentsOfDirectory() unknown architecture, not implemented
     
 #endif
 
@@ -506,7 +506,7 @@ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc
     return files;
 }
 
-__private_extern__ SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
+CF_PRIVATE SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
     Boolean fileExists;
     Boolean isDirectory = false;
     
@@ -580,7 +580,7 @@ __private_extern__ SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path,
     if (dirContents != NULL) {
         if (fileExists && isDirectory) {
             
-            CFMutableArrayRef contents = _CFContentsOfDirectory(alloc, (char *)path, NULL, NULL, NULL);
+            CFMutableArrayRef contents = _CFCreateContentsOfDirectory(alloc, (char *)path, NULL, NULL, NULL);
             
             if (contents) {
                 *dirContents = contents;
@@ -594,7 +594,7 @@ __private_extern__ SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path,
     return 0;
 }
 
-__private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
+CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
     
     char path[CFMaxPathSize];
 
@@ -614,35 +614,57 @@ __private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pa
 
 #if defined(WINDOWS_PATH_SEMANTICS)
     #define CFPreferredSlash   ((UniChar)'\\')
+    #define CFPreferredSlashStr CFSTR("\\")
 #elif defined(UNIX_PATH_SEMANTICS)
     #define CFPreferredSlash   ((UniChar)'/')
-#elif defined(HFS_PATH_SEMANTICS)
-    #define CFPreferredSlash   ((UniChar)':')
+    #define CFPreferredSlashStr CFSTR("/")
 #else
     #error Cannot define NSPreferredSlash on this platform
 #endif
 
-#if defined(HFS_PATH_SEMANTICS)
-#define HAS_DRIVE(S) (false)
-#define HAS_NET(S) (false)
-#else
+static Boolean _hasDrive(CFStringRef path) {
+    if (CFStringGetLength(path) >= 2) {
+        UniChar firstCharacters[2];
+        firstCharacters[0] = CFStringGetCharacterAtIndex(path, 0);
+        firstCharacters[1] = CFStringGetCharacterAtIndex(path, 1);
+        if (firstCharacters[1] == ':' &&
+            (('A' <= (firstCharacters)[0] && (firstCharacters)[0] <= 'Z') ||
+             ('a' <= (firstCharacters)[0] && (firstCharacters)[0] <= 'z'))
+            ) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static Boolean _hasNet(CFStringRef path) {
+    if (CFStringGetLength(path) >= 2) {
+        UniChar firstCharacters[2];
+        firstCharacters[0] = CFStringGetCharacterAtIndex(path, 0);
+        firstCharacters[1] = CFStringGetCharacterAtIndex(path, 1);
+        if (firstCharacters[0] == '\\' && firstCharacters[1] == '\\') return true;
+    }
+    return false;
+}
+
 #define HAS_DRIVE(S) ((S)[1] == ':' && (('A' <= (S)[0] && (S)[0] <= 'Z') || ('a' <= (S)[0] && (S)[0] <= 'z')))
 #define HAS_NET(S) ((S)[0] == '\\' && (S)[1] == '\\')
-#endif
 
 #if defined(WINDOWS_PATH_SEMANTICS)
     #define IS_SLASH(C)        ((C) == '\\' || (C) == '/')
 #elif defined(UNIX_PATH_SEMANTICS)
     #define IS_SLASH(C)        ((C) == '/')
-#elif defined(HFS_PATH_SEMANTICS)
-    #define IS_SLASH(C)        ((C) == ':')
 #endif
 
-__private_extern__ UniChar _CFGetSlash(){
+CF_PRIVATE UniChar _CFGetSlash() {
     return CFPreferredSlash;
 }
 
-__private_extern__ Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length) {
+CF_PRIVATE CFStringRef _CFGetSlashStr() {
+    return CFPreferredSlashStr;
+}
+
+CF_PRIVATE Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length) {
     if (length < 1) {
         return false;
     }
@@ -662,8 +684,6 @@ __private_extern__ Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length)
     if (IS_SLASH(unichars[2]) && HAS_DRIVE(unichars)) {
         return true;
     }
-#elif defined(HFS_PATH_SEMANTICS)
-    return !IS_SLASH(unichars[0]);
 #else
     if (unichars[0] == '~') {
         return true;
@@ -675,7 +695,7 @@ __private_extern__ Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length)
     return false;
 }
 
-__private_extern__ Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length) {
+CF_PRIVATE Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length) {
     Boolean destHasDrive = (1 < *length) && HAS_DRIVE(unichars);
     CFIndex oldLength = *length;
     while (((destHasDrive && 3 < *length) || (!destHasDrive && 1 < *length)) && IS_SLASH(unichars[*length - 1])) {
@@ -684,7 +704,7 @@ __private_extern__ Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFInde
     return (oldLength != *length);
 }
 
-__private_extern__ Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex *length, CFIndex maxLength) {
+static Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex *length, CFIndex maxLength) {
     if (maxLength < *length + 1) {
         return false;
     }
@@ -708,7 +728,39 @@ __private_extern__ Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex
     return true;
 }
 
-__private_extern__ Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength) {
+CF_PRIVATE void _CFAppendTrailingPathSlash2(CFMutableStringRef path) {
+    static const UniChar slash[1] = { CFPreferredSlash };
+    CFIndex len = CFStringGetLength(path);
+    if (len == 0) {
+        // Do nothing for this case
+    } else if (len == 1) {
+        UniChar character = CFStringGetCharacterAtIndex((CFStringRef)path, 0);
+        if (!IS_SLASH(character)) {
+            CFStringAppendCharacters(path, slash, 1);
+        }
+    } else if (len == 2) {
+        if (!_hasDrive(path) && !_hasNet(path)) {
+            CFStringAppendCharacters(path, slash, 1);
+        }
+    } else {
+        CFStringAppendCharacters(path, slash, 1);
+    }
+}
+
+CF_PRIVATE void _CFAppendConditionalTrailingPathSlash2(CFMutableStringRef path) {
+    static const UniChar slash[1] = { CFPreferredSlash };
+    UniChar character = CFStringGetCharacterAtIndex((CFStringRef)path, CFStringGetLength(path) - 1);
+    if (!IS_SLASH(character)) {
+        CFStringAppendCharacters(path, slash, 1);
+    }
+}
+
+CF_PRIVATE void _CFAppendPathComponent2(CFMutableStringRef path, CFStringRef component) {
+    _CFAppendTrailingPathSlash2(path);
+    CFStringAppend(path, component);
+}
+
+CF_PRIVATE Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength) {
     if (0 == componentLength) {
         return true;
     }
@@ -721,7 +773,61 @@ __private_extern__ Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *le
     return true;
 }
 
-__private_extern__ Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength) {
+CF_PRIVATE Boolean _CFAppendPathExtension2(CFMutableStringRef path, CFStringRef extension) {
+    if (!path) {
+        return false;
+    }
+    
+    if (0 < CFStringGetLength(extension) && IS_SLASH(CFStringGetCharacterAtIndex(extension, 0))) {
+        return false;
+    }
+    if (1 < CFStringGetLength(extension)) {
+        if (_hasDrive(extension)) return false;
+    }
+    
+    Boolean destHasDrive = (1 < CFStringGetLength(path)) && _hasDrive(path);
+    while (((destHasDrive && 3 < CFStringGetLength(path)) || (!destHasDrive && 1 < CFStringGetLength(path))) && IS_SLASH(CFStringGetCharacterAtIndex(path, CFStringGetLength(path) - 1))) {
+        CFStringDelete(path, CFRangeMake(CFStringGetLength(path) - 1, 1));
+    }
+
+    if (CFStringGetLength(path) == 0) {
+        return false;
+    }
+    
+    UniChar firstChar = CFStringGetCharacterAtIndex(path, 0);
+    CFIndex newLength = CFStringGetLength(path);
+    switch (newLength) {
+        case 0:
+            return false;
+        case 1:
+            if (IS_SLASH(firstChar) || firstChar == '~') {
+                return false;
+            }
+            break;
+        case 2:
+            if (_hasDrive(path) || _hasNet(path)) {
+                return false;
+            }
+            break;
+        case 3:
+            if (IS_SLASH(CFStringGetCharacterAtIndex(path, 2)) && _hasDrive(path)) {
+                return false;
+            }
+            break;
+    }
+    if (0 < newLength && firstChar == '~') {
+        // Make sure we have a slash in the string
+        if (!CFStringFindWithOptions(path, CFPreferredSlashStr, CFRangeMake(1, newLength - 1), 0, NULL)) {
+            return false;
+        }
+    }
+    static const UniChar dotChar = '.';
+    CFStringAppendCharacters(path, &dotChar, 1);
+    CFStringAppend(path, extension);
+    return true;
+}
+
+CF_PRIVATE Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength) {
     if (maxLength < *length + 1 + extensionLength) {
         return false;
     }
@@ -767,7 +873,7 @@ __private_extern__ Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *le
     return true;
 }
 
-__private_extern__ Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash) {
+CF_PRIVATE Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash) {
     CFIndex didx, sidx, scnt = *length;
     sidx = (1 < *length && HAS_NET(unichars)) ? 2 : 0;
     didx = sidx;
@@ -783,7 +889,34 @@ __private_extern__ Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *l
     return (scnt != didx);
 }
 
-__private_extern__ CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length) {
+CF_PRIVATE CFStringRef _CFCreateLastPathComponent(CFAllocatorRef alloc, CFStringRef path, CFIndex *slashIndex) {
+    CFIndex len = CFStringGetLength(path);
+    if (len < 2) {
+        // Can't be any path components in a string this short
+        if (slashIndex) *slashIndex = -1;
+        return (CFStringRef)CFRetain(path);
+    }
+    
+    // Find the last slash
+    for (CFIndex i = len - 1; i >= 0; i--) {
+        if (IS_SLASH(CFStringGetCharacterAtIndex(path, i))) {
+            if (slashIndex) *slashIndex = i;
+            return CFStringCreateWithSubstring(alloc, path, CFRangeMake(i + 1, len - i - 1));
+        }
+    }
+    
+    // Strip any drive if we have one
+    if (len > 2 && _hasDrive(path)) {
+        if (slashIndex) *slashIndex = -1;
+        return CFStringCreateWithSubstring(alloc, path, CFRangeMake(2, len - 2));
+    }
+    
+    // No slash, so just return the same string
+    if (slashIndex) *slashIndex = -1;
+    return (CFStringRef)CFRetain(path);
+}
+
+CF_PRIVATE CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length) {
     CFIndex idx;
     if (length < 2) {
         return 0;
@@ -799,7 +932,23 @@ __private_extern__ CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFInde
     return 0;
 }
 
-__private_extern__ CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length) {
+CF_PRIVATE CFIndex _CFStartOfLastPathComponent2(CFStringRef path) {
+    CFIndex length = CFStringGetLength(path);
+    if (length < 2) {
+        return 0;
+    }
+    for (CFIndex idx = length - 1; idx; idx--) {
+        if (IS_SLASH(CFStringGetCharacterAtIndex(path, idx - 1))) {
+            return idx;
+        }
+    }
+    if ((2 < length && _hasDrive(path))) {
+        return 2;
+    }
+    return 0;
+}
+
+CF_PRIVATE CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length) {
     CFIndex idx;
     if (length < 2) {
         return 0;
@@ -818,7 +967,28 @@ __private_extern__ CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unic
     return 0;
 }
 
-__private_extern__ CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length) {
+CF_PRIVATE CFIndex _CFStartOfPathExtension2(CFStringRef path) {
+    if (CFStringGetLength(path) < 2) {
+        return 0;
+    }
+    Boolean hasDrive = _hasDrive(path);
+    for (CFIndex idx = CFStringGetLength(path) - 1; idx; idx--) {
+        UniChar thisCharacter = CFStringGetCharacterAtIndex(path, idx);
+        if (IS_SLASH(thisCharacter)) {
+            return 0;
+        }
+        if (thisCharacter != '.') {
+            continue;
+        }
+        if (idx == 2 && hasDrive) {
+            return 0;
+        }
+        return idx;
+    }
+    return 0;
+}
+
+CF_PRIVATE CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length) {
     CFIndex idx;
     if (length < 2) {
         return 0;
@@ -838,9 +1008,97 @@ __private_extern__ CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex le
     return 0;
 }
 
-__private_extern__ CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length) {
+CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension2(CFStringRef path) {
+    CFIndex start = _CFStartOfPathExtension2(path);
+    return ((0 < start) ? start : CFStringGetLength(path));
+}
+
+CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length) {
     CFIndex start = _CFStartOfPathExtension(unichars, length);
     return ((0 < start) ? start : length);
 }
 
+#if DEPLOYMENT_TARGET_WINDOWS
+#define        DT_DIR           4
+#define        DT_REG           8
+#define        DT_LNK          10
+#endif
+
+// NOTE: on Windows the filename is UTF16-encoded, the fileNameLen is result of wcslen. This function automatically skips '.' and '..', and '._' files
+CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean (^fileHandler)(CFStringRef fileName, uint8_t fileType)) {
+    char directoryPathBuf[CFMaxPathSize];
+    if (!CFStringGetFileSystemRepresentation(directoryPath, directoryPathBuf, CFMaxPathSize)) return;
+    
+#if DEPLOYMENT_TARGET_WINDOWS
+    CFIndex cpathLen = strlen(directoryPathBuf);
+    // Make sure there is room for the additional space we need in the win32 api
+    if (cpathLen + 2 < CFMaxPathSize) {
+        WIN32_FIND_DATAW file;
+        HANDLE handle;
+        
+        directoryPathBuf[cpathLen++] = '\\';
+        directoryPathBuf[cpathLen++] = '*';
+        directoryPathBuf[cpathLen] = '\0';
+        
+        // Convert UTF8 buffer to windows appropriate UTF-16LE
+        // Get the real length of the string in UTF16 characters
+        CFStringRef cfStr = CFStringCreateWithCString(kCFAllocatorSystemDefault, directoryPathBuf, kCFStringEncodingUTF8);
+        cpathLen = CFStringGetLength(cfStr);
+        // Allocate a wide buffer to hold the converted string, including space for a NULL terminator
+        wchar_t *wideBuf = (wchar_t *)malloc((cpathLen + 1) * sizeof(wchar_t));
+        // Copy the string into the buffer and terminate
+        CFStringGetCharacters(cfStr, CFRangeMake(0, cpathLen), (UniChar *)wideBuf);
+        wideBuf[cpathLen] = 0;
+        CFRelease(cfStr);
+        
+        handle = FindFirstFileW(wideBuf, (LPWIN32_FIND_DATAW)&file);
+        if (handle != INVALID_HANDLE_VALUE) {
+            do {
+                CFIndex nameLen = wcslen(file.cFileName);
+                if (file.cFileName[0] == '.' && (nameLen == 1 || (nameLen == 2  && file.cFileName[1] == '.'))) {
+                    continue;
+                }
+                
+                CFStringRef fileName = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const uint8_t *)file.cFileName, nameLen * sizeof(wchar_t), kCFStringEncodingUTF16, NO);
+                if (!fileName) {
+                    continue;
+                }
+                
+                Boolean isDirectory = file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
+                Boolean result = fileHandler(fileName, isDirectory ? DT_DIR : DT_REG);
+                CFRelease(fileName);
+                if (!result) break;
+            } while (FindNextFileW(handle, &file));
+            
+            FindClose(handle);
+        }
+        free(wideBuf);
+    }
+#else
+    DIR *dirp;
+    struct dirent *dent;
+    if ((dirp = opendir(directoryPathBuf))) {
+        while ((dent = readdir(dirp))) {
+#if DEPLOYMENT_TARGET_LINUX
+            CFIndex nameLen = strlen(dent->d_name);
+#else
+            CFIndex nameLen = dent->d_namlen;
+#endif
+            if (0 == nameLen || 0 == dent->d_fileno || ('.' == dent->d_name[0] && (1 == nameLen || (2 == nameLen && '.' == dent->d_name[1]) || '_' == dent->d_name[1]))) {
+                continue;
+            }
+            
+            CFStringRef fileName = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, dent->d_name);
+            if (!fileName) {
+                continue;
+            }
+
+            Boolean result = fileHandler(fileName, dent->d_type);
+            CFRelease(fileName);
+            if (!result) break;
+        }
+        (void)closedir(dirp);
+    }
+#endif
+}
 
index 3414ca33df7b6f7d32166366da08573e5bad7c16..931b11e192f42b9ff5fef136b0522b51509420b2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFICUConverters.c
-       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -74,7 +74,7 @@ CF_INLINE __CFICUThreadData *__CFStringEncodingICUGetThreadData() {
     return data;
 }
 
-__private_extern__ const char *__CFStringEncodingGetICUName(CFStringEncoding encoding) {
+CF_PRIVATE const char *__CFStringEncodingGetICUName(CFStringEncoding encoding) {
 #define STACK_BUFFER_SIZE (60)
     char buffer[STACK_BUFFER_SIZE];
     const char *result = NULL;
@@ -93,11 +93,12 @@ __private_extern__ const char *__CFStringEncodingGetICUName(CFStringEncoding enc
 #undef STACK_BUFFER_SIZE
 }
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromICUName(const char *icuName) {
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromICUName(const char *icuName) {
     uint32_t codepage;
+    char *endPtr;
     UErrorCode errorCode = U_ZERO_ERROR;
 
-    if ((0 == strncasecmp_l(icuName, "windows-", strlen("windows-"), NULL)) && (0 != (codepage = strtol(icuName + strlen("windows-"), NULL, 10)))) return __CFStringEncodingGetFromWindowsCodePage(codepage);
+    if ((0 == strncasecmp_l(icuName, "windows-", strlen("windows-"), NULL)) && (0 != (codepage = strtol(icuName + strlen("windows-"), &endPtr, 10))) && (*endPtr == '\0')) return __CFStringEncodingGetFromWindowsCodePage(codepage);
 
     if (0 != ucnv_countAliases(icuName, &errorCode)) {
         CFStringEncoding encoding;
@@ -107,7 +108,7 @@ __private_extern__ CFStringEncoding __CFStringEncodingGetFromICUName(const char
         name = ucnv_getStandardName(icuName, "WINDOWS", &errorCode);
         
         if (NULL != name) {
-            if ((0 == strncasecmp_l(name, "windows-", strlen("windows-"), NULL)) && (0 != (codepage = strtol(name + strlen("windows-"), NULL, 10)))) return __CFStringEncodingGetFromWindowsCodePage(codepage);
+            if ((0 == strncasecmp_l(name, "windows-", strlen("windows-"), NULL)) && (0 != (codepage = strtol(name + strlen("windows-"), &endPtr, 10))) && (*endPtr == '\0')) return __CFStringEncodingGetFromWindowsCodePage(codepage);
             
             if (strncasecmp_l(icuName, name, strlen(name), NULL) && (kCFStringEncodingInvalidId != (encoding = __CFStringEncodingGetFromCanonicalName(name)))) return encoding;
         }
@@ -238,14 +239,17 @@ static CFIndex __CFStringEncodingConverterReleaseICUConverter(UConverter *conver
 #define MAX_BUFFER_SIZE (1000)
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if 0
+// we're no longer doing this check. Revive when the status in the bug changed.
 #if (U_ICU_VERSION_MAJOR_NUM > 49)
 #warning Unknown ICU version. Check binary compatibility issues for rdar://problem/6024743
 #endif
 #endif
+#endif
 #define HAS_ICU_BUG_6024743 (1)
 #define HAS_ICU_BUG_6025527 (1)
 
-__private_extern__ CFIndex __CFStringEncodingICUToBytes(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+CF_PRIVATE CFIndex __CFStringEncodingICUToBytes(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
     UConverter *converter;
     UErrorCode errorCode = U_ZERO_ERROR;
     const UTF16Char *source = characters;
@@ -347,7 +351,7 @@ __private_extern__ CFIndex __CFStringEncodingICUToBytes(const char *icuName, uin
     return status;
 }
 
-__private_extern__ CFIndex __CFStringEncodingICUToUnicode(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) {
+CF_PRIVATE CFIndex __CFStringEncodingICUToUnicode(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) {
     UConverter *converter;
     UErrorCode errorCode = U_ZERO_ERROR;
     const char *source = (const char *)bytes;
@@ -418,17 +422,17 @@ __private_extern__ CFIndex __CFStringEncodingICUToUnicode(const char *icuName, u
     return status;
 }
 
-__private_extern__ CFIndex __CFStringEncodingICUCharLength(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
+CF_PRIVATE CFIndex __CFStringEncodingICUCharLength(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
     CFIndex usedCharLen;
     return (__CFStringEncodingICUToUnicode(icuName, flags, bytes, numBytes, NULL, NULL, 0, &usedCharLen) == kCFStringEncodingConversionSuccess ? usedCharLen : 0);
 }
 
-__private_extern__ CFIndex __CFStringEncodingICUByteLength(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars) {
+CF_PRIVATE CFIndex __CFStringEncodingICUByteLength(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars) {
     CFIndex usedByteLen;
     return (__CFStringEncodingICUToBytes(icuName, flags, characters, numChars, NULL, NULL, 0, &usedByteLen) == kCFStringEncodingConversionSuccess ? usedByteLen : 0);
 }
 
-__private_extern__ CFStringEncoding *__CFStringEncodingCreateICUEncodings(CFAllocatorRef allocator, CFIndex *numberOfIndex) {
+CF_PRIVATE CFStringEncoding *__CFStringEncodingCreateICUEncodings(CFAllocatorRef allocator, CFIndex *numberOfIndex) {
     CFIndex count = ucnv_countAvailable();
     CFIndex numEncodings = 0;
     CFStringEncoding *encodings;
index cffc26cbd38e684b75066f478a2c03de371398b5..9d1cfefac97121043c5e62802381f535af3011d6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *  CoreFoundation
  *
  *  Created by Aki Inoue on 07/12/04.
- *  Copyright (c) 2007-2012, Apple Inc. All rights reserved.
+ *  Copyright (c) 2007-2013, Apple Inc. All rights reserved.
  *
  */
 
 #include <CoreFoundation/CFString.h>
 
-__private_extern__ const char *__CFStringEncodingGetICUName(CFStringEncoding encoding);
+CF_PRIVATE const char *__CFStringEncodingGetICUName(CFStringEncoding encoding);
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromICUName(const char *icuName);
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromICUName(const char *icuName);
 
 
-__private_extern__ CFIndex __CFStringEncodingICUToBytes(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen);
-__private_extern__ CFIndex __CFStringEncodingICUToUnicode(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen);
-__private_extern__ CFIndex __CFStringEncodingICUCharLength(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes);
-__private_extern__ CFIndex __CFStringEncodingICUByteLength(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars);
+CF_PRIVATE CFIndex __CFStringEncodingICUToBytes(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen);
+CF_PRIVATE CFIndex __CFStringEncodingICUToUnicode(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen);
+CF_PRIVATE CFIndex __CFStringEncodingICUCharLength(const char *icuName, uint32_t flags, const uint8_t *bytes, CFIndex numBytes);
+CF_PRIVATE CFIndex __CFStringEncodingICUByteLength(const char *icuName, uint32_t flags, const UniChar *characters, CFIndex numChars);
 
 // The caller is responsible for freeing the memory (use CFAllocatorDeallocate)
-__private_extern__ CFStringEncoding *__CFStringEncodingCreateICUEncodings(CFAllocatorRef allocator, CFIndex *numberOfIndex);
+CF_PRIVATE CFStringEncoding *__CFStringEncodingCreateICUEncodings(CFAllocatorRef allocator, CFIndex *numberOfIndex);
 
 
diff --git a/CFICULogging.h b/CFICULogging.h
new file mode 100644 (file)
index 0000000..8673e85
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+/*
+    CFICULogging.h
+    Copyright (c) 2008-2013, Apple Inc. All rights reserved.
+*/
+
+/*
+ This file is for the use of the CoreFoundation project only.
+*/
+
+#if !defined(__COREFOUNDATION_CFICULOGGING__)
+#define __COREFOUNDATION_CFICULOGGING__ 1
+
+#include <unicode/ucal.h>
+#include <unicode/udatpg.h>
+#include <unicode/udat.h>
+#include <unicode/unum.h>
+#include <unicode/ucurr.h>
+#include <unicode/ustring.h>
+
+// ucal
+
+
+#define __cficu_ucal_open ucal_open
+#define __cficu_ucal_close ucal_close
+#define __cficu_ucal_clone ucal_clone
+#define __cficu_ucal_setAttribute ucal_setAttribute
+#define __cficu_ucal_getAttribute ucal_getAttribute
+#define __cficu_ucal_setGregorianChange ucal_setGregorianChange
+#define __cficu_ucal_getGregorianChange ucal_getGregorianChange
+#define __cficu_ucal_getMillis ucal_getMillis
+#define __cficu_ucal_setMillis ucal_setMillis
+#define __cficu_ucal_set ucal_set
+#define __cficu_ucal_get ucal_get
+#define __cficu_ucal_getDayOfWeekType ucal_getDayOfWeekType
+#define __cficu_ucal_getWeekendTransition ucal_getWeekendTransition
+#define __cficu_ucal_isWeekend ucal_isWeekend
+#define __cficu_ucal_clear ucal_clear
+#define __cficu_ucal_getLimit ucal_getLimit
+#define __cficu_ucal_add ucal_add
+#define __cficu_ucal_roll ucal_roll
+#define __cficu_ucal_getFieldDifference ucal_getFieldDifference
+#define __cficu_ucal_getNow ucal_getNow
+#define __cficu_ucal_setTimeZone ucal_setTimeZone
+// udatpg
+#define __cficu_udatpg_open udatpg_open
+#define __cficu_udatpg_close udatpg_close
+#define __cficu_udatpg_getSkeleton udatpg_getSkeleton
+#define __cficu_udatpg_getBestPattern udatpg_getBestPattern
+// udat
+#define __cficu_udat_applyPattern udat_applyPattern
+#define __cficu_udat_applyPatternRelative udat_applyPatternRelative
+#define __cficu_udat_clone udat_clone
+#define __cficu_udat_close udat_close
+#define __cficu_udat_countSymbols udat_countSymbols
+#define __cficu_udat_format udat_format
+#define __cficu_udat_get2DigitYearStart udat_get2DigitYearStart
+#define __cficu_udat_getCalendar udat_getCalendar
+#define __cficu_udat_getSymbols udat_getSymbols
+#define __cficu_udat_isLenient udat_isLenient
+#define __cficu_udat_open udat_open
+#define __cficu_udat_parseCalendar udat_parseCalendar
+#define __cficu_udat_set2DigitYearStart udat_set2DigitYearStart
+#define __cficu_udat_setCalendar udat_setCalendar
+#define __cficu_udat_setLenient udat_setLenient
+#define __cficu_udat_setSymbols udat_setSymbols
+#define __cficu_udat_toPattern udat_toPattern
+#define __cficu_udat_toPatternRelativeDate udat_toPatternRelativeDate
+#define __cficu_udat_toPatternRelativeTime udat_toPatternRelativeTime
+#define __cficu_unum_applyPattern unum_applyPattern
+#define __cficu_unum_close unum_close
+#define __cficu_unum_formatDecimal unum_formatDecimal
+#define __cficu_unum_formatDouble unum_formatDouble
+#define __cficu_unum_getAttribute unum_getAttribute
+#define __cficu_unum_getDoubleAttribute unum_getDoubleAttribute
+#define __cficu_unum_getSymbol unum_getSymbol
+#define __cficu_unum_getTextAttribute unum_getTextAttribute
+#define __cficu_unum_open unum_open
+#define __cficu_unum_parse unum_parse
+#define __cficu_unum_parseDecimal unum_parseDecimal
+#define __cficu_unum_setAttribute unum_setAttribute
+#define __cficu_unum_setDoubleAttribute unum_setDoubleAttribute
+#define __cficu_unum_setSymbol unum_setSymbol
+#define __cficu_unum_setTextAttribute unum_setTextAttribute
+#define __cficu_unum_toPattern unum_toPattern
+
+// ucurr
+
+#define __cficu_ucurr_getDefaultFractionDigits ucurr_getDefaultFractionDigits
+#define __cficu_ucurr_getRoundingIncrement ucurr_getRoundingIncrement
+
+
+#endif
index dffc01683810a0a5f62ad55bd6fcb5fa717100cb..2204025feda6beee279ec4853afa58b7d6b8b80c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFInternal.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*
@@ -36,6 +36,7 @@
 #if !defined(__COREFOUNDATION_CFINTERNAL__)
 #define __COREFOUNDATION_CFINTERNAL__ 1
 
+
 #define __CF_COMPILE_YEAR__    (__DATE__[7] * 1000 + __DATE__[8] * 100 + __DATE__[9] * 10 + __DATE__[10] - 53328)
 #define __CF_COMPILE_MONTH__   ((__DATE__[1] + __DATE__[2] == 207) ? 1 : \
                                 (__DATE__[1] + __DATE__[2] == 199) ? 2 : \
@@ -92,6 +93,7 @@ CF_EXTERN_C_BEGIN
 #include <unistd.h>
 #include <sys/time.h>
 #include <signal.h>
+#include <stdio.h>
 #endif
 #include <pthread.h>
 
@@ -123,13 +125,26 @@ CF_EXPORT CFStringRef _CFStringCreateHostName(void);
 CF_EXPORT void _CFMachPortInstallNotifyPort(CFRunLoopRef rl, CFStringRef mode);
 #endif
 
-__private_extern__ CFIndex __CFActiveProcessorCount();
+
+CF_PRIVATE CFIndex __CFActiveProcessorCount();
+
+#ifndef CLANG_ANALYZER_NORETURN
+#if __has_feature(attribute_analyzer_noreturn)
+#define CLANG_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+#else
+#define CLANG_ANALYZER_NORETURN
+#endif
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#define __builtin_unreachable() do { } while (0)
+#endif
 
 #if defined(__i386__) || defined(__x86_64__)
     #if defined(__GNUC__)
-        #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); } while (0)
+        #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); __builtin_unreachable(); } while (0)
     #elif defined(_MSC_VER)
-        #define HALT do { DebugBreak(); abort(); } while (0)
+        #define HALT do { DebugBreak(); abort(); __builtin_unreachable(); } while (0)
     #else
         #error Compiler not supported
     #endif
@@ -163,7 +178,7 @@ __private_extern__ CFIndex __CFActiveProcessorCount();
 #define __kCFLogAssertion      3
 
 // This CF-only log function uses no CF functionality, so it may be called anywhere within CF - including thread teardown or prior to full CF setup
-__private_extern__ void _CFLogSimple(int32_t lev, char *format, ...);
+CF_PRIVATE void _CFLogSimple(int32_t lev, char *format, ...);
 
 #if defined(DEBUG)
 extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func);
@@ -200,6 +215,7 @@ enum {
        __CFTSDKeyCollatorUCollator = 9,
        __CFTSDKeyRunLoop = 10,
        __CFTSDKeyRunLoopCntr = 11,
+        __CFTSDKeyMachMessageBoost = 12, // valid only in the context of a CFMachPort callout
        // autorelease pool stuff must be higher than run loop constants
        __CFTSDKeyAutoreleaseData2 = 61,
        __CFTSDKeyAutoreleaseData1 = 62,
@@ -270,16 +286,20 @@ CF_EXPORT void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr);
 
 CF_EXPORT CFAllocatorRef _CFTemporaryMemoryAllocator(void);
 
-extern SInt64 __CFTimeIntervalToTSR(CFTimeInterval ti);
-extern CFTimeInterval __CFTSRToTimeInterval(SInt64 tsr);
+extern uint64_t __CFTimeIntervalToTSR(CFTimeInterval ti);
+extern CFTimeInterval __CFTSRToTimeInterval(uint64_t tsr);
+// use this instead of attempting to subtract mach_absolute_time() directly, because that can underflow and give an unexpected answer
+CF_PRIVATE CFTimeInterval __CFTimeIntervalUntilTSR(uint64_t tsr);
+CF_PRIVATE dispatch_time_t __CFTSRToDispatchTime(uint64_t tsr);
+CF_PRIVATE uint64_t __CFTSRToNanoseconds(uint64_t tsr);
 
 extern CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions);
 
 /* Enhanced string formatting support
  */
-__private_extern__ CFDictionaryRef _CFStringGetFormatSpecifierConfiguration(CFStringRef aFormatString);
-__private_extern__ CFStringRef _CFStringCopyWithFomatStringConfiguration(CFStringRef aFormatString, CFDictionaryRef formatConfiguration);
-__private_extern__ CFStringRef _CFCopyResolvedFormatStringWithConfiguration(CFTypeRef anObject, CFDictionaryRef aConfiguration, CFDictionaryRef formatOptions);
+CF_PRIVATE CFDictionaryRef _CFStringGetFormatSpecifierConfiguration(CFStringRef aFormatString);
+CF_PRIVATE CFStringRef _CFStringCopyWithFomatStringConfiguration(CFStringRef aFormatString, CFDictionaryRef formatConfiguration);
+CF_PRIVATE CFStringRef _CFCopyResolvedFormatStringWithConfiguration(CFTypeRef anObject, CFDictionaryRef aConfiguration, CFDictionaryRef formatOptions);
 
 /* result is long long or int, depending on doLonglong
 */
@@ -289,6 +309,8 @@ extern Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, un
 
 extern const char *__CFgetenv(const char *n);
 
+CF_PRIVATE Boolean __CFProcessIsRestricted();
+
 // This is really about the availability of C99. We don't have that on Windows, but we should everywhere else.
 #if DEPLOYMENT_TARGET_WINDOWS
 #define STACK_BUFFER_DECL(T, N, C) T *N = (T *)_alloca((C) * sizeof(T))
@@ -302,7 +324,7 @@ CF_EXPORT void * __CFConstantStringClassReferencePtr;
 #ifdef __CONSTANT_CFSTRINGS__
 
 #define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
-#define PE_CONST_STRING_DECL(S, V) __private_extern__ const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
+#define PE_CONST_STRING_DECL(S, V) CF_PRIVATE const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
 
 #else
 
@@ -323,7 +345,7 @@ static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringCl
 const CFStringRef S = (CFStringRef) & __ ## S ## __;
 #define PE_CONST_STRING_DECL(S, V)                     \
 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
-__private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
+CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __;
 
 #elif __CF_LITTLE_ENDIAN__
 
@@ -332,7 +354,7 @@ static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringCl
 const CFStringRef S = (CFStringRef) & __ ## S ## __;
 #define PE_CONST_STRING_DECL(S, V)                     \
 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
-__private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
+CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __;
 
 #endif
 
@@ -350,7 +372,7 @@ CF_EXPORT CFHashCode        CFHashBytes(UInt8 *bytes, CFIndex length);
 
 CF_EXPORT CFStringEncoding CFStringFileSystemEncoding(void);
 
-__private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(CFAllocatorRef alloc, const void *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean possiblyExternalFormat, Boolean tryToReduceUnicode, Boolean hasLengthByte, Boolean hasNullByte, Boolean noCopy, CFAllocatorRef contentsDeallocator, UInt32 converterFlags);
+CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3(CFAllocatorRef alloc, const void *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean possiblyExternalFormat, Boolean tryToReduceUnicode, Boolean hasLengthByte, Boolean hasNullByte, Boolean noCopy, CFAllocatorRef contentsDeallocator, UInt32 converterFlags);
 
 extern const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr);
 extern const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr);
@@ -358,9 +380,9 @@ extern void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr)
 
 extern CFTypeRef CFMakeUncollectable(CFTypeRef cf);
 
-__private_extern__ void _CFRaiseMemoryException(CFStringRef reason);
+CF_PRIVATE void _CFRaiseMemoryException(CFStringRef reason);
 
-__private_extern__ Boolean __CFProphylacticAutofsAccess;
+CF_PRIVATE Boolean __CFProphylacticAutofsAccess;
 
 
 #if DEPLOYMENT_TARGET_MACOSX
@@ -515,111 +537,63 @@ CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void
 
 CF_EXPORT Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length);
 
-CF_EXPORT CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType);
+CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType);
     /* On Mac OS 8/9, one of dirSpec, dirPath and dirURL must be non-NULL */
     /* On all other platforms, one of path and dirURL must be non-NULL */
     /* If both are present, they are assumed to be in-synch; that is, they both refer to the same directory.  */
     /* alloc may be NULL */
     /* return value is CFArray of CFURLs */
 
-CF_EXPORT SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
+CF_PRIVATE SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
     /* alloc may be NULL */
     /* any of exists, posixMode, size, modTime, and dirContents can be NULL.  Usually it is not a good idea to pass NULL for exists, since interpretting the other values sometimes requires that you know whether the file existed or not.  Except for dirContents, it is pretty cheap to compute any of these things as loing as one of them must be computed. */
 
-CF_EXPORT SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
+CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
     /* alloc may be NULL */
     /* any of exists, posixMode, size, modTime, and dirContents can be NULL.  Usually it is not a good idea to pass NULL for exists, since interpretting the other values sometimes requires that you know whether the file existed or not.  Except for dirContents, it is pretty cheap to compute any of these things as loing as one of them must be computed. */
 
 
 /* ==================== Simple path manipulation ==================== */
-/* These functions all act on a UniChar buffers. */
 
 CF_EXPORT UniChar _CFGetSlash();
+CF_PRIVATE CFStringRef _CFGetSlashStr();
 CF_EXPORT Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length);
-CF_EXPORT Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length);
-__private_extern__ Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex *length, CFIndex maxLength);
+CF_PRIVATE void _CFAppendTrailingPathSlash2(CFMutableStringRef path);
+CF_PRIVATE void _CFAppendConditionalTrailingPathSlash2(CFMutableStringRef path);
 CF_EXPORT Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength);
+CF_PRIVATE void _CFAppendPathComponent2(CFMutableStringRef path, CFStringRef component);
+CF_PRIVATE Boolean _CFAppendPathExtension2(CFMutableStringRef path, CFStringRef extension);
 CF_EXPORT Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength);
 CF_EXPORT Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash);
+CF_PRIVATE CFStringRef _CFCreateLastPathComponent(CFAllocatorRef alloc, CFStringRef path, CFIndex *slashIndex);
 CF_EXPORT CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length);
+CF_PRIVATE CFIndex _CFStartOfLastPathComponent2(CFStringRef path);
 CF_EXPORT CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length);
+CF_PRIVATE CFIndex _CFLengthAfterDeletingPathExtension2(CFStringRef path);
 CF_EXPORT CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length);
+CF_PRIVATE CFIndex _CFStartOfPathExtension2(CFStringRef path);
 CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length);
 
-#define __CFMaxRuntimeTypes    65535
-
-// Tagged pointer support
-// Low-bit set means tagged object, next 3 bits (currently)
-// define the tagged object class, next 4 bits are for type
-// information for the specific tagged object class.  Thus,
-// the low byte is for type info, and the rest of a pointer
-// (32 or 64-bit) is for payload, whatever the tagged class.
-//
-// Note that the specific integers used to identify the
-// specific tagged classes can and will change from release
-// to release (that's why this stuff is in CF*Internal*.h),
-// as can the definition of type info vs payload above.
-//
-#if __LP64__
-#define CF_IS_TAGGED_OBJ(PTR)  ((uintptr_t)(PTR) & 0x1)
-#define CF_TAGGED_OBJ_TYPE(PTR)        ((uintptr_t)(PTR) & 0xF)
-#else
-#define CF_IS_TAGGED_OBJ(PTR)  0
-#define CF_TAGGED_OBJ_TYPE(PTR)        0
+#if __BLOCKS__
+#if DEPLOYMENT_TARGET_WINDOWS
+#define        DT_DIR           4
+#define        DT_REG           8
+#define DT_LNK          10
 #endif
-enum {
-    kCFTaggedObjectID_Invalid = 0,
-    kCFTaggedObjectID_Atom = (0 << 1) + 1,
-    kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
-    kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
-    kCFTaggedObjectID_Integer = (3 << 1) + 1,
-    kCFTaggedObjectID_DateTS = (4 << 1) + 1,
-    kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
-    kCFTaggedObjectID_Date = (6 << 1) + 1,
-    kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
-};
 
+// This function automatically skips '.' and '..', and '._' files
+CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean (^fileHandler)(CFStringRef fileName, uint8_t fileType));
+#endif
 
+#define __CFMaxRuntimeTypes    65535
 #define __CFRuntimeClassTableSize 1024
 
-extern uintptr_t __CFRuntimeObjCClassTable[];
-CF_INLINE uintptr_t __CFISAForTypeID(CFTypeID typeID) {
-    return (typeID < __CFRuntimeClassTableSize) ? __CFRuntimeObjCClassTable[typeID] : 0;
-}
-
-CF_INLINE Boolean CF_IS_OBJC(CFTypeID typeID, const void *obj) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
-    if (CF_IS_TAGGED_OBJ(obj)) return true;
-    uintptr_t cfisa = ((CFRuntimeBase *)obj)->_cfisa;
-    if (cfisa == 0) return false;
-#if 0
-    // Temporarily disabled
-#if __LP64__
-    if (cfisa < 0x10000000UL) {
-        CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
-        return false;
-    }
-#else
-    if (cfisa < 0x1000UL) {
-        CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
-        return false;
-    }
-#endif
-#endif
-    if (cfisa == (uintptr_t)__CFConstantStringClassReferencePtr) return false;
-    uintptr_t type_isa = (uintptr_t)(typeID < __CFRuntimeClassTableSize ? __CFRuntimeObjCClassTable[typeID] : 0);
-    if (cfisa == type_isa) return false;
-    return true;
-#else
-    return false;
-#endif
-}
-
+extern void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID);
 
 #define CF_OBJC_FUNCDISPATCHV(typeID, obj, ...) do { } while (0)
 #define CF_OBJC_CALLV(obj, ...) (0)
-
+#define CF_IS_OBJC(typeID, obj) (0)
+#define __CFISAForTypeID(t) (0)
 
 /* See comments in CFBase.c
 */
@@ -703,19 +677,21 @@ extern void *__CFLookupCoreServicesInternalFunction(const char *name);
 #define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...)
 #endif
 
-__private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale);
+CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale);
 
 
-__private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops);
+CF_PRIVATE CFArrayRef _CFBundleCopyUserLanguages();
 
 
 // This should only be used in CF types, not toll-free bridged objects!
 // It should not be used with CFAllocator arguments!
 // Use CFGetAllocator() in the general case, and this inline function in a few limited (but often called) situations.
 CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) {      // !!! Use with CF types only, and NOT WITH CFAllocator!
-    if (CF_IS_TAGGED_OBJ(cf)) {
+#if OBJC_HAVE_TAGGED_POINTERS
+    if (_objc_isTaggedPointer(cf)) {
         return kCFAllocatorSystemDefault;
     }
+#endif
     if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7), 1)) {
        return kCFAllocatorSystemDefault;
     }
@@ -730,8 +706,10 @@ struct __objcFastEnumerationStateEquivalent {
     unsigned long extra[5];
 };
 
+#if 0
 #pragma mark -
 #pragma mark Windows Compatability
+#endif
 
 // Need to use the _O_BINARY flag on Windows to get the correct behavior
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -764,7 +742,7 @@ CF_EXPORT void _NS_pthread_setname_np(const char *name);
 #endif
 
 #if DEPLOYMENT_TARGET_WINDOWS
-__private_extern__ const wchar_t *_CFDLLPath(void);
+CF_PRIVATE const wchar_t *_CFDLLPath(void);
 #endif
 
 /* Buffer size for file pathname */
@@ -781,6 +759,24 @@ __private_extern__ const wchar_t *_CFDLLPath(void);
 #define PATH_SEP_STR CFSTR("/")
 #endif
 
+CF_INLINE const char *CFPathRelativeToAppleFrameworksRoot(const char *path, Boolean *allocated) {
+    if (path) {
+        const char *platformRoot = __CFgetenv("APPLE_FRAMEWORKS_ROOT");
+        if (platformRoot) {
+            char *newPath = NULL;
+            asprintf(&newPath, "%s%s", platformRoot, path);
+            if (allocated && newPath) {
+                *allocated = true;
+            }
+            return newPath;
+        }
+    }
+    if (allocated) {
+        *allocated = false;
+    }
+    return path;
+}
+
 CF_EXTERN_C_END
 
 #endif /* ! __COREFOUNDATION_CFINTERNAL__ */
index d6eb54d140bfe6dba89f295d01a3fa09d2ff3958..b9a840c33a727a619cc206fcfe48e8c2c1330a8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*  CFLocale.c
-    Copyright (c) 2002-2012, Apple Inc. All rights reserved.
+    Copyright (c) 2002-2013, Apple Inc. All rights reserved.
     Responsibility: David Smith
 */
 
@@ -154,11 +154,11 @@ struct __CFLocale {
     Boolean _nullLocale;
 };
  
-__private_extern__ Boolean __CFLocaleGetNullLocale(struct __CFLocale *locale) {
+CF_PRIVATE Boolean __CFLocaleGetNullLocale(struct __CFLocale *locale) {
     return locale->_nullLocale;
 }
 
-__private_extern__ void __CFLocaleSetNullLocale(struct __CFLocale *locale) {
+CF_PRIVATE void __CFLocaleSetNullLocale(struct __CFLocale *locale) {
     locale->_nullLocale = true;
 }
 
@@ -299,72 +299,97 @@ static CFLocaleRef __CFLocaleCurrent = NULL;
 #define FALLBACK_LOCALE_NAME CFSTR("en_US")
 #endif
 
-CFLocaleRef CFLocaleCopyCurrent(void) {
-
-    CFStringRef name = NULL, ident = NULL;
+static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, CFDictionaryRef overridePrefs) {
+    
+    CFStringRef ident = NULL;
     // We cannot be helpful here, because it causes performance problems,
     // even though the preference lookup is relatively quick, as there are
     // things which call this function thousands or millions of times in
     // a short period.
+    if (!name) {
 #if 0 // DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
-    name = (CFStringRef)CFPreferencesCopyAppValue(CFSTR("AppleLocale"), kCFPreferencesCurrentApplication);
+        name = (CFStringRef)CFPreferencesCopyAppValue(CFSTR("AppleLocale"), kCFPreferencesCurrentApplication);
 #endif
+    } else {
+        CFRetain(name);
+    }
     if (name && (CFStringGetTypeID() == CFGetTypeID(name))) {
         ident = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, name);
     }
     if (name) CFRelease(name);
-    CFLocaleRef oldLocale = NULL;
-    __CFLocaleLockGlobal();
-    if (__CFLocaleCurrent) {
-        if (ident && !CFEqual(__CFLocaleCurrent->_identifier, ident)) {
-           oldLocale = __CFLocaleCurrent;
-           __CFLocaleCurrent = NULL;
-        } else {
-            CFLocaleRef res = __CFLocaleCurrent;
-            CFRetain(res);
-            __CFLocaleUnlockGlobal();
-            if (ident) CFRelease(ident);
-            return res;
-       }
+    
+    if (useCache) {
+        CFLocaleRef oldLocale = NULL;
+        __CFLocaleLockGlobal();
+        if (__CFLocaleCurrent) {
+            if (ident && !CFEqual(__CFLocaleCurrent->_identifier, ident)) {
+                oldLocale = __CFLocaleCurrent;
+                __CFLocaleCurrent = NULL;
+            } else {
+                CFLocaleRef res = __CFLocaleCurrent;
+                CFRetain(res);
+                __CFLocaleUnlockGlobal();
+                if (ident) CFRelease(ident);
+                return res;
+            }
+        }
+        __CFLocaleUnlockGlobal();
+        if (oldLocale) CFRelease(oldLocale);
     }
-    __CFLocaleUnlockGlobal();
-    if (oldLocale) CFRelease(oldLocale);
-    if (ident) CFRelease(ident);
-    // We could *probably* re-use ident down below, but that would't
-    // get us out of querying CFPrefs for the current application state.
-
+    
     CFDictionaryRef prefs = NULL;
-    CFStringRef identifier = NULL;
     
     struct __CFLocale *locale;
     uint32_t size = sizeof(struct __CFLocale) - sizeof(CFRuntimeBase);
     locale = (struct __CFLocale *)_CFRuntimeCreateInstance(kCFAllocatorSystemDefault, CFLocaleGetTypeID(), size, NULL);
     if (NULL == locale) {
        if (prefs) CFRelease(prefs);
-       if (identifier) CFRelease(identifier);
+       if (ident) CFRelease(ident);
        return NULL;
     }
     __CFLocaleSetType(locale, __kCFLocaleUser);
-    if (NULL == identifier) identifier = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME);
-    locale->_identifier = identifier;
+    if (NULL == ident) ident = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME);
+    locale->_identifier = ident;
     locale->_cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
     locale->_overrides = NULL;
     locale->_prefs = prefs;
     locale->_lock = CFSpinLockInit;
     locale->_nullLocale = false;
-
-    __CFLocaleLockGlobal();
-    if (NULL == __CFLocaleCurrent) {
-       __CFLocaleCurrent = locale;
-    } else {
-       CFRelease(locale);
+    
+    if (useCache) {
+        __CFLocaleLockGlobal();
+        if (NULL == __CFLocaleCurrent) {
+            __CFLocaleCurrent = locale;
+        } else {
+            CFRelease(locale);
+        }
+        locale = (struct __CFLocale *)CFRetain(__CFLocaleCurrent);
+        __CFLocaleUnlockGlobal();
     }
-    locale = (struct __CFLocale *)CFRetain(__CFLocaleCurrent);
-    __CFLocaleUnlockGlobal();
     return locale;
 }
 
-__private_extern__ CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale) {
+/*
+ <rdar://problem/13834276> NSDateFormatter: Cannot specify force12HourTime/force24HourTime
+ This returns an instance of CFLocale that's set up exactly like it would be if the user changed the current locale to that identifier, then called CFLocaleCopyCurrent()
+ */
+CFLocaleRef _CFLocaleCopyAsIfCurrent(CFStringRef name) {
+    return _CFLocaleCopyCurrentGuts(name, false, NULL);
+}
+
+/*
+ <rdar://problem/14032388> Need the ability to initialize a CFLocaleRef from a preferences dictionary
+ This returns an instance of CFLocale that's set up exactly like it would be if the user changed the current locale to that identifier, set the preferences keys in the overrides dictionary, then called CFLocaleCopyCurrent()
+ */
+CFLocaleRef _CFLocaleCopyAsIfCurrentWithOverrides(CFStringRef name, CFDictionaryRef overrides) {
+    return _CFLocaleCopyCurrentGuts(name, false, overrides);
+}
+
+CFLocaleRef CFLocaleCopyCurrent(void) {
+    return _CFLocaleCopyCurrentGuts(NULL, true, NULL);
+}
+
+CF_PRIVATE CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale) {
     CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFDictionaryRef, (NSLocale *)locale, _prefs);
     return locale->_prefs;
 }
index 3f575fc4611be8cf7b33e6181daa147d9f23c6e1..b8d3383765cd64e08d8ceed13797fdd82b4ec713 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFLocale.h
-       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFLOCALE__)
index 48bc702f33571d3cfb4f832386bc150a80c2fdc6..496c9078665ba133d0c248b758c77d7ed77cc1d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -23,7 +23,7 @@
 
 /*
     CFLocaleIdentifier.c
-       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2013, Apple Inc. All rights reserved.
     Responsibility: David Smith
     
     CFLocaleIdentifier.c defines
index c1b5b982be51a94e865950affa4abcbd963c7c6b..7b0134ae1fc1a2688f5a88ca786d066cc5323939 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -23,7 +23,7 @@
 
 /*     
  CFLocaleInternal.h
- Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+ Copyright (c) 2008-2013, Apple Inc. All rights reserved.
  */
 
 /*
@@ -83,6 +83,7 @@ CF_EXPORT CFStringRef const kCFDateFormatterVeryShortStandaloneMonthSymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterVeryShortStandaloneWeekdaySymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterVeryShortWeekdaySymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterWeekdaySymbolsKey;
+CF_EXPORT CFStringRef const kCFDateFormatterUsesCharacterDirectionKey;
 
 CF_EXPORT CFStringRef const kCFNumberFormatterAlwaysShowDecimalSeparatorKey;
 CF_EXPORT CFStringRef const kCFNumberFormatterCurrencyCodeKey;
@@ -122,6 +123,7 @@ CF_EXPORT CFStringRef const kCFNumberFormatterSecondaryGroupingSizeKey;
 CF_EXPORT CFStringRef const kCFNumberFormatterUseGroupingSeparatorKey;
 CF_EXPORT CFStringRef const kCFNumberFormatterUseSignificantDigitsKey;
 CF_EXPORT CFStringRef const kCFNumberFormatterZeroSymbolKey;
+CF_EXPORT CFStringRef const kCFNumberFormatterUsesCharacterDirectionKey;
 
 CF_EXPORT CFStringRef const kCFCalendarIdentifierGregorian;
 CF_EXPORT CFStringRef const kCFCalendarIdentifierBuddhist;
index 425c9af74da8095c4efd573c80ed1b0e0a40f744..6d79c897ce4c6bc7bfdbed7bc10106b870c4bd63 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFLocaleKeys.c
-       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -80,6 +80,7 @@ CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneMonthSymbolsKey, "kCFDateFo
 CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneWeekdaySymbolsKey, "kCFDateFormatterVeryShortStandaloneWeekdaySymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterVeryShortWeekdaySymbolsKey, "kCFDateFormatterVeryShortWeekdaySymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterWeekdaySymbolsKey, "kCFDateFormatterWeekdaySymbolsKey");
+CONST_STRING_DECL(kCFDateFormatterUsesCharacterDirectionKey, "kCFDateFormatterUsesCharacterDirectionKey");
 
 CONST_STRING_DECL(kCFNumberFormatterAlwaysShowDecimalSeparatorKey, "kCFNumberFormatterAlwaysShowDecimalSeparatorKey");
 CONST_STRING_DECL(kCFNumberFormatterCurrencyCodeKey, "kCFNumberFormatterCurrencyCodeKey");
@@ -119,6 +120,7 @@ CONST_STRING_DECL(kCFNumberFormatterSecondaryGroupingSizeKey, "kCFNumberFormatte
 CONST_STRING_DECL(kCFNumberFormatterUseGroupingSeparatorKey, "kCFNumberFormatterUseGroupingSeparatorKey");
 CONST_STRING_DECL(kCFNumberFormatterUseSignificantDigitsKey, "kCFNumberFormatterUseSignificantDigitsKey");
 CONST_STRING_DECL(kCFNumberFormatterZeroSymbolKey, "kCFNumberFormatterZeroSymbolKey");
+CONST_STRING_DECL(kCFNumberFormatterUsesCharacterDirectionKey, "kCFNumberFormatterUsesCharacterDirectionKey");
 
 CONST_STRING_DECL(kCFCalendarIdentifierGregorian, "gregorian");
 CONST_STRING_DECL(kCFCalendarIdentifierBuddhist, "buddhist");
@@ -233,6 +235,8 @@ CF_EXPORT CFStringRef const kCFNumberFormatterSecondaryGroupingSize __attribute_
 CF_EXPORT CFStringRef const kCFNumberFormatterUseGroupingSeparator __attribute__((alias ("kCFNumberFormatterUseGroupingSeparatorKey")));
 CF_EXPORT CFStringRef const kCFNumberFormatterUseSignificantDigits __attribute__((alias ("kCFNumberFormatterUseSignificantDigitsKey")));
 CF_EXPORT CFStringRef const kCFNumberFormatterZeroSymbol __attribute__((alias ("kCFNumberFormatterZeroSymbolKey")));
+CF_EXPORT CFStringRef const kCFNumberFormatterUsesCharacterDirection __attribute__((alias ("kCFNumberFormatterUsesCharacterDirectionKey")));
+CF_EXPORT CFStringRef const kCFDateFormatterUsesCharacterDirection __attribute__((alias ("kCFDateFormatterUsesCharacterDirectionKey")));
 CF_EXPORT CFStringRef const kCFDateFormatterCalendarName __attribute__((alias ("kCFDateFormatterCalendarIdentifierKey")));
 
 #endif
index b4b06239fd06acf9e1502e6e306ab9956e19a29b..896f4b2af0c636bf0dadf92e529feafc146f7cf3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFLogUtilities.h
-       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2013, Apple Inc. All rights reserved.
 */
 
 /*
index d5df91efd829b4dd578c9a1fa57eb3de94774dd4..a8479e199ca174b8ff0ac031ef48f2451b89ddc9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFMachPort.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -33,6 +33,7 @@
 #include <dispatch/private.h>
 #include <mach/mach.h>
 #include <dlfcn.h>
+#include <stdio.h>
 #include "CFInternal.h"
 
 
@@ -62,14 +63,14 @@ struct __CFMachPort {
     int32_t _state;
     mach_port_t _port;                          /* immutable */
     dispatch_source_t _dsrc;                    /* protected by _lock */
-    dispatch_source_t _dsrc2;                   /* protected by _lock */
     dispatch_semaphore_t _dsrc_sem;             /* protected by _lock */
-    dispatch_semaphore_t _dsrc2_sem;            /* protected by _lock */
     CFMachPortInvalidationCallBack _icallout;   /* protected by _lock */
     CFRunLoopSourceRef _source;                 /* immutable, once created */
     CFMachPortCallBack _callout;                /* immutable */
     CFMachPortContext _context;                 /* immutable */
     CFSpinLock_t _lock;
+    const void *(*retain)(const void *info); // use these to store the real callbacks
+    void        (*release)(const void *info);
 };
 
 /* Bit 1 in the base reserved bits is used for has-receive-ref state */
@@ -131,7 +132,7 @@ static CFStringRef __CFMachPortCopyDescription(CFTypeRef cf) {
     Dl_info info;
     void *addr = mp->_callout;
     const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
-    CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFMachPort %p [%p]>{valid = %s, port = %p, source = %p, callout = %s (%p), context = %@}"), cf, CFGetAllocator(mp), (__CFMachPortIsValid(mp) ? "Yes" : "No"), mp->_port, mp->_source, name, addr, contextDesc);
+    CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFMachPort %p [%p]>{valid = %s, port = %x, source = %p, callout = %s (%p), context = %@}"), cf, CFGetAllocator(mp), (__CFMachPortIsValid(mp) ? "Yes" : "No"), mp->_port, mp->_source, name, addr, contextDesc);
     if (NULL != contextDesc) {
         CFRelease(contextDesc);
     }
@@ -153,10 +154,11 @@ CF_INLINE void __CFMachPortInvalidateLocked(CFRunLoopSourceRef source, CFMachPor
         __CFSpinLock(&mp->_lock);
     }
     void *info = mp->_context.info;
+    void (*release)(const void *info) = mp->release;
     mp->_context.info = NULL;
-    if (mp->_context.release) {
+    if (release) {
         __CFSpinUnlock(&mp->_lock);
-        mp->_context.release(info);
+        release(info);
         __CFSpinLock(&mp->_lock);
     }
     mp->_state = kCFMachPortStateInvalid;
@@ -178,10 +180,6 @@ static void __CFMachPortDeallocate(CFTypeRef cf) {
             dispatch_source_cancel(mp->_dsrc);
             mp->_dsrc = NULL;
         }
-        if (mp->_dsrc2) {
-            dispatch_source_cancel(mp->_dsrc2);
-            mp->_dsrc2 = NULL;
-        }
         source = mp->_source;
         mp->_source = NULL;
     }    
@@ -193,7 +191,6 @@ static void __CFMachPortDeallocate(CFTypeRef cf) {
     // hand ownership of the port and semaphores to the block below
     mach_port_t port = mp->_port;
     dispatch_semaphore_t sem1 = mp->_dsrc_sem;
-    dispatch_semaphore_t sem2 = mp->_dsrc2_sem;
     Boolean doSend2 = __CFMachPortHasSend2(mp), doSend = __CFMachPortHasSend(mp), doReceive = __CFMachPortHasReceive(mp);
 
     __CFSpinUnlock(&mp->_lock);
@@ -204,11 +201,6 @@ static void __CFMachPortDeallocate(CFTypeRef cf) {
                 // immediate release is only safe if dispatch_semaphore_signal() does not touch the semaphore after doing the signal bit
                 dispatch_release(sem1);
             }
-            if (sem2) {
-                dispatch_semaphore_wait(sem2, DISPATCH_TIME_FOREVER);
-                // immediate release is only safe if dispatch_semaphore_signal() does not touch the semaphore after doing the signal bit
-                dispatch_release(sem2);
-            }
 
             // MUST deallocate the send right FIRST if necessary,
             // then the receive right if necessary.  Don't ask me why;
@@ -234,6 +226,7 @@ static CFMutableArrayRef __CFAllMachPorts = NULL;
 static __CFPointerArray *__CFAllMachPorts = nil;
 #endif
 
+static Boolean __CFMachPortCheck(mach_port_t) __attribute__((noinline));
 static Boolean __CFMachPortCheck(mach_port_t port) {
     mach_port_type_t type = 0;
     kern_return_t ret = mach_port_type(mach_task_self(), port, &type);
@@ -262,10 +255,6 @@ static void __CFMachPortChecker(Boolean fromTimer) {
                     dispatch_source_cancel(mp->_dsrc);
                     mp->_dsrc = NULL;
                 }
-                if (mp->_dsrc2) {
-                    dispatch_source_cancel(mp->_dsrc2);
-                    mp->_dsrc2 = NULL;
-                }
                 source = mp->_source;
                 mp->_source = NULL;
                 CFRetain(mp);
@@ -309,7 +298,7 @@ static const CFRuntimeClass __CFMachPortClass = {
     __CFMachPortCopyDescription
 };
 
-__private_extern__ void __CFMachPortInitialize(void) {
+CF_PRIVATE void __CFMachPortInitialize(void) {
     __kCFMachPortTypeID = _CFRuntimeRegisterClass(&__CFMachPortClass);
 }
 
@@ -337,10 +326,7 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
     static dispatch_source_t timerSource = NULL;
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
-        uint64_t nanos = 63 * 1000 * 1000 * 1000ULL;
-        uint64_t leeway = 9 * 1000ULL;
-        timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _CFMachPortQueue());
-        dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, nanos), nanos, leeway);
+        timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_INTERVAL, 60 * 1000 /* milliseconds */, 0, _CFMachPortQueue());
         dispatch_source_set_event_handler(timerSource, ^{
             __CFMachPortChecker(true);
         });
@@ -378,20 +364,24 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
         }
         memory->_port = port;
         memory->_dsrc = NULL;
-        memory->_dsrc2 = NULL;
         memory->_dsrc_sem = NULL;
-        memory->_dsrc2_sem = NULL;
         memory->_icallout = NULL;
         memory->_source = NULL;
         memory->_context.info = NULL;
         memory->_context.retain = NULL;
         memory->_context.release = NULL;
         memory->_context.copyDescription = NULL;
+        memory->retain = NULL;
+        memory->release = NULL;
         memory->_callout = callout;
         memory->_lock = CFSpinLockInit;
         if (NULL != context) {
             objc_memmove_collectable(&memory->_context, context, sizeof(CFMachPortContext));
             memory->_context.info = context->retain ? (void *)context->retain(context->info) : context->info;
+            memory->retain = context->retain;
+            memory->release = context->release;
+           memory->_context.retain = (void *)0xAAAAAAAAAACCCAAA;
+            memory->_context.release = (void *)0xAAAAAAAAAABBBAAA;
         }
         memory->_state = kCFMachPortStateReady;
         __CFSpinLock(&__CFAllMachPortsLock);
@@ -408,26 +398,14 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
 
         if (type & MACH_PORT_TYPE_SEND_RIGHTS) {
             dispatch_source_t theSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, port, DISPATCH_MACH_SEND_DEAD, _CFMachPortQueue());
-            dispatch_source_set_cancel_handler(theSource, ^{
-                dispatch_release(theSource);
-            });
-            dispatch_source_set_event_handler(theSource, ^{
-                __CFMachPortChecker(false);
-            });
-            memory->_dsrc = theSource;
-            dispatch_resume(theSource);
-        }
-        if (memory->_dsrc) {
-            dispatch_source_t source = memory->_dsrc; // put these in locals so they are fully copied into the block
-            dispatch_semaphore_t sem = dispatch_semaphore_create(0);
-            memory->_dsrc_sem = sem;
-            dispatch_source_set_cancel_handler(memory->_dsrc, ^{ dispatch_semaphore_signal(sem); dispatch_release(source); });
-        }
-        if (memory->_dsrc2) {
-            dispatch_source_t source = memory->_dsrc2;
-            dispatch_semaphore_t sem = dispatch_semaphore_create(0);
-            memory->_dsrc2_sem = sem;
-            dispatch_source_set_cancel_handler(memory->_dsrc2, ^{ dispatch_semaphore_signal(sem); dispatch_release(source); });
+           if (theSource) {
+                dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+                dispatch_source_set_cancel_handler(theSource, ^{ dispatch_semaphore_signal(sem); dispatch_release(theSource); });
+                dispatch_source_set_event_handler(theSource, ^{ __CFMachPortChecker(false); });
+                memory->_dsrc_sem = sem;
+                memory->_dsrc = theSource;
+                dispatch_resume(theSource);
+           }
         }
     }
     
@@ -498,10 +476,6 @@ void CFMachPortInvalidate(CFMachPortRef mp) {
             dispatch_source_cancel(mp->_dsrc);
             mp->_dsrc = NULL;
         }
-        if (mp->_dsrc2) {
-            dispatch_source_cancel(mp->_dsrc2);
-            mp->_dsrc2 = NULL;
-        }
         source = mp->_source;
         mp->_source = NULL;
     }
@@ -553,6 +527,13 @@ CFMachPortInvalidationCallBack CFMachPortGetInvalidationCallBack(CFMachPortRef m
 void CFMachPortSetInvalidationCallBack(CFMachPortRef mp, CFMachPortInvalidationCallBack callout) {
     CHECK_FOR_FORK_RET();
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
+    if (callout) {
+       mach_port_type_t type = 0;
+       kern_return_t ret = mach_port_type(mach_task_self(), mp->_port, &type);
+       if (KERN_SUCCESS != ret || 0 == (type & MACH_PORT_TYPE_SEND_RIGHTS)) {
+           CFLog(kCFLogLevelError, CFSTR("*** WARNING: CFMachPortSetInvalidationCallBack() called on a CFMachPort with a Mach port (0x%x) which does not have any send rights.  This is not going to work.  Callback function: %p"), mp->_port, callout);
+       }
+    }
     __CFSpinLock(&mp->_lock);
     if (__CFMachPortIsValid(mp) || !callout) {
         mp->_icallout = callout;
@@ -581,7 +562,7 @@ static mach_port_t __CFMachPortGetPort(void *info) {
     return mp->_port;
 }
 
-static void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef allocator, void *info) {
+CF_PRIVATE void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef allocator, void *info) {
     CHECK_FOR_FORK_RET(NULL);
     CFMachPortRef mp = (CFMachPortRef)info;
     __CFSpinLock(&mp->_lock);
@@ -589,25 +570,27 @@ static void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef allocat
     void *context_info = NULL;
     void (*context_release)(const void *) = NULL;
     if (isValid) {
-        if (mp->_context.retain) {
-            context_info = (void *)mp->_context.retain(mp->_context.info);
-            context_release = mp->_context.release;
+        if (mp->retain) {
+            context_info = (void *)mp->retain(mp->_context.info);
+            context_release = mp->release;
         } else {
             context_info = mp->_context.info;
         }
     }
     __CFSpinUnlock(&mp->_lock);
-    if (!isValid) return NULL;
-
-    mp->_callout(mp, msg, size, context_info);
+    if (isValid) {
+        mp->_callout(mp, msg, size, context_info);
 
-    if (context_release) {
-        context_release(context_info);
+        if (context_release) {
+            context_release(context_info);
+        }
+        CHECK_FOR_FORK_RET(NULL);
     }
-    CHECK_FOR_FORK_RET(NULL);
     return NULL;
 }
 
+
+
 CFRunLoopSourceRef CFMachPortCreateRunLoopSource(CFAllocatorRef allocator, CFMachPortRef mp, CFIndex order) {
     CHECK_FOR_FORK_RET(NULL);
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
index de872627ed0be47fd0571a6cd3e4491bda523f1e..605c92e7f3de70e26b571e3ac955c2c6069469e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFMachPort.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFMACHPORT__)
index f28a81f00fab76b73d60f601c176573c12095896..385a7bc56c782429ab64d3af295cdca53a481f47 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFMessagePort.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -301,7 +301,7 @@ static const CFRuntimeClass __CFMessagePortClass = {
     __CFMessagePortCopyDescription
 };
 
-__private_extern__ void __CFMessagePortInitialize(void) {
+CF_PRIVATE void __CFMessagePortInitialize(void) {
     __kCFMessagePortTypeID = _CFRuntimeRegisterClass(&__CFMessagePortClass);
 }
 
@@ -879,7 +879,7 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef
     CFRunLoopRef currentRL = CFRunLoopGetCurrent();
     CFRunLoopSourceRef source = NULL;
     CFDataRef reply = NULL;
-    int64_t termTSR;
+    uint64_t termTSR;
     uint32_t sendOpts = 0, sendTimeOut = 0;
     int32_t desiredReply;
     Boolean didRegister = false;
@@ -953,10 +953,10 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef
     _CFMachPortInstallNotifyPort(currentRL, replyMode);
     termTSR = mach_absolute_time() + __CFTimeIntervalToTSR(rcvTimeout);
     for (;;) {
-       CFRunLoopRunInMode(replyMode, __CFTSRToTimeInterval(termTSR - mach_absolute_time()), true);
+       CFRunLoopRunInMode(replyMode, __CFTimeIntervalUntilTSR(termTSR), true);
        // warning: what, if anything, should be done if remote is now invalid?
        reply = CFDictionaryGetValue(remote->_replies, (void *)(uintptr_t)desiredReply);
-       if (NULL != reply || termTSR < (int64_t)mach_absolute_time()) {
+       if (NULL != reply || termTSR < mach_absolute_time()) {
            break;
        }
        if (!CFMessagePortIsValid(remote)) {
@@ -990,6 +990,7 @@ static mach_port_t __CFMessagePortGetPort(void *info) {
     return ms->_port ? CFMachPortGetPort(ms->_port) : MACH_PORT_NULL;
 }
 
+
 static void *__CFMessagePortPerform(void *msg, CFIndex size, CFAllocatorRef allocator, void *info) {
     CFMessagePortRef ms = info;
     mach_msg_base_t *msgp = msg;
@@ -1015,6 +1016,7 @@ static void *__CFMessagePortPerform(void *msg, CFIndex size, CFAllocatorRef allo
     }
     __CFMessagePortUnlock(ms);
 
+    
     int32_t byteslen = 0;
 
     Boolean invalidMagic = (MSGP_GET(msgp, magic) != MAGIC) && (CFSwapInt32(MSGP_GET(msgp, magic)) != MAGIC);
index 4d8f9b74706932ca147e56b341eadfeae01d4df4..6112e49132542e54aa7d46504169aa842aee905f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFMessagePort.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFMESSAGEPORT__)
index 4ddbcc0e30801013d4b60b9279faa2c1de9798eb..f945444ffee3cc4117a9f06e9e905f9c44fc1b31 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumber.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
@@ -60,7 +60,7 @@ static CFStringRef __CFBooleanCopyDescription(CFTypeRef cf) {
     return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFBoolean %p [%p]>{value = %s}"), cf, CFGetAllocator(cf), (boolean == kCFBooleanTrue) ? "true" : "false");
 }
 
-__private_extern__ CFStringRef __CFBooleanCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+CF_PRIVATE CFStringRef __CFBooleanCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
     CFBooleanRef boolean = (CFBooleanRef)cf;
     return (CFStringRef)CFRetain((boolean == kCFBooleanTrue) ? CFSTR("true") : CFSTR("false"));
 }
@@ -88,12 +88,10 @@ static const CFRuntimeClass __CFBooleanClass = {
     __CFBooleanCopyDescription
 };
 
-__private_extern__ void __CFBooleanInitialize(void) {
+CF_PRIVATE void __CFBooleanInitialize(void) {
     __kCFBooleanTypeID = _CFRuntimeRegisterClass(&__CFBooleanClass);
-    _CFRuntimeSetInstanceTypeID(&__kCFBooleanTrue, __kCFBooleanTypeID);
-    __kCFBooleanTrue._base._cfisa = __CFISAForTypeID(__kCFBooleanTypeID);
-    _CFRuntimeSetInstanceTypeID(&__kCFBooleanFalse, __kCFBooleanTypeID);
-    __kCFBooleanFalse._base._cfisa = __CFISAForTypeID(__kCFBooleanTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanTrue, __kCFBooleanTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanFalse, __kCFBooleanTypeID);
 }
 
 CFTypeID CFBooleanGetTypeID(void) {
@@ -129,7 +127,7 @@ struct __CFNumber_old {             /* Only as many bytes as necessary are alloc
 static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2);
 static CFHashCode __CFNumberHash_old(CFTypeRef cf);
 static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf);
-__private_extern__ CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf);
+CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf);
 static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions);
 static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr);
 static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number);
@@ -425,14 +423,7 @@ static const struct {
     /* kCFNumberSInt128Type */ {kCFNumberSInt128Type, 0, 1, 4, 0},
 };
 
-#define CF_IS_TAGGED_INT(OBJ)  (CF_TAGGED_OBJ_TYPE(OBJ) == kCFTaggedObjectID_Integer)
-
 CF_INLINE CFNumberType __CFNumberGetType(CFNumberRef num) {
-    if (CF_IS_TAGGED_INT(num)) {
-        uintptr_t type_bits = ((uintptr_t)num >> 6) & 0x3; // top 2 bits of low byte
-        const CFNumberType canonical_types[4] = {kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt64Type};
-       return canonical_types[type_bits];
-    }
     return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0);
 }
 
@@ -464,12 +455,6 @@ static Boolean __CFNumberGetValue(CFNumberRef number, CFNumberType type, void *v
     type = __CFNumberTypeTable[type].canonicalType;
     CFNumberType ntype = __CFNumberGetType(number);
     const void *data = &(number->_pad);
-    intptr_t taggedInteger;
-    if (CF_IS_TAGGED_INT(number)) {
-        taggedInteger = (intptr_t)number;
-        taggedInteger = taggedInteger >> 8;
-       data = &taggedInteger;
-    }
     switch (type) {
     case kCFNumberSInt8Type:
        if (__CFNumberTypeTable[ntype].floatBit) {
@@ -660,12 +645,6 @@ static Boolean __CFNumberGetValueCompat(CFNumberRef number, CFNumberType type, v
     type = __CFNumberTypeTable[type].canonicalType;
     CFNumberType ntype = __CFNumberGetType(number);
     const void *data = &(number->_pad);
-    intptr_t taggedInteger;
-    if (CF_IS_TAGGED_INT(number)) {
-        taggedInteger = (intptr_t)number;
-        taggedInteger = taggedInteger >> 8;
-        data = &taggedInteger;
-    }
     switch (type) {
     case kCFNumberSInt8Type:
        if (__CFNumberTypeTable[ntype].floatBit) {
@@ -897,7 +876,7 @@ static CFStringRef __CFNumberCreateFormattingDescriptionAsFloat64(CFAllocatorRef
     return CFStringCreateWithFormat(allocator, NULL, CFSTR("%.*g"), DBL_DIG + 2, d);
 }
 
-__private_extern__ CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64(CFTypeRef cf) {
+CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64(CFTypeRef cf) {
     CFStringRef result = __CFNumberCreateFormattingDescriptionAsFloat64(kCFAllocatorSystemDefault, cf);
 #if OLD_CRAP_TOO
 CFNumberRef number = (CFNumberRef)cf;
@@ -913,7 +892,7 @@ CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyFormattingDescri
     return result;
 }
 
-__private_extern__ CFStringRef __CFNumberCreateFormattingDescription(CFAllocatorRef allocator, CFTypeRef cf, CFDictionaryRef formatOptions) {
+CF_PRIVATE CFStringRef __CFNumberCreateFormattingDescription(CFAllocatorRef allocator, CFTypeRef cf, CFDictionaryRef formatOptions) {
     CFNumberRef number = (CFNumberRef)cf;
     CFNumberType type = __CFNumberGetType(number);
     if (__CFNumberTypeTable[type].floatBit) {
@@ -939,7 +918,7 @@ static CFStringRef __CFNumberCopyFormattingDescription_new(CFTypeRef cf, CFDicti
     return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%s"), buffer);
 }
 
-__private_extern__ CFStringRef __CFNumberCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
     CFStringRef result = __CFNumberCopyFormattingDescription_new(cf, formatOptions);
 #if OLD_CRAP_TOO
 CFNumberRef number = (CFNumberRef)cf;
@@ -1007,7 +986,6 @@ CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberHash: '%d' '%d'"), h
 }
 
 static CFTypeID __kCFNumberTypeID = _kCFRuntimeNotATypeID;
-static void *__CFTaggedNumberClass = 0;
 
 enum {
   kCFNumberCachingEnabled = 0,
@@ -1029,21 +1007,18 @@ static const CFRuntimeClass __CFNumberClass = {
 };
 
 
-__private_extern__ void __CFNumberInitialize(void) {
+CF_PRIVATE void __CFNumberInitialize(void) {
     __kCFNumberTypeID = _CFRuntimeRegisterClass(&__CFNumberClass);
 
-    _CFRuntimeSetInstanceTypeID(&__kCFNumberNaN, __kCFNumberTypeID);
-    __kCFNumberNaN._base._cfisa = __CFISAForTypeID(__kCFNumberTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFNumberNaN, __kCFNumberTypeID);
     __CFBitfieldSetValue(__kCFNumberNaN._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
     __kCFNumberNaN._pad = BITSFORDOUBLENAN;
 
-    _CFRuntimeSetInstanceTypeID(& __kCFNumberNegativeInfinity, __kCFNumberTypeID);
-    __kCFNumberNegativeInfinity._base._cfisa = __CFISAForTypeID(__kCFNumberTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberNegativeInfinity, __kCFNumberTypeID);
     __CFBitfieldSetValue(__kCFNumberNegativeInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
     __kCFNumberNegativeInfinity._pad = BITSFORDOUBLENEGINF;
 
-    _CFRuntimeSetInstanceTypeID(& __kCFNumberPositiveInfinity, __kCFNumberTypeID);
-    __kCFNumberPositiveInfinity._base._cfisa = __CFISAForTypeID(__kCFNumberTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberPositiveInfinity, __kCFNumberTypeID);
     __CFBitfieldSetValue(__kCFNumberPositiveInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
     __kCFNumberPositiveInfinity._pad = BITSFORDOUBLEPOSINF;
 
@@ -1067,45 +1042,6 @@ CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const vo
 
     if (!allocator) allocator = __CFGetDefaultAllocator();
 
-    if (__CFTaggedNumberClass && _CFAllocatorIsSystemDefault(allocator) && (__CFNumberCaching != kCFNumberCachingFullyDisabled)) {
-       switch (__CFNumberTypeTable[type].canonicalType) { // canonicalized client-desired type
-       case kCFNumberSInt8Type: {
-            int8_t value = *(int8_t *)valuePtr;
-            return (CFNumberRef)((uintptr_t)((intptr_t)value << 8) | (0 << 6) | kCFTaggedObjectID_Integer);
-        }
-       case kCFNumberSInt16Type: {
-            int16_t value = *(int16_t *)valuePtr;
-            return (CFNumberRef)((uintptr_t)((intptr_t)value << 8) | (1 << 6) | kCFTaggedObjectID_Integer);
-        }
-       case kCFNumberSInt32Type: {
-            int32_t value = *(int32_t *)valuePtr;
-#if !__LP64__
-            // We don't bother allowing the min 24-bit integer -2^23 to also be fast-pathed;
-            // tell anybody that complains about that to go ... hang.
-            int32_t limit = (1L << 23);
-            if (value <= -limit || limit <= value) break;
-#endif
-            uintptr_t ptr_val = ((uintptr_t)((intptr_t)value << 8) | (2 << 6) | kCFTaggedObjectID_Integer);
-            return (CFNumberRef)ptr_val;
-        }
-       case kCFNumberSInt64Type: {
-            int64_t value = *(int64_t *)valuePtr;
-#if __LP64__
-            // We don't bother allowing the min 56-bit integer -2^55 to also be fast-pathed;
-            // tell anybody that complains about that to go ... hang.
-            int64_t limit = (1L << 55);
-            if (value <= -limit || limit <= value) break;
-#else
-            // We don't bother allowing the min 24-bit integer -2^23 to also be fast-pathed;
-            // tell anybody that complains about that to go ... hang.
-            int64_t limit = (1L << 23);
-            if (value <= -limit || limit <= value) break;
-#endif
-            uintptr_t ptr_val = ((uintptr_t)((intptr_t)value << 8) | (3 << 6) | kCFTaggedObjectID_Integer);
-            return (CFNumberRef)ptr_val;
-       }
-       }
-    }
 
     // Look for cases where we can return a cached instance.
     // We only use cached objects if the allocator is the system
@@ -1194,9 +1130,6 @@ CFLog(kCFLogLevelWarning, CFSTR("+++ Create old number '%@'"), __CFNumberCopyDes
 
 CFNumberType CFNumberGetType(CFNumberRef number) {
 //printf("+ [%p] CFNumberGetType(%p)\n", pthread_self(), number);
-    if (CF_IS_TAGGED_INT(number)) {
-        return __CFNumberGetType(number);
-    }
     CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, CFNumberType, (NSNumber *)number, _cfNumberType);
     __CFAssertIsNumber(number);
     CFNumberType type = __CFNumberGetType(number);
@@ -1216,6 +1149,7 @@ CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberGetType: '%d' '%d'"),
 }
 
 CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number) {
+    CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, CFNumberType, (NSNumber *)number, _cfNumberType);
     __CFAssertIsNumber(number);
     return __CFNumberGetType(number);
 }
@@ -1258,51 +1192,7 @@ CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberIsFloatType: '%d' '%d'
 
 Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) {
 //printf("+ [%p] CFNumberGetValue(%p, %d, %p)\n", pthread_self(), number, type, valuePtr);
-    if (CF_IS_TAGGED_INT(number)) {
-        __CFAssertIsValidNumberType(type);
-        uint8_t localMemory[128];
-        if (!valuePtr) valuePtr = localMemory;
-        intptr_t taggedInteger = (intptr_t)number;
-        taggedInteger = taggedInteger >> 8;
-        switch (__CFNumberTypeTable[type].canonicalType) { // canonicalized client-desired type
-        case kCFNumberSInt8Type:
-#if 0
-            if (taggedInteger < INT8_MIN) {
-                *(int8_t *)valuePtr = INT8_MIN;
-                return false;
-            }
-            if (INT8_MAX < taggedInteger) {
-                *(int8_t *)valuePtr = INT8_MAX;
-                return false;
-            }
-#endif
-            *(int8_t *)valuePtr = (int8_t)taggedInteger;
-            return true;
-        case kCFNumberSInt16Type:
-#if 0
-            if (taggedInteger < INT16_MIN) {
-                *(int16_t *)valuePtr = INT16_MIN;
-                return false;
-            }
-            if (INT16_MAX < taggedInteger) {
-                *(int16_t *)valuePtr = INT16_MAX;
-                return false;
-            }
-#endif
-            *(int16_t *)valuePtr = (int16_t)taggedInteger;
-            return true;
-        case kCFNumberSInt32Type:
-            *(int32_t *)valuePtr = (int32_t)taggedInteger;
-            return true;
-#if __LP64__
-        case kCFNumberSInt64Type:
-            *(int64_t *)valuePtr = (int64_t)taggedInteger;
-            return true;
-#endif
-        }
-        Boolean r = __CFNumberGetValueCompat(number, type, valuePtr);
-        return r;
-    }
+
     CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, Boolean, (NSNumber *)number, _getValue:(void *)valuePtr forType:(CFNumberType)__CFNumberTypeTable[type].canonicalType);
     __CFAssertIsNumber(number);
     __CFAssertIsValidNumberType(type);
@@ -1631,7 +1521,7 @@ static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf) {
 
 // This function separated out from __CFNumberCopyFormattingDescription() so the plist creation can use it as well.
 
-__private_extern__ CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf) {
+CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf) {
     double d;
     CFNumberGetValue_old((struct __CFNumber_old *)cf, kCFNumberFloat64Type, &d);
         if (isnan(d)) {
index 5cddcbb464ec50e179a751ae4a306a58aaeafd3c..2792e271318ac3da8f5b4c9bf998541f2b70b0eb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumber.h
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFNUMBER__)
index 2a3fc8c8c2f4acdfed47bc8cde4154643fe0698b..dbb63df55001a75b555ea28f2f99b1d025017236 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumberFormatter.c
-       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -31,8 +31,7 @@
 #include <CoreFoundation/CFBigNumber.h>
 #include "CFInternal.h"
 #include "CFLocaleInternal.h"
-#include <unicode/unum.h>
-#include <unicode/ucurr.h>
+#include "CFICULogging.h"
 #include <math.h>
 #include <float.h>
 
@@ -55,6 +54,7 @@ struct __CFNumberFormatter {
     CFStringRef _zeroSym;
     Boolean _isLenient;
     Boolean _userSetMultiplier;
+    Boolean _usesCharacterDirection;
 };
 
 static CFStringRef __CFNumberFormatterCopyDescription(CFTypeRef cf) {
@@ -64,7 +64,7 @@ static CFStringRef __CFNumberFormatterCopyDescription(CFTypeRef cf) {
 
 static void __CFNumberFormatterDeallocate(CFTypeRef cf) {
     CFNumberFormatterRef formatter = (CFNumberFormatterRef)cf;
-    if (formatter->_nf) unum_close(formatter->_nf);
+    if (formatter->_nf) __cficu_unum_close(formatter->_nf);
     if (formatter->_locale) CFRelease(formatter->_locale);
     if (formatter->_format) CFRelease(formatter->_format);
     if (formatter->_defformat) CFRelease(formatter->_defformat);
@@ -115,6 +115,7 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR
     memory->_zeroSym = NULL;
     memory->_isLenient = false;
     memory->_userSetMultiplier = false;
+    memory->_usesCharacterDirection = false;
     if (NULL == locale) locale = CFLocaleGetSystem();
     memory->_style = style;
     uint32_t ustyle;
@@ -144,7 +145,7 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR
        return NULL;
     }
     UErrorCode status = U_ZERO_ERROR;
-    memory->_nf = unum_open((UNumberFormatStyle)ustyle, NULL, 0, cstr, NULL, &status);
+    memory->_nf = __cficu_unum_open((UNumberFormatStyle)ustyle, NULL, 0, cstr, NULL, &status);
     CFAssert2(memory->_nf, __kCFLogAssertion, "%s(): error (%d) creating number formatter", __PRETTY_FUNCTION__, status);
     if (NULL == memory->_nf) {
        CFRelease(memory);
@@ -154,16 +155,16 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR
     if (kCFNumberFormatterNoStyle == style) {
         status = U_ZERO_ERROR;
        ubuff[0] = '#'; ubuff[1] = ';'; ubuff[2] = '#';
-        unum_applyPattern(memory->_nf, false, ubuff, 3, NULL, &status);
-       unum_setAttribute(memory->_nf, UNUM_MAX_INTEGER_DIGITS, 42);
-       unum_setAttribute(memory->_nf, UNUM_MAX_FRACTION_DIGITS, 0);
+        __cficu_unum_applyPattern(memory->_nf, false, ubuff, 3, NULL, &status);
+       __cficu_unum_setAttribute(memory->_nf, UNUM_MAX_INTEGER_DIGITS, 42);
+       __cficu_unum_setAttribute(memory->_nf, UNUM_MAX_FRACTION_DIGITS, 0);
     }
     memory->_locale = locale ? CFLocaleCreateCopy(allocator, locale) : CFLocaleGetSystem();
     __CFNumberFormatterCustomize(memory);
     if (kCFNumberFormatterSpellOutStyle != memory->_style && kCFNumberFormatterOrdinalStyle != memory->_style && kCFNumberFormatterDurationStyle != memory->_style) {
        UChar ubuffer[BUFFER_SIZE];
        status = U_ZERO_ERROR;
-       int32_t ret = unum_toPattern(memory->_nf, false, ubuffer, BUFFER_SIZE, &status);
+       int32_t ret = __cficu_unum_toPattern(memory->_nf, false, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
            memory->_format = CFStringCreateWithCharacters(allocator, (const UniChar *)ubuffer, ret);
        }
@@ -171,13 +172,13 @@ CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleR
     memory->_defformat = memory->_format ? (CFStringRef)CFRetain(memory->_format) : NULL;
     memory->_compformat = memory->_format ? __CFNumberFormatterCreateCompressedString(memory->_format, true, NULL) : NULL;
     if (kCFNumberFormatterSpellOutStyle != memory->_style && kCFNumberFormatterOrdinalStyle != memory->_style && kCFNumberFormatterDurationStyle != memory->_style) {
-       int32_t n = unum_getAttribute(memory->_nf, UNUM_MULTIPLIER);
+       int32_t n = __cficu_unum_getAttribute(memory->_nf, UNUM_MULTIPLIER);
        if (1 != n) {
            memory->_multiplier = CFNumberCreate(allocator, kCFNumberSInt32Type, &n);
-           unum_setAttribute(memory->_nf, UNUM_MULTIPLIER, 1);
+           __cficu_unum_setAttribute(memory->_nf, UNUM_MULTIPLIER, 1);
        }
     }
-    unum_setAttribute(memory->_nf, UNUM_LENIENT_PARSE, 0);
+    __cficu_unum_setAttribute(memory->_nf, UNUM_LENIENT_PARSE, 0);
     return (CFNumberFormatterRef)memory;
 }
 
@@ -225,15 +226,15 @@ static void __substituteFormatStringFromPrefsNF(CFNumberFormatterRef formatter)
                if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
            }
            UErrorCode status = U_ZERO_ERROR;
-           UNumberFormat *nf = unum_open((UNumberFormatStyle)icustyle, NULL, 0, cstr, NULL, &status);
+           UNumberFormat *nf = __cficu_unum_open((UNumberFormatStyle)icustyle, NULL, 0, cstr, NULL, &status);
            if (NULL != nf) {
                UChar ubuffer[BUFFER_SIZE];
                status = U_ZERO_ERROR;
-               int32_t number_len = unum_toPattern(nf, false, ubuffer, BUFFER_SIZE, &status);
+               int32_t number_len = __cficu_unum_toPattern(nf, false, ubuffer, BUFFER_SIZE, &status);
                if (U_SUCCESS(status) && number_len <= BUFFER_SIZE) {
                    CFStringRef numberString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, number_len);
                    status = U_ZERO_ERROR;
-                   int32_t formatter_len = unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
+                   int32_t formatter_len = __cficu_unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
                    if (U_SUCCESS(status) && formatter_len <= BUFFER_SIZE) {
                        CFMutableStringRef formatString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
                        CFStringAppendCharacters(formatString, (const UniChar *)ubuffer, formatter_len);
@@ -247,7 +248,7 @@ static void __substituteFormatStringFromPrefsNF(CFNumberFormatterRef formatter)
                    }
                    CFRelease(numberString);
                }
-               unum_close(nf);
+               __cficu_unum_close(nf);
            }
        }
     }
@@ -301,7 +302,7 @@ static void __CFNumberFormatterApplySymbolPrefs(const void *key, const void *val
            item_ustr = item_buffer;
        }
        UErrorCode status = U_ZERO_ERROR;
-       unum_setSymbol(formatter->_nf, sym, item_ustr, item_cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, sym, item_ustr, item_cnt, &status);
    }
 }
 
@@ -318,21 +319,21 @@ static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter
        ustr = ubuffer;
     }
     UErrorCode status = U_ZERO_ERROR;
-    unum_applyPattern(formatter->_nf, false, ustr, cnt, NULL, &status);
+    __cficu_unum_applyPattern(formatter->_nf, false, ustr, cnt, NULL, &status);
 
-    // unum_applyPattern() may have magically changed other attributes based on
+    // __cficu_unum_applyPattern() may have magically changed other attributes based on
     // the contents of the format string; we simply expose that ICU behavior, except
     // for UNUM_MULTIPLIER, which we re-read and reset, like we did at initialization
     // time though any user-set multiplier state takes precedence.
     if (formatter->_userSetMultiplier) {
-       unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
     } else {
        if (formatter->_multiplier) CFRelease(formatter->_multiplier);
         formatter->_multiplier = NULL;
-        int32_t n = unum_getAttribute(formatter->_nf, UNUM_MULTIPLIER);
+        int32_t n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MULTIPLIER);
         if (1 != n) {
            formatter->_multiplier = CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
-           unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
+           __cficu_unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
         }
     }
     return status;
@@ -365,7 +366,7 @@ CFStringRef CFNumberFormatterGetFormat(CFNumberFormatterRef formatter) {
     UChar ubuffer[BUFFER_SIZE];
     CFStringRef newString = NULL;
     UErrorCode status = U_ZERO_ERROR;
-    int32_t ret = unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
+    int32_t ret = __cficu_unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
     if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
        newString = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ret);
     }
@@ -397,7 +398,7 @@ void CFNumberFormatterSetFormat(CFNumberFormatterRef formatter, CFStringRef form
        if (U_SUCCESS(status)) {
            UChar ubuffer2[BUFFER_SIZE];
            status = U_ZERO_ERROR;
-           int32_t ret = unum_toPattern(formatter->_nf, false, ubuffer2, BUFFER_SIZE, &status);
+           int32_t ret = __cficu_unum_toPattern(formatter->_nf, false, ubuffer2, BUFFER_SIZE, &status);
            if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
                if (formatter->_format) CFRelease(formatter->_format);
                formatter->_format = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer2, ret);
@@ -425,6 +426,7 @@ CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CF
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
     __CFGenericValidateType(number, CFNumberGetTypeID());
+    // The values of CFNumbers with large unsigned 64-bit ints don't survive well through this
     CFNumberType type = CFNumberGetType(number);
     char buffer[64];
     CFNumberGetValue(number, type, buffer);
@@ -438,12 +440,12 @@ CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CF
                value = (T)(value * multiplier);                     \
        }                                                               \
        status = U_ZERO_ERROR;                                          \
-       used = FUNC(formatter->_nf, value, ubuffer, cnt, NULL, &status); \
+       used = FUNC(formatter->_nf, value, ubuffer + 1, cnt, NULL, &status); \
        if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {          \
-           cnt = used + 1;                                             \
+           cnt = used + 1 + 1;                                         \
            ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0); \
            status = U_ZERO_ERROR;                                      \
-           used = FUNC(formatter->_nf, value, ustr, cnt, NULL, &status); \
+           used = FUNC(formatter->_nf, value, ustr + 1, cnt, NULL, &status); \
        }
 
 #define FORMAT_INT(T, FUN)                                                   \
@@ -454,15 +456,15 @@ CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CF
         }                                                           \
         _CFBigNum bignum;                                           \
         FUN(&bignum, value);                                        \
-        char buffer[BUFFER_SIZE];                                           \
+        char buffer[BUFFER_SIZE + 1];                                           \
         _CFBigNumToCString(&bignum, false, true, buffer, BUFFER_SIZE);      \
         status = U_ZERO_ERROR;                                      \
-        used = unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ubuffer, BUFFER_SIZE, NULL, &status);     \
+        used = __cficu_unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ubuffer + 1, BUFFER_SIZE, NULL, &status);     \
         if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {      \
-            cnt = used + 1;                                         \
+            cnt = used + 1 + 1;                                         \
             ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0);                 \
             status = U_ZERO_ERROR;                                  \
-            used = unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ustr, cnt, NULL, &status);            \
+            used = __cficu_unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ustr + 1, cnt, NULL, &status);            \
         }                                                           \
 
 CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFNumberType numberType, const void *valuePtr) {
@@ -470,13 +472,13 @@ CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFN
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
     GET_MULTIPLIER;
-    UChar *ustr = NULL, ubuffer[BUFFER_SIZE];
+    UChar *ustr = NULL, ubuffer[BUFFER_SIZE + 1];
     UErrorCode status = U_ZERO_ERROR;
     CFIndex used, cnt = BUFFER_SIZE;
     if (numberType == kCFNumberFloat64Type || numberType == kCFNumberDoubleType) {
-       FORMAT_FLT(double, unum_formatDouble)
+       FORMAT_FLT(double, __cficu_unum_formatDouble)
     } else if (numberType == kCFNumberFloat32Type || numberType == kCFNumberFloatType) {
-       FORMAT_FLT(float, unum_formatDouble)
+       FORMAT_FLT(float, __cficu_unum_formatDouble)
     } else if (numberType == kCFNumberSInt64Type || numberType == kCFNumberLongLongType) {
        FORMAT_INT(int64_t, _CFBigNumInitWithInt64)
     } else if (numberType == kCFNumberLongType || numberType == kCFNumberCFIndexType) {
@@ -497,7 +499,16 @@ CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFN
     }
     CFStringRef string = NULL;
     if (U_SUCCESS(status)) {
-       string = CFStringCreateWithCharacters(allocator, ustr ? (const UniChar *)ustr : (const UniChar *)ubuffer, used);
+        UniChar *bufferToUse = ustr ? (UniChar *)ustr : (UniChar *)ubuffer;
+        if (formatter->_usesCharacterDirection && CFLocaleGetLanguageCharacterDirection(CFLocaleGetIdentifier(formatter->_locale)) == kCFLocaleLanguageDirectionRightToLeft) {
+            // Insert Unicode RTL marker
+            bufferToUse[0] = 0x200F;
+            used++;
+        } else {
+            // Move past direction marker
+            bufferToUse++;
+        }
+        string = CFStringCreateWithCharacters(allocator, bufferToUse, used);
     }
     if (ustr) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ustr);
     return string;
@@ -606,7 +617,7 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
         } else {
             range.length = CFStringGetLength(stringToParse);
         }
-        // unum_parse chokes on leading whitespace
+        // __cficu_unum_parse chokes on leading whitespace
         CFCharacterSetRef whitespace = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
         while(range.length > 0 && CFCharacterSetIsCharacterMember(whitespace, CFStringGetCharacterAtIndex(stringToParse, range.location))) {
             range.location++;
@@ -644,10 +655,10 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
     case kCFNumberSInt32Type: case kCFNumberIntType:
     case kCFNumberLongType: case kCFNumberCFIndexType:
     case kCFNumberSInt64Type: case kCFNumberLongLongType:
-       unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 1); // ignored by ICU for rule-based formatters
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 1); // ignored by ICU for rule-based formatters
        break;
     default:
-       unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 0); // ignored by ICU for rule-based formatters
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 0); // ignored by ICU for rule-based formatters
        integerOnly = 0;
        break;
     }
@@ -660,7 +671,7 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
     } else {
        char buffer[1024];
         memset(buffer, 0, sizeof(buffer));
-       int32_t len = unum_parseDecimal(formatter->_nf, ustr, range.length, &dpos, buffer, sizeof(buffer), &status);
+       int32_t len = __cficu_unum_parseDecimal(formatter->_nf, ustr, range.length, &dpos, buffer, sizeof(buffer), &status);
         if (!U_FAILURE(status) && 0 < len && integerOnly) {
            char *endptr = NULL;
            errno = 0;
@@ -766,37 +777,37 @@ void CFNumberFormatterSetProperty(CFNumberFormatterRef formatter, CFStringRef ke
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterDecimalSeparatorKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterCurrencyDecimalSeparatorKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterAlwaysShowDecimalSeparatorKey == key) {
        __CFGenericValidateType(value, CFBooleanGetTypeID());
-       unum_setAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN, (kCFBooleanTrue == value));
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN, (kCFBooleanTrue == value));
     } else if (kCFNumberFormatterGroupingSeparatorKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, (const UChar *)ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, (const UChar *)ubuffer, cnt, &status);
     } else if (kCFNumberFormatterUseGroupingSeparatorKey == key) {
        __CFGenericValidateType(value, CFBooleanGetTypeID());
-       unum_setAttribute(formatter->_nf, UNUM_GROUPING_USED, (kCFBooleanTrue == value));
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_GROUPING_USED, (kCFBooleanTrue == value));
     } else if (kCFNumberFormatterPercentSymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterZeroSymbolKey == key) {
         __CFGenericValidateType(value, CFStringGetTypeID());
         CFStringRef old = formatter->_zeroSym;
@@ -807,83 +818,83 @@ void CFNumberFormatterSetProperty(CFNumberFormatterRef formatter, CFStringRef ke
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterInfinitySymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterMinusSignKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterPlusSignKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterCurrencySymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, (const UChar *)ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, (const UChar *)ubuffer, cnt, &status);
     } else if (kCFNumberFormatterExponentSymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, cnt, &status);
+       __cficu_unum_setSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterMinIntegerDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS, n);
     } else if (kCFNumberFormatterMaxIntegerDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS, n);
     } else if (kCFNumberFormatterMinFractionDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS, n);
     } else if (kCFNumberFormatterMaxFractionDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS, n);
     } else if (kCFNumberFormatterGroupingSizeKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_GROUPING_SIZE, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_GROUPING_SIZE, n);
     } else if (kCFNumberFormatterSecondaryGroupingSizeKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE, n);
     } else if (kCFNumberFormatterRoundingModeKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_ROUNDING_MODE, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_ROUNDING_MODE, n);
     } else if (kCFNumberFormatterRoundingIncrementKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberDoubleType, &d);
-       unum_setDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT, d);
+       __cficu_unum_setDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT, d);
     } else if (kCFNumberFormatterFormatWidthKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_FORMAT_WIDTH, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_FORMAT_WIDTH, n);
     } else if (kCFNumberFormatterPaddingPositionKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_PADDING_POSITION, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_PADDING_POSITION, n);
     } else if (kCFNumberFormatterPaddingCharacterKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterDefaultFormatKey == key) {
        // read-only attribute
     } else if (kCFNumberFormatterMultiplierKey == key) {
@@ -897,65 +908,68 @@ void CFNumberFormatterSetProperty(CFNumberFormatterRef formatter, CFStringRef ke
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterPositiveSuffixKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
     } else if (kCFNumberFormatterNegativePrefixKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterNegativeSuffixKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-       unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
+       __cficu_unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
     } else if (kCFNumberFormatterPerMillSymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
         cnt = CFStringGetLength((CFStringRef)value);
         if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
         CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-        unum_setSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, cnt, &status);
+        __cficu_unum_setSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterInternationalCurrencySymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
         cnt = CFStringGetLength((CFStringRef)value);
         if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
         CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-        unum_setSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, cnt, &status);
+        __cficu_unum_setSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterCurrencyGroupingSeparatorKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
         cnt = CFStringGetLength((CFStringRef)value);
         if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
         CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-        unum_setSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
+        __cficu_unum_setSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
     } else if (kCFNumberFormatterIsLenientKey == key) {
        __CFGenericValidateType(value, CFBooleanGetTypeID());
        formatter->_isLenient = (kCFBooleanTrue == value);
-       unum_setAttribute(formatter->_nf, UNUM_LENIENT_PARSE, (kCFBooleanTrue == value));
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_LENIENT_PARSE, (kCFBooleanTrue == value));
     } else if (kCFNumberFormatterUseSignificantDigitsKey == key) {
        __CFGenericValidateType(value, CFBooleanGetTypeID());
-       unum_setAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED, (kCFBooleanTrue == value));
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED, (kCFBooleanTrue == value));
     } else if (kCFNumberFormatterMinSignificantDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS, n);
     } else if (kCFNumberFormatterMaxSignificantDigitsKey == key) {
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
-       unum_setAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS, n);
+       __cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS, n);
+    } else if (kCFNumberFormatterUsesCharacterDirectionKey == key) {
+        __CFGenericValidateType(value, CFBooleanGetTypeID());
+        formatter->_usesCharacterDirection = value == kCFBooleanTrue;
     } else {
        CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
     }
     if (_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)) {
         // do a dummy call to CFNumberFormatterGetFormat() after changing an attribute because
         // ICU sometimes changes the pattern due to a property change, and we need to poke
-        // unum_toPattern() and also update our own variables
+        // __cficu_unum_toPattern() and also update our own variables
         CFNumberFormatterGetFormat(formatter);
     }
 }
@@ -973,7 +987,7 @@ CFTypeRef CFNumberFormatterCopyProperty(CFNumberFormatterRef formatter, CFString
     if (kCFNumberFormatterOrdinalStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
     if (kCFNumberFormatterDurationStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
     if (kCFNumberFormatterCurrencyCodeKey == key) {
-       cnt = unum_getTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt == 0) {
            CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
            char buffer[BUFFER_SIZE];
@@ -985,129 +999,129 @@ CFTypeRef CFNumberFormatterCopyProperty(CFNumberFormatterRef formatter, CFString
                return NULL;
            }
            UErrorCode status = U_ZERO_ERROR;
-           UNumberFormat *nf = unum_open(UNUM_CURRENCY, NULL, 0, cstr, NULL, &status);
+           UNumberFormat *nf = __cficu_unum_open(UNUM_CURRENCY, NULL, 0, cstr, NULL, &status);
            if (NULL != nf) {
-               cnt = unum_getTextAttribute(nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
-               unum_close(nf);
+               cnt = __cficu_unum_getTextAttribute(nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
+               __cficu_unum_close(nf);
            }
        }
        if (U_SUCCESS(status) && 0 < cnt && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterDecimalSeparatorKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterCurrencyDecimalSeparatorKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, (UChar *)ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, (UChar *)ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterAlwaysShowDecimalSeparatorKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN);
        if (1) {
            return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
        }
     } else if (kCFNumberFormatterGroupingSeparatorKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterUseGroupingSeparatorKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_GROUPING_USED);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_GROUPING_USED);
        if (1) {
            return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
        }
    } else if (kCFNumberFormatterPercentSymbolKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterZeroSymbolKey == key) {
         return formatter->_zeroSym ? CFRetain(formatter->_zeroSym) : NULL;
     } else if (kCFNumberFormatterNaNSymbolKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterInfinitySymbolKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterMinusSignKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterPlusSignKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterCurrencySymbolKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterExponentSymbolKey == key) {
-       cnt = unum_getSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
     } else if (kCFNumberFormatterMinIntegerDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterMaxIntegerDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterMinFractionDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterMaxFractionDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterGroupingSizeKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_GROUPING_SIZE);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_GROUPING_SIZE);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterSecondaryGroupingSizeKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterRoundingModeKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_ROUNDING_MODE);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_ROUNDING_MODE);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterRoundingIncrementKey == key) {
-       d = unum_getDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT);
+       d = __cficu_unum_getDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberDoubleType, &d);
        }
     } else if (kCFNumberFormatterFormatWidthKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_FORMAT_WIDTH);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_FORMAT_WIDTH);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterPaddingPositionKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_PADDING_POSITION);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_PADDING_POSITION);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterPaddingCharacterKey == key) {
-       cnt = unum_getTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, BUFFER_SIZE, &status);
+       cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
@@ -1116,55 +1130,55 @@ CFTypeRef CFNumberFormatterCopyProperty(CFNumberFormatterRef formatter, CFString
     } else if (kCFNumberFormatterMultiplierKey == key) {
         return formatter->_multiplier ? CFRetain(formatter->_multiplier) : NULL;
     } else if (kCFNumberFormatterPositivePrefixKey == key) {
-        cnt = unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterPositiveSuffixKey == key) {
-        cnt = unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterNegativePrefixKey == key) {
-        cnt = unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterNegativeSuffixKey == key) {
-        cnt = unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterPerMillSymbolKey == key) {
-        cnt = unum_getSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterInternationalCurrencySymbolKey == key) {
-        cnt = unum_getSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterCurrencyGroupingSeparatorKey == key) {
-        cnt = unum_getSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
+        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
         if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
             return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
         }
     } else if (kCFNumberFormatterIsLenientKey == key) {
-       // unum_getAttribute(, UNUM_LENIENT_PARSE) is undefined.
+       // __cficu_unum_getAttribute(, UNUM_LENIENT_PARSE) is undefined.
        return CFRetain(formatter->_isLenient ? kCFBooleanTrue : kCFBooleanFalse);
     } else if (kCFNumberFormatterUseSignificantDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED);
        if (1) {
            return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
        }
     } else if (kCFNumberFormatterMinSignificantDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
     } else if (kCFNumberFormatterMaxSignificantDigitsKey == key) {
-       n = unum_getAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS);
+       n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
@@ -1182,8 +1196,8 @@ Boolean CFNumberFormatterGetDecimalInfoForCurrencyCode(CFStringRef currencyCode,
     CFStringGetCharacters(currencyCode, CFRangeMake(0, 3), (UniChar *)ubuffer);
     ubuffer[3] = 0;
     UErrorCode icuStatus = U_ZERO_ERROR;
-    if (defaultFractionDigits) *defaultFractionDigits = ucurr_getDefaultFractionDigits(ubuffer, &icuStatus);
-    if (roundingIncrement) *roundingIncrement = ucurr_getRoundingIncrement(ubuffer, &icuStatus);
+    if (defaultFractionDigits) *defaultFractionDigits = __cficu_ucurr_getDefaultFractionDigits(ubuffer, &icuStatus);
+    if (roundingIncrement) *roundingIncrement = __cficu_ucurr_getRoundingIncrement(ubuffer, &icuStatus);
     if (U_FAILURE(icuStatus))
         return false;
     return (!defaultFractionDigits || 0 <= *defaultFractionDigits) && (!roundingIncrement || 0.0 <= *roundingIncrement);
index 9c17102ea58cd72dfa43d3e4db309b7e4259a324..f9eded16e8d165d83c26f49adae5874001498096 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumberFormatter.h
-       Copyright (c) 2003-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2003-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFNUMBERFORMATTER__)
index 38817880b8913fcb97399df62ad7c5ff313d07ae..1882efaf1f5f3d115b6b46bc6d47c02758b73105 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFOldStylePList.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
 //
 
 CF_INLINE void __CFPListRelease(CFTypeRef cf, CFAllocatorRef allocator) {
-    if (cf && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(cf);
+    if (cf && !(0)) CFRelease(cf);
 }
 
-__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
+CF_PRIVATE CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
 
 typedef struct {
     const UniChar *begin;
@@ -171,7 +171,7 @@ static UniChar getSlashedChar(_CFStringsFileParseInfo *pInfo) {
 }
 
 static CFStringRef _uniqueStringForCharacters(_CFStringsFileParseInfo *pInfo, const UniChar *base, CFIndex length) {
-    if (0 == length) return !_CFAllocatorIsGCRefZero(pInfo->allocator) ? (CFStringRef)CFRetain(CFSTR("")) : CFSTR("");
+    if (0 == length) return !(0) ? (CFStringRef)CFRetain(CFSTR("")) : CFSTR("");
     // This is to avoid having to promote the buffers of all the strings compared against
     // during the set probe; if a Unicode string is passed in, that's what happens.
     CFStringRef stringToUnique = NULL;
@@ -198,7 +198,7 @@ static CFStringRef _uniqueStringForCharacters(_CFStringsFileParseInfo *pInfo, co
        uniqued = stringToUnique;
     }
     __CFPListRelease(stringToUnique, pInfo->allocator);
-    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
+    if (uniqued && !(0)) CFRetain(uniqued);
     return uniqued;
 }
 
@@ -209,7 +209,7 @@ static CFStringRef _uniqueStringForString(_CFStringsFileParseInfo *pInfo, CFStri
         CFSetAddValue(pInfo->stringSet, uniqued);
         __CFTypeCollectionRelease(pInfo->allocator, uniqued);
     }
-    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
+    if (uniqued && !(0)) CFRetain(uniqued);
     return uniqued;
 }
 
@@ -532,7 +532,7 @@ static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireOb
 
 // CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError, Boolean allowNewTypes, CFPropertyListFormat *format, CFSetRef keyPaths
 
-__private_extern__ CFTypeRef __CFParseOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format) {
+CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format) {
     
     // Convert the string to UTF16 for parsing old-style
     if (originalString) {
@@ -622,8 +622,8 @@ __private_extern__ CFTypeRef __CFParseOldStylePropertyListOrStringsFile(CFAlloca
     
     if (result && format) *format = kCFPropertyListOpenStepFormat;
     
-    if (createdBuffer && !_CFAllocatorIsGCRefZero(allocator)) CFAllocatorDeallocate(allocator, buf);
-    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(stringsPInfo.stringSet);
+    if (createdBuffer && !(0)) CFAllocatorDeallocate(allocator, buf);
+    CFRelease(stringsPInfo.stringSet);
     CFRelease(originalString);
     return result;
 }
index 7d51cfa1e567fd5a958715b806da0c66ed87feea..aca99b29becc11d70a09bda99c8bfe3f00243866 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlatform.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -37,6 +37,7 @@
     #include <pwd.h>
     #include <crt_externs.h>
     #include <mach-o/dyld.h>
+    #include <pthread/tsd_private.h>
 #endif
 
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -63,14 +64,14 @@ int _CFArgc(void) { return *_NSGetArgc(); }
 #endif
 
 
-__private_extern__ Boolean _CFGetCurrentDirectory(char *path, int maxlen) {
+CF_PRIVATE Boolean _CFGetCurrentDirectory(char *path, int maxlen) {
     return getcwd(path, maxlen) != NULL;
 }
 
 #if DEPLOYMENT_TARGET_WINDOWS
 // Returns the path to the CF DLL, which we can then use to find resources like char sets
 bool bDllPathCached = false;
-__private_extern__ const wchar_t *_CFDLLPath(void) {
+CF_PRIVATE const wchar_t *_CFDLLPath(void) {
     static wchar_t cachedPath[MAX_PATH+1];
 
     if (!bDllPathCached) {
@@ -190,7 +191,7 @@ const char *_CFProcessPath(void) {
 }
 #endif
 
-__private_extern__ CFStringRef _CFProcessNameString(void) {
+CF_PRIVATE CFStringRef _CFProcessNameString(void) {
     static CFStringRef __CFProcessNameString = NULL;
     if (!__CFProcessNameString) {
         const char *processName = *_CFGetProgname();
@@ -231,7 +232,7 @@ static CFURLRef _CFCopyHomeDirURLForUser(struct passwd *upwd, bool fallBackToHom
 #define CFMaxHostNameLength    256
 #define CFMaxHostNameSize      (CFMaxHostNameLength+1)
 
-__private_extern__ CFStringRef _CFStringCreateHostName(void) {
+CF_PRIVATE CFStringRef _CFStringCreateHostName(void) {
     char myName[CFMaxHostNameSize];
 
     // return @"" instead of nil a la CFUserName() and Ali Ozer
@@ -510,7 +511,7 @@ CF_EXPORT int _NS_pthread_main_np() {
 #define CF_TSD_MAX_SLOTS 70
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-#define CF_TSD_KEY 55
+static const unsigned long CF_TSD_KEY = __PTK_FRAMEWORK_COREFOUNDATION_KEY5;
 #endif
 
 // Windows and Linux, not sure how many times the destructor could get called; CF_TSD_MAX_DESTRUCTOR_CALLS could be 1
@@ -533,17 +534,17 @@ static void __CFTSDFinalize(void *arg);
 static DWORD __CFTSDIndexKey = 0xFFFFFFFF;
 
 // Called from CFRuntime's startup code, on Windows only
-__private_extern__ void __CFTSDWindowsInitialize() {
+CF_PRIVATE void __CFTSDWindowsInitialize() {
     __CFTSDIndexKey = TlsAlloc();
 }
 
 // Called from CFRuntime's cleanup code, on Windows only
-__private_extern__ void __CFTSDWindowsCleanup() {
+CF_PRIVATE void __CFTSDWindowsCleanup() {
     TlsFree(__CFTSDIndexKey);
 }
 
 // Called for each thread as it exits, on Windows only
-__private_extern__ void __CFFinalizeWindowsThreadData() {
+CF_PRIVATE void __CFFinalizeWindowsThreadData() {
     // Normally, this should call the finalizer several times to emulate the behavior of pthreads on Windows. However, a few bugs keep us from doing this:
     // <rdar://problem/8989063> REGRESSION(CF-610-CF-611): Crash closing Safari in BonjourDB destructor (Windows)
     // <rdar://problem/9326814> SyncUIHandler crashes after conflict is resolved and we do SyncNow
@@ -559,7 +560,7 @@ __private_extern__ void __CFFinalizeWindowsThreadData() {
 static pthread_key_t __CFTSDIndexKey;
 
 // Called from CFRuntime's startup code, on Linux only
-__private_extern__ void __CFTSDLinuxInitialize() {
+CF_PRIVATE void __CFTSDLinuxInitialize() {
     (void)pthread_key_create(&__CFTSDIndexKey, __CFTSDFinalize);
 }
 
@@ -567,7 +568,7 @@ __private_extern__ void __CFTSDLinuxInitialize() {
 
 static void __CFTSDSetSpecific(void *arg) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    pthread_setspecific(CF_TSD_KEY, arg);
+    _pthread_setspecific_direct(CF_TSD_KEY, arg);
 #elif DEPLOYMENT_TARGET_LINUX
     pthread_setspecific(__CFTSDIndexKey, arg);
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -577,7 +578,7 @@ static void __CFTSDSetSpecific(void *arg) {
 
 static void *__CFTSDGetSpecific() {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    return pthread_getspecific(CF_TSD_KEY);
+    return _pthread_getspecific_direct(CF_TSD_KEY);
 #elif DEPLOYMENT_TARGET_LINUX
     return pthread_getspecific(__CFTSDIndexKey);
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -1023,7 +1024,7 @@ struct timezone {
     int        tz_dsttime;     /* type of dst correction */
 };
 
-__private_extern__ int _NS_gettimeofday(struct timeval *tv, struct timezone *tz) {
+CF_PRIVATE int _NS_gettimeofday(struct timeval *tv, struct timezone *tz) {
     if (tv) {
         FILETIME ft;
         GetSystemTimeAsFileTime(&ft);
@@ -1077,6 +1078,10 @@ bool OSAtomicCompareAndSwap32Barrier(int32_t oldValue, int32_t newValue, volatil
     return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
 }
 
+bool OSAtomicCompareAndSwap64Barrier(int64_t oldValue, int64_t newValue, volatile int64_t *theValue) {
+    return __sync_bool_compare_and_swap(theValue, oldValue, newValue);
+}
+
 int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst)
 {
     return OSAtomicAdd32Barrier(-1, dst);
@@ -1103,6 +1108,13 @@ void OSMemoryBarrier() {
     __sync_synchronize();
 }
 
+#include <Block_private.h>
+
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) {
+    struct Block_layout *layout = (struct Block_layout *)block; 
+    pthread_once(predicate, (void (*)(void))layout->invoke);
+}
+
 #endif // DEPLOYMENT_TARGET_LINUX
 
 #pragma mark -
@@ -1112,7 +1124,7 @@ void OSMemoryBarrier() {
 
 #include <stdio.h>
 
-__private_extern__ int asprintf(char **ret, const char *format, ...) {
+CF_PRIVATE int asprintf(char **ret, const char *format, ...) {
     va_list args;
     size_t sz = 1024;
     *ret = (char *) malloc(sz * sizeof(char));
index b4b8d09c0739b8388d8bcc8ee3c6636f57e7dfb9..fc264d50813d9d4cdd00c33127261219bb3a4da0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlatformConverters.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -59,7 +59,7 @@ static const CFStringEncodingConverter __CFPlatformBootstrap = {
     NULL /* toUnicodeFallback */, NULL /* toBytesPrecompose */, NULL, /* isValidCombiningChar */
 };
 
-__private_extern__ const CFStringEncodingConverter *__CFStringEncodingGetExternalConverter(uint32_t encoding) {
+CF_PRIVATE const CFStringEncodingConverter *__CFStringEncodingGetExternalConverter(uint32_t encoding) {
 
     // we prefer Text Encoding Converter ICU since it's more reliable
     if (__CFIsPlatformConverterAvailable(encoding)) {
@@ -75,7 +75,7 @@ __private_extern__ const CFStringEncodingConverter *__CFStringEncodingGetExterna
 }
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-__private_extern__ CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) {
+CF_PRIVATE CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) {
 
     return NULL;
 }
@@ -101,7 +101,7 @@ static char CALLBACK __CFWin32EnumCodePageProc(LPTSTR string) {
     return true;
 }
 
-__private_extern__ CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) {
+CF_PRIVATE CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) {
     CFStringEncoding *encodings;
 
     EnumSystemCodePages((CODEPAGE_ENUMPROC)&__CFWin32EnumCodePageProc, CP_INSTALLED);
@@ -117,10 +117,10 @@ __private_extern__ CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlat
     return encodings;
 }
 #else
-__private_extern__ CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) { return NULL; }
+CF_PRIVATE CFStringEncoding *__CFStringEncodingCreateListOfAvailablePlatformConverters(CFAllocatorRef allocator, CFIndex *numberOfConverters) { return NULL; }
 #endif
 
-__private_extern__ CFIndex __CFStringEncodingPlatformUnicodeToBytes(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
+CF_PRIVATE CFIndex __CFStringEncodingPlatformUnicodeToBytes(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars, CFIndex *usedCharLen, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen) {
 
 #if DEPLOYMENT_TARGET_WINDOWS
     WORD dwFlags = 0;
@@ -171,7 +171,7 @@ __private_extern__ CFIndex __CFStringEncodingPlatformUnicodeToBytes(uint32_t enc
     return kCFStringEncodingConverterUnavailable;
 }
 
-__private_extern__ CFIndex __CFStringEncodingPlatformBytesToUnicode(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) {
+CF_PRIVATE CFIndex __CFStringEncodingPlatformBytesToUnicode(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, CFIndex *usedByteLen, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen) {
 
 #if DEPLOYMENT_TARGET_WINDOWS
     WORD dwFlags = 0;
@@ -216,12 +216,12 @@ __private_extern__ CFIndex __CFStringEncodingPlatformBytesToUnicode(uint32_t enc
     return kCFStringEncodingConverterUnavailable;
 }
 
-__private_extern__ CFIndex __CFStringEncodingPlatformCharLengthForBytes(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
+CF_PRIVATE CFIndex __CFStringEncodingPlatformCharLengthForBytes(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
     CFIndex usedCharLen;
     return (__CFStringEncodingPlatformBytesToUnicode(encoding, flags, bytes, numBytes, NULL, NULL, 0, &usedCharLen) == kCFStringEncodingConversionSuccess ? usedCharLen : 0);
 }
 
-__private_extern__ CFIndex __CFStringEncodingPlatformByteLengthForCharacters(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars) {
+CF_PRIVATE CFIndex __CFStringEncodingPlatformByteLengthForCharacters(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars) {
     CFIndex usedByteLen;
     return (__CFStringEncodingPlatformUnicodeToBytes(encoding, flags, characters, numChars, NULL, NULL, 0, &usedByteLen) == kCFStringEncodingConversionSuccess ? usedByteLen : 0);
 }
index 1a28795f831589c128fc5e0a47804816418849ce..c1e7b851e6544cadb03d097e3335ee030cda276c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*      CFPlugIn.c
-        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
@@ -35,7 +35,7 @@ CONST_STRING_DECL(kCFPlugInUnloadFunctionKey, "CFPlugInUnloadFunction")
 CONST_STRING_DECL(kCFPlugInFactoriesKey, "CFPlugInFactories")
 CONST_STRING_DECL(kCFPlugInTypesKey, "CFPlugInTypes")
 
-__private_extern__ void __CFPlugInInitialize(void) {
+CF_PRIVATE void __CFPlugInInitialize(void) {
 }
 
 /* ===================== Finding factories and creating instances ===================== */
index d51e0bef05f4516d300c8a202d914cc15fdb3c65..c440e00751b340a5440f10803e87159c8926e063 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGIN__)
@@ -43,16 +43,11 @@ CF_EXTERN_C_BEGIN
 
 /* ================ Standard Info.plist keys for plugIns ================ */
 
-CF_EXPORT
-const CFStringRef kCFPlugInDynamicRegistrationKey;
-CF_EXPORT
-const CFStringRef kCFPlugInDynamicRegisterFunctionKey;
-CF_EXPORT
-const CFStringRef kCFPlugInUnloadFunctionKey;
-CF_EXPORT
-const CFStringRef kCFPlugInFactoriesKey;
-CF_EXPORT
-const CFStringRef kCFPlugInTypesKey;
+CF_EXPORT const CFStringRef kCFPlugInDynamicRegistrationKey;
+CF_EXPORT const CFStringRef kCFPlugInDynamicRegisterFunctionKey;
+CF_EXPORT const CFStringRef kCFPlugInUnloadFunctionKey;
+CF_EXPORT const CFStringRef kCFPlugInFactoriesKey;
+CF_EXPORT const CFStringRef kCFPlugInTypesKey;
 
 /* ================= Function prototypes for various callbacks ================= */
 /* Function types that plugIn authors can implement for various purposes. */
@@ -63,15 +58,12 @@ typedef void *(*CFPlugInFactoryFunction)(CFAllocatorRef allocator, CFUUIDRef typ
 
 /* ================= Creating PlugIns ================= */
 
-CF_EXPORT
-CFTypeID CFPlugInGetTypeID(void);
+CF_EXPORT CFTypeID CFPlugInGetTypeID(void);
 
-CF_EXPORT
-CFPlugInRef CFPlugInCreate(CFAllocatorRef allocator, CFURLRef plugInURL);
+CF_EXPORT CFPlugInRef CFPlugInCreate(CFAllocatorRef allocator, CFURLRef plugInURL);
     /* Might return an existing instance with the ref-count bumped. */
 
-CF_EXPORT
-CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn);
+CF_EXPORT CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn);
 
 /* ================= Controlling load on demand ================= */
 /* For plugIns. */
@@ -79,56 +71,45 @@ CFBundleRef CFPlugInGetBundle(CFPlugInRef plugIn);
 /* PlugIns that do dynamic registration are not load on demand by default. */
 /* A dynamic registration function can call CFPlugInSetLoadOnDemand(). */
 
-CF_EXPORT
-void CFPlugInSetLoadOnDemand(CFPlugInRef plugIn, Boolean flag);
+CF_EXPORT void CFPlugInSetLoadOnDemand(CFPlugInRef plugIn, Boolean flag);
 
-CF_EXPORT
-Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn);
+CF_EXPORT Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn);
 
 /* ================= Finding factories and creating instances ================= */
 /* For plugIn hosts. */
 /* Functions for finding factories to create specific types and actually creating instances of a type. */
 
-CF_EXPORT
-CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeUUID);
-    /* This function finds all the factories from any plugin for the given type.  Returns an array that the caller must release. */
-    
-CF_EXPORT
-CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeUUID, CFPlugInRef plugIn);
-    /* This function restricts the result to factories from the given plug-in that can create the given type.  Returns an array that the caller must release. */
+/* This function finds all the factories from any plugin for the given type.  Returns an array that the caller must release. */
+CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeUUID) CF_RETURNS_RETAINED;
 
-CF_EXPORT
-void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
-    /* This function returns the IUnknown interface for the new instance. */
+
+/* This function restricts the result to factories from the given plug-in that can create the given type.  Returns an array that the caller must release. */
+CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeUUID, CFPlugInRef plugIn) CF_RETURNS_RETAINED;
+
+/* This function returns the IUnknown interface for the new instance. */
+CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
 
 /* ================= Registering factories and types ================= */
 /* For plugIn writers who must dynamically register things. */
 /* Functions to register factory functions and to associate factories with types. */
 
-CF_EXPORT
-Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryUUID, CFPlugInFactoryFunction func);
+CF_EXPORT Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryUUID, CFPlugInFactoryFunction func);
 
-CF_EXPORT
-Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryUUID, CFPlugInRef plugIn, CFStringRef functionName);
+CF_EXPORT Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryUUID, CFPlugInRef plugIn, CFStringRef functionName);
 
-CF_EXPORT
-Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryUUID);
+CF_EXPORT Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryUUID);
 
-CF_EXPORT
-Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+CF_EXPORT Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
 
-CF_EXPORT
-Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
+CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryUUID, CFUUIDRef typeUUID);
 
 /* ================= Registering instances ================= */
 /* When a new instance of a type is created, the instance is responsible for registering itself with the factory that created it and unregistering when it deallocates. */
 /* This means that an instance must keep track of the CFUUIDRef of the factory that created it so it can unregister when it goes away. */
 
-CF_EXPORT
-void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID);
+CF_EXPORT void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID);
 
-CF_EXPORT
-void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID);
+CF_EXPORT void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID);
 
 
 /* Obsolete API */
@@ -138,16 +119,16 @@ typedef struct __CFPlugInInstance *CFPlugInInstanceRef;
 typedef Boolean (*CFPlugInInstanceGetInterfaceFunction)(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl);
 typedef void (*CFPlugInInstanceDeallocateInstanceDataFunction)(void *instanceData);
 
-CF_EXPORT
-Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl);
-CF_EXPORT
-CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance);
-CF_EXPORT
-void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance);
-CF_EXPORT
-CFTypeID CFPlugInInstanceGetTypeID(void);
-CF_EXPORT
-CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction);
+CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef instance, CFStringRef interfaceName, void **ftbl);
+
+/* This function returns a retained object on 10.8 or later. */
+CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) CF_RETURNS_RETAINED;
+
+CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance);
+
+CF_EXPORT CFTypeID CFPlugInInstanceGetTypeID(void);
+
+CF_EXPORT CFPlugInInstanceRef CFPlugInInstanceCreateWithInstanceDataSize(CFAllocatorRef allocator, CFIndex instanceDataSize, CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceFunction, CFStringRef factoryName, CFPlugInInstanceGetInterfaceFunction getInterfaceFunction);
 
 CF_EXTERN_C_END
 
index cc41e52dfc1ed1a654235216182da05215f6e8ec..b06469e1579741edc2b565a66561cf0d076c479a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugInCOM.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGINCOM__)
index b65a86a63d4c95441b644d8ab43d6d60aff88f41..82e59b46e4b8b823738ed6617bf031b115409480 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn_Factory.c
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
@@ -61,7 +61,7 @@ static const CFRuntimeClass __CFPFactoryClass = {
     NULL,       // debug desc
 };
 
-__private_extern__ void __CFPFactoryInitialize(void) {
+CF_PRIVATE void __CFPFactoryInitialize(void) {
     __kCFPFactoryTypeID = _CFRuntimeRegisterClass(&__CFPFactoryClass);
 }
 
@@ -104,7 +104,7 @@ static void _CFPFactoryRemoveFromTable(_CFPFactoryRef factory) {
     if (uuid) CFRelease(uuid);
 }
 
-__private_extern__ _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
+CF_PRIVATE _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
     _CFPFactoryRef result = NULL;
     
     __CFSpinLock(&CFPlugInGlobalDataLock);
@@ -153,7 +153,7 @@ static _CFPFactoryRef _CFPFactoryCommonCreate(CFAllocatorRef allocator, CFUUIDRe
     return factory;
 }
 
-__private_extern__ _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
+CF_PRIVATE _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
     _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);
 
     __CFSpinLock(&factory->_lock);    
@@ -165,7 +165,7 @@ __private_extern__ _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CF
     return factory;
 }
 
-__private_extern__ _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
+CF_PRIVATE _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
     _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);
 
     __CFSpinLock(&factory->_lock);    
@@ -178,7 +178,7 @@ __private_extern__ _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocat
     return factory;
 }
 
-__private_extern__ CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory) {
+CF_PRIVATE CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory) {
     __CFSpinLock(&factory->_lock);
     CFUUIDRef uuid = factory->_uuid;
     if (uuid) CFRetain(uuid);
@@ -186,7 +186,7 @@ __private_extern__ CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory) {
     return uuid;
 }
 
-__private_extern__ CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory) {
+CF_PRIVATE CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory) {
     __CFSpinLock(&factory->_lock);
     CFPlugInRef result = factory->_plugIn;
     if (result) CFRetain(result);
@@ -194,7 +194,7 @@ __private_extern__ CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory) {
     return result;
 }
 
-__private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) {
+CF_PRIVATE void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) {
     void *result = NULL;
 
     __CFSpinLock(&factory->_lock);
@@ -219,14 +219,14 @@ __private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CF
     return result;
 }
 
-__private_extern__ void _CFPFactoryDisable(_CFPFactoryRef factory) {
+CF_PRIVATE void _CFPFactoryDisable(_CFPFactoryRef factory) {
     __CFSpinLock(&factory->_lock);    
     factory->_enabled = false;
     __CFSpinUnlock(&factory->_lock);
     CFRelease(factory);
 }
 
-__private_extern__ void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory) {
+CF_PRIVATE void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory) {
     /* MF:!!! Assert that this factory belongs to a plugIn. */
     /* This is called by the factory's plugIn when the plugIn unloads its code. */
     __CFSpinLock(&factory->_lock);
@@ -234,7 +234,7 @@ __private_extern__ void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory) {
     __CFSpinUnlock(&factory->_lock);
 }
 
-__private_extern__ void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID) {
+CF_PRIVATE void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID) {
     /* Add the factory to the type's array of factories */
     __CFSpinLock(&factory->_lock);
     /* Add the type to the factory's type list */
@@ -255,7 +255,7 @@ __private_extern__ void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typ
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
 }
 
-__private_extern__ void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID) {
+CF_PRIVATE void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID) {
     /* Remove it from the factory's type list */
     SInt32 idx;
 
@@ -279,7 +279,7 @@ __private_extern__ void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
 }
 
-__private_extern__ Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID) {
+CF_PRIVATE Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID) {
     SInt32 idx;
 
     __CFSpinLock(&factory->_lock);
@@ -289,7 +289,7 @@ __private_extern__ Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUI
     return (idx >= 0 ? true : false);
 }
 
-__private_extern__ CFArrayRef _CFPFactoryFindCopyForType(CFUUIDRef typeID) {
+CF_PRIVATE CFArrayRef _CFPFactoryFindCopyForType(CFUUIDRef typeID) {
     CFArrayRef result = NULL;
     __CFSpinLock(&CFPlugInGlobalDataLock);
     if (_factoriesByTypeID) {
@@ -302,7 +302,7 @@ __private_extern__ CFArrayRef _CFPFactoryFindCopyForType(CFUUIDRef typeID) {
 }
 
 /* These methods are called by CFPlugInInstance when an instance is created or destroyed.  If a factory's instance count goes to 0 and the factory has been disabled, the factory is destroyed. */
-__private_extern__ void _CFPFactoryAddInstance(_CFPFactoryRef factory) {
+CF_PRIVATE void _CFPFactoryAddInstance(_CFPFactoryRef factory) {
     /* MF:!!! Assert that factory is enabled. */
     CFRetain(factory);
     __CFSpinLock(&factory->_lock);
@@ -315,7 +315,7 @@ __private_extern__ void _CFPFactoryAddInstance(_CFPFactoryRef factory) {
     }    
 }
 
-__private_extern__ void _CFPFactoryRemoveInstance(_CFPFactoryRef factory) {
+CF_PRIVATE void _CFPFactoryRemoveInstance(_CFPFactoryRef factory) {
     __CFSpinLock(&factory->_lock);
     CFPlugInRef plugin = factory->_plugIn;
     if (plugin) CFRetain(plugin);
index 2b4320a57212f7f070e1162c38e6669d0fc95e84..8f94abf59afe7c9677fca42268af128ebd2b94e7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn_Factory.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGIN_FACTORY__)
index afc17eb1c2231edc30549cc09566d362c032c99c..252b45a5bececca8b9d2587f3f461ead009af3b3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn_Instance.c
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
@@ -79,7 +79,7 @@ static const CFRuntimeClass __CFPlugInInstanceClass = {
     __CFPlugInInstanceCopyDescription
 };
 
-__private_extern__ void __CFPlugInInstanceInitialize(void) {
+CF_PRIVATE void __CFPlugInInstanceInitialize(void) {
     __kCFPlugInInstanceTypeID = _CFRuntimeRegisterClass(&__CFPlugInInstanceClass);
 }
 
@@ -115,7 +115,8 @@ CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef
 }
 
 CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) {
-    // This function leaks, but it's the only safe way to access the factory name
+    // This function leaks, but it's the only safe way to access the factory name (on 10.8 or later).
+    // On 10.9 we added the CF_RETURNS_RETAINED annotation to the header.
     CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(instance->factory);
     return (CFStringRef)factoryId;
 }
index c922f8cf45e250fe36d6088f49203f86c3a11261..6ba9a072e74489e34ed57a8b28014f665a447c0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*      CFPlugIn_PlugIn.c
-        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
         Responsibility: Tony Parker
 */
 
@@ -66,7 +66,7 @@ static void _registerType(const void *key, const void *val, void *context) {
     if (typeID) CFRelease(typeID);
 }
 
-__private_extern__ Boolean _CFBundleNeedsInitPlugIn(CFBundleRef bundle) {
+CF_PRIVATE Boolean _CFBundleNeedsInitPlugIn(CFBundleRef bundle) {
     Boolean result = false;
     CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle), factoryDict;
     CFStringRef tempStr;
@@ -79,7 +79,7 @@ __private_extern__ Boolean _CFBundleNeedsInitPlugIn(CFBundleRef bundle) {
     return result;
 }
 
-__private_extern__ void _CFBundleInitPlugIn(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleInitPlugIn(CFBundleRef bundle) {
     CFArrayCallBacks _pluginFactoryArrayCallbacks = {0, NULL, NULL, NULL, NULL};
     Boolean doDynamicReg = false;
     CFDictionaryRef infoDict;
@@ -119,7 +119,7 @@ __private_extern__ void _CFBundleInitPlugIn(CFBundleRef bundle) {
     }
 }
 
-__private_extern__ void _CFBundlePlugInLoaded(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundlePlugInLoaded(CFBundleRef bundle) {
     CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
     CFStringRef tempStr;
     CFPlugInDynamicRegisterFunction func = NULL;
@@ -148,7 +148,7 @@ __private_extern__ void _CFBundlePlugInLoaded(CFBundleRef bundle) {
     }
 }
 
-__private_extern__ void _CFBundleDeallocatePlugIn(CFBundleRef bundle) {
+CF_PRIVATE void _CFBundleDeallocatePlugIn(CFBundleRef bundle) {
     if (__CFBundleGetPlugInData(bundle)->_isPlugIn) {
         SInt32 c;
 
@@ -196,7 +196,7 @@ Boolean CFPlugInIsLoadOnDemand(CFPlugInRef plugIn) {
     }
 }
 
-__private_extern__ void _CFPlugInWillUnload(CFPlugInRef plugIn) {
+CF_PRIVATE void _CFPlugInWillUnload(CFPlugInRef plugIn) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
         SInt32 c = CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories);
         /* First, flush all the function pointers that may be cached by our factories. */
@@ -204,7 +204,7 @@ __private_extern__ void _CFPlugInWillUnload(CFPlugInRef plugIn) {
     }
 }
 
-__private_extern__ void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn) {
+CF_PRIVATE void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
         if (__CFBundleGetPlugInData(plugIn)->_instanceCount == 0 && __CFBundleGetPlugInData(plugIn)->_loadOnDemand) _CFBundleUnscheduleForUnloading(CFPlugInGetBundle(plugIn));     // Make sure we are not scheduled for unloading
         __CFBundleGetPlugInData(plugIn)->_instanceCount++;
@@ -213,7 +213,7 @@ __private_extern__ void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn) {
     }
 }
 
-__private_extern__ void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) {
+CF_PRIVATE void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
         /* MF:!!! Assert that instanceCount > 0. */
         __CFBundleGetPlugInData(plugIn)->_instanceCount--;
@@ -228,11 +228,11 @@ __private_extern__ void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) {
     }
 }
 
-__private_extern__ void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) {
+CF_PRIVATE void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) CFArrayAppendValue(__CFBundleGetPlugInData(plugIn)->_factories, factory);
 }
 
-__private_extern__ void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) {
+CF_PRIVATE void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) {
         SInt32 idx = CFArrayGetFirstIndexOfValue(__CFBundleGetPlugInData(plugIn)->_factories, CFRangeMake(0, CFArrayGetCount(__CFBundleGetPlugInData(plugIn)->_factories)), factory);
         if (idx >= 0) CFArrayRemoveValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, idx);
index 5364c3433c8bdb86bf24a247df58b95aadce8dae..50637c4a03a2d7259544f05df9478c02ad844bf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPreferences.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -67,7 +67,7 @@ CONST_STRING_DECL(kCFPreferencesCurrentUser, "kCFPreferencesCurrentUser")
 
 
 static CFAllocatorRef _preferencesAllocator = NULL;
-__private_extern__ CFAllocatorRef __CFPreferencesAllocator(void) {
+CF_PRIVATE CFAllocatorRef __CFPreferencesAllocator(void) {
     if (!_preferencesAllocator) {
 #if DEBUG_PREFERENCES_MEMORY
         _preferencesAllocator = CFCountingAllocatorCreate(NULL);
@@ -103,7 +103,7 @@ CF_EXPORT void CFPreferencesDumpMem(void) {
 // If this becomes available in a header (<rdar://problem/4943036>), I need to pull this out
 int gethostuuid(unsigned char *uuid_buf, const struct timespec *timeoutp);
 
-__private_extern__ CFStringRef _CFGetHostUUIDString(void) {
+CF_PRIVATE CFStringRef _CFGetHostUUIDString(void) {
     static CFStringRef __hostUUIDString = NULL;
     
     if (!__hostUUIDString) {
@@ -131,7 +131,7 @@ __private_extern__ CFStringRef _CFGetHostUUIDString(void) {
     return __hostUUIDString;
 }
 
-__private_extern__ CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
+CF_PRIVATE CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
     static CFStringRef __byHostIdentifierString = NULL;
 
     if (!__byHostIdentifierString) {
@@ -164,7 +164,7 @@ __private_extern__ CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
 
 #else
 
-__private_extern__ CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
+CF_PRIVATE CFStringRef _CFPreferencesGetByHostIdentifierString(void) {
     return CFSTR("");
 }
 
@@ -425,7 +425,7 @@ static const CFRuntimeClass __CFPreferencesDomainClass = {
 };
 
 /* This is called once at CFInitialize() time. */
-__private_extern__ void __CFPreferencesDomainInitialize(void) {
+CF_PRIVATE void __CFPreferencesDomainInitialize(void) {
     __kCFPreferencesDomainTypeID = _CFRuntimeRegisterClass(&__CFPreferencesDomainClass);
 }
 
@@ -571,7 +571,7 @@ static void __CFPreferencesPerformSynchronize(const void *key, const void *value
     if (!_CFPreferencesDomainSynchronize(domain)) *cumulativeResult = false;
 }
 
-__private_extern__ Boolean _CFSynchronizeDomainCache(void) {
+CF_PRIVATE Boolean _CFSynchronizeDomainCache(void) {
     Boolean result = true;
     __CFSpinLock(&domainCacheLock);
     if (domainCache) {
@@ -581,7 +581,7 @@ __private_extern__ Boolean _CFSynchronizeDomainCache(void) {
     return result;
 }
 
-__private_extern__ void _CFPreferencesPurgeDomainCache(void) {
+CF_PRIVATE void _CFPreferencesPurgeDomainCache(void) {
     _CFSynchronizeDomainCache();
     __CFSpinLock(&domainCacheLock);
     if (domainCache) {
@@ -591,7 +591,7 @@ __private_extern__ void _CFPreferencesPurgeDomainCache(void) {
     __CFSpinUnlock(&domainCacheLock);
 }
 
-__private_extern__ CFArrayRef  _CFPreferencesCreateDomainList(CFStringRef  userName, CFStringRef  hostName) {
+CF_PRIVATE CFArrayRef  _CFPreferencesCreateDomainList(CFStringRef  userName, CFStringRef  hostName) {
     CFAllocatorRef prefAlloc = __CFPreferencesAllocator();
     CFArrayRef  domains;
     CFMutableArrayRef  marray;
@@ -715,17 +715,17 @@ void _CFPreferencesDomainSet(CFPreferencesDomainRef domain, CFStringRef  key, CF
     domain->_callBacks->writeValue(domain->_context, domain->_domain, key, value);
 }
 
-__private_extern__ Boolean _CFPreferencesDomainSynchronize(CFPreferencesDomainRef domain) {
+CF_PRIVATE Boolean _CFPreferencesDomainSynchronize(CFPreferencesDomainRef domain) {
     return domain->_callBacks->synchronize(domain->_context, domain->_domain);
 }
 
-__private_extern__ void _CFPreferencesDomainSetIsWorldReadable(CFPreferencesDomainRef domain, Boolean isWorldReadable) {
+CF_PRIVATE void _CFPreferencesDomainSetIsWorldReadable(CFPreferencesDomainRef domain, Boolean isWorldReadable) {
     if (domain->_callBacks->setIsWorldReadable) {
         domain->_callBacks->setIsWorldReadable(domain->_context, domain->_domain, isWorldReadable);
     }
 }
 
-__private_extern__ void *_CFPreferencesDomainCopyDictFunc(CFPreferencesDomainRef domain) {
+CF_PRIVATE void *_CFPreferencesDomainCopyDictFunc(CFPreferencesDomainRef domain) {
     return domain->_callBacks->copyDomainDictionary;
 }
 
index 9a59a265a927f261c3994f6a293335257dab9ab3..aa2c15496a3afdde55904ac3e68a961099fc5ae7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPreferences.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPREFERENCES__)
@@ -129,7 +129,7 @@ which have preferences in the scope of the given user and host.
 The returned value must be released by the caller; neither argument
 may be NULL. */
 CF_EXPORT
-CFArrayRef CFPreferencesCopyApplicationList(CFStringRef userName, CFStringRef hostName);
+CFArrayRef CFPreferencesCopyApplicationList(CFStringRef userName, CFStringRef hostName) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
 /* Constructs and returns the list of all keys set in the given
 location.  The returned value must be released by the caller;
index 3ce670281a5313c23591d936fb1a48bef60424fe..6957d7a1b64a8883f23493911344764759c17768 100644 (file)
--- a/CFPriv.h
+++ b/CFPriv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPriv.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*
@@ -46,6 +46,7 @@
 
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
 #include <CoreFoundation/CFMachPort.h>
+#include <CoreFoundation/CFMessagePort.h>
 #endif
 
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32
@@ -85,6 +86,8 @@ CF_EXPORT CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef all
 
 CF_EXPORT void CFPreferencesFlushCaches(void);
 
+
+
 #if TARGET_OS_WIN32
 CF_EXPORT Boolean _CFURLGetWideFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, wchar_t *buffer, CFIndex bufferLength);
 #endif
@@ -222,6 +225,7 @@ typedef CF_OPTIONS(CFOptionFlags, CFSearchPathDomainMask) {
 CF_EXPORT
 CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directory, CFSearchPathDomainMask domainMask, Boolean expandTilde);
 
+
 /* Obsolete keys */
 CF_EXPORT const CFStringRef kCFFileURLExists;
 CF_EXPORT const CFStringRef kCFFileURLPOSIXMode;
@@ -304,8 +308,8 @@ extern UniChar __CFCharToUniCharTable[256];
 CF_INLINE const UniChar *CFStringGetCharactersPtrFromInlineBuffer(CFStringInlineBuffer *buf, CFRange desiredRange) {
     if ((desiredRange.location < 0) || ((desiredRange.location + desiredRange.length) > buf->rangeToBuffer.length)) return NULL;
 
-    if (buf->directBuffer) {
-        return buf->directBuffer + buf->rangeToBuffer.location + desiredRange.location;
+    if (buf->directUniCharBuffer) {
+        return buf->directUniCharBuffer + buf->rangeToBuffer.location + desiredRange.location;
     } else {
         if (desiredRange.length > __kCFStringInlineBufferLength) return NULL;
 
@@ -313,7 +317,14 @@ CF_INLINE const UniChar *CFStringGetCharactersPtrFromInlineBuffer(CFStringInline
             buf->bufferedRangeStart = desiredRange.location;
             buf->bufferedRangeEnd = buf->bufferedRangeStart + __kCFStringInlineBufferLength;
             if (buf->bufferedRangeEnd > buf->rangeToBuffer.length) buf->bufferedRangeEnd = buf->rangeToBuffer.length;
-            CFStringGetCharacters(buf->theString, CFRangeMake(buf->rangeToBuffer.location + buf->bufferedRangeStart, buf->bufferedRangeEnd - buf->bufferedRangeStart), buf->buffer);
+            CFIndex location = buf->rangeToBuffer.location + buf->bufferedRangeStart;
+            CFIndex length = buf->bufferedRangeEnd - buf->bufferedRangeStart;
+            if (buf->directCStringBuffer) {
+                UniChar *bufPtr = buf->buffer;
+                while (length--) *bufPtr++ = (UniChar)buf->directCStringBuffer[location++];
+            } else {
+                CFStringGetCharacters(buf->theString, CFRangeMake(location, length), buf->buffer);
+            }
         }
 
         return buf->buffer + (desiredRange.location - buf->bufferedRangeStart);
@@ -321,8 +332,8 @@ CF_INLINE const UniChar *CFStringGetCharactersPtrFromInlineBuffer(CFStringInline
 }
 
 CF_INLINE void CFStringGetCharactersFromInlineBuffer(CFStringInlineBuffer *buf, CFRange desiredRange, UniChar *outBuf) {
-    if (buf->directBuffer) {
-        memmove(outBuf, buf->directBuffer + buf->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar));
+    if (buf->directUniCharBuffer) {
+        memmove(outBuf, buf->directUniCharBuffer + buf->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar));
     } else {
         if ((desiredRange.location >= buf->bufferedRangeStart) && (desiredRange.location < buf->bufferedRangeEnd)) {
             CFIndex bufLen = desiredRange.length;
@@ -340,19 +351,103 @@ CF_INLINE void CFStringGetCharactersFromInlineBuffer(CFStringInlineBuffer *buf,
             }
         }
 
-        if (desiredRange.length > 0) CFStringGetCharacters(buf->theString, CFRangeMake(buf->rangeToBuffer.location + desiredRange.location, desiredRange.length), outBuf);
+        if (desiredRange.length > 0) {
+            CFIndex location = buf->rangeToBuffer.location + desiredRange.location;
+            CFIndex length = desiredRange.length;
+            if (buf->directCStringBuffer) {
+                UniChar *bufPtr = outBuf;
+                while (length--) *bufPtr++ = (UniChar)buf->directCStringBuffer[location++];
+            } else {
+                CFStringGetCharacters(buf->theString, CFRangeMake(location, length), outBuf);
+            }
+        }
     }
 }
 
 #else
-#define CFStringGetCharactersPtrFromInlineBuffer(buf, desiredRange) ((buf)->directBuffer ? (buf)->directBuffer + (buf)->rangeToBuffer.location + desiredRange.location : NULL)
+#define CFStringGetCharactersPtrFromInlineBuffer(buf, desiredRange) ((buf)->directUniCharBuffer ? (buf)->directUniCharBuffer + (buf)->rangeToBuffer.location + desiredRange.location : NULL)
 
 #define CFStringGetCharactersFromInlineBuffer(buf, desiredRange, outBuf) \
-    if (buf->directBuffer) memmove(outBuf, (buf)->directBuffer + (buf)->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar)); \
+    if (buf->directUniCharBuffer) memmove(outBuf, (buf)->directUniCharBuffer + (buf)->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar)); \
     else CFStringGetCharacters((buf)->theString, CFRangeMake((buf)->rangeToBuffer.location + desiredRange.location, desiredRange.length), outBuf);
 
 #endif /* CF_INLINE */
 
+
+#if defined(CF_INLINE)
+
+#ifndef __kCFStringAppendBufferLength
+    #define __kCFStringAppendBufferLength 1024
+#endif
+typedef struct {
+    UniChar buffer[__kCFStringAppendBufferLength];
+    CFIndex bufferIndex;
+    CFMutableStringRef theString;
+} CFStringAppendBuffer;
+
+
+// Initializes CFStringAppendBuffer with new mutable string.
+CF_INLINE void CFStringInitAppendBuffer(CFAllocatorRef alloc, CFStringAppendBuffer *buf)
+{
+    buf->bufferIndex = 0;
+    buf->theString = CFStringCreateMutable(alloc, 0);
+}
+
+// Appends the characters of a string to the CFStringAppendBuffer.
+CF_INLINE void CFStringAppendStringToAppendBuffer(CFStringAppendBuffer *buf, CFStringRef appendedString)
+{
+    CFIndex numChars = CFStringGetLength(appendedString);
+    if ( numChars > __kCFStringAppendBufferLength ) {
+        if ( buf->bufferIndex ) {
+            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
+            buf->bufferIndex = 0;
+        }
+        CFStringAppend(buf->theString, appendedString);
+    }
+    else {
+        if ( (buf->bufferIndex + numChars) > __kCFStringAppendBufferLength ) {
+            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
+            buf->bufferIndex = 0;
+        }
+        CFStringGetCharacters(appendedString, CFRangeMake(0, numChars), &buf->buffer[buf->bufferIndex]);
+        buf->bufferIndex += numChars;
+    }
+}
+
+// Appends a buffer of Unicode characters to the CFStringAppendBuffer.
+CF_INLINE void CFStringAppendCharactersToAppendBuffer(CFStringAppendBuffer *buf, const UniChar *chars, CFIndex numChars)
+{
+    if ( numChars > __kCFStringAppendBufferLength ) {
+        if ( buf->bufferIndex ) {
+            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
+            buf->bufferIndex = 0;
+        }
+        CFStringAppendCharacters(buf->theString, chars, numChars);
+    }
+    else {
+        if ( (buf->bufferIndex + numChars) > __kCFStringAppendBufferLength ) {
+            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
+            buf->bufferIndex = 0;
+        }
+        memcpy(&buf->buffer[buf->bufferIndex], chars, numChars * sizeof(UniChar));
+        buf->bufferIndex += numChars;
+    }
+}
+
+// Returns a mutable string from the CFStringAppendBuffer.
+CF_INLINE CFMutableStringRef CFStringCreateMutableWithAppendBuffer(CFStringAppendBuffer *buf)
+{
+    if ( buf->bufferIndex ) {
+        CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
+        buf->bufferIndex = 0;
+    }
+    CFMutableStringRef result = buf->theString;
+    buf->theString = NULL;
+    return ( result );
+}
+
+#endif /* CF_INLINE */
+
 /*
  CFCharacterSetInlineBuffer related declarations
  */
@@ -513,6 +608,8 @@ CF_EXPORT bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFData
 // Returns a subset of the property list, only including the keyPaths in the CFSet. If the top level object is not a dictionary, you will get back an empty dictionary as the result.
 CF_EXPORT bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) CF_AVAILABLE(10_8, 6_0);
 
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32
+
 // Returns a subset of a bundle's Info.plist. The keyPaths follow the same rules as above CFPropertyList function. This function takes platform and product keys into account.
 typedef CF_OPTIONS(CFOptionFlags, _CFBundleFilteredPlistOptions) {
     _CFBundleFilteredPlistMemoryMapped = 1
@@ -520,6 +617,7 @@ typedef CF_OPTIONS(CFOptionFlags, _CFBundleFilteredPlistOptions) {
 
 CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) CF_AVAILABLE(10_8, 6_0);
 CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredLocalizedInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, CFStringRef localizationName, _CFBundleFilteredPlistOptions options) CF_AVAILABLE(10_8, 6_0);
+#endif
 
 #if TARGET_OS_WIN32
 #include <CoreFoundation/CFNotificationCenter.h>
@@ -552,6 +650,9 @@ CF_EXPORT CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRe
 CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
 #endif
 
+CF_EXPORT const CFStringRef kCFNumberFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);  // CFBoolean
+CF_EXPORT const CFStringRef kCFDateFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);    // CFBoolean
+
 
 CF_EXTERN_C_END
 
index b22218c5dff126678ec50a1eb8a350708992808e..0ff03e445b09059fc182a3bdcc34aa6fb715f8da 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPropertyList.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -49,6 +49,9 @@
 #include <math.h>
 #include <ctype.h>
 
+
+CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);
+
 #define PLIST_IX    0
 #define ARRAY_IX    1
 #define DICT_IX     2
@@ -88,7 +91,7 @@
     if (N ## _count__ == 0) N ## _count__ = 1; \
     STACK_BUFFER_DECL(CFTypeRef, N ## _buffer__, N ## _is_stack__ ? N ## _count__ : 1); \
     if (N ## _is_stack__) memset(N ## _buffer__, 0, N ## _count__ * sizeof(CFTypeRef)); \
-    CFTypeRef * N = N ## _is_stack__ ? N ## _buffer__ : (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, (N ## _count__) * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory); \
+    CFTypeRef * N = N ## _is_stack__ ? N ## _buffer__ : (CFTypeRef *)CFAllocatorAllocate(kCFAllocatorSystemDefault, (N ## _count__) * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory); \
     if (! N) { \
         CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); \
         HALT; \
 #if !defined(free_cftype_array)
 #define free_cftype_array(N) \
     if (! N ## _is_stack__) { \
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFAllocatorDeallocate(kCFAllocatorSystemDefault, N); \
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, N); \
     } \
     do {} while (0)
 #endif
@@ -125,7 +128,7 @@ static void initStatics() {
     });
 }
 
-__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...) {    
+CF_PRIVATE CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...) {    
     va_list argList;        
     CFErrorRef error = NULL;
     
@@ -153,8 +156,13 @@ static CFStringRef __copyErrorDebugDescription(CFErrorRef error) {
     CFStringRef result = NULL;
     if (error) {
         CFDictionaryRef userInfo = CFErrorCopyUserInfo(error);
-        result = CFStringCreateCopy(kCFAllocatorSystemDefault, (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey));
-        CFRelease(userInfo);
+        if (userInfo != NULL) {
+            CFStringRef desc = (CFStringRef) CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
+            if (desc != NULL) {
+                result = CFStringCreateCopy(kCFAllocatorSystemDefault, desc);
+            }
+            CFRelease(userInfo);
+        }
     }
     return result;
 }
@@ -243,9 +251,9 @@ static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive,
 static Boolean _CFPropertyListIsValidWithErrorString(CFPropertyListRef plist, CFPropertyListFormat format, CFStringRef *error) {
     initStatics();
     CFAssert1(plist != NULL, __kCFLogAssertion, "%s(): NULL is not a property list", __PRETTY_FUNCTION__);
-    CFMutableSetRef set = CFSetCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, NULL);
+    CFMutableSetRef set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
     bool result = __CFPropertyListIsValidAux(plist, true, set, format, error);
-    if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(set);
+    CFRelease(set);
     return result;
 }
 
@@ -298,10 +306,10 @@ typedef struct {
     Boolean skip; // if true, do not create any objects.
 } _CFXMLPlistParseInfo;
 
-__private_extern__ CFTypeRef __CFParseOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format);
+CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format);
 
 CF_INLINE void __CFPListRelease(CFTypeRef cf, CFAllocatorRef allocator) {
-    if (cf && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(cf);
+    if (cf && !(0)) CFRelease(cf);
 }
 
 
@@ -690,7 +698,7 @@ CF_EXPORT CFDataRef _CFPropertyListCreateXMLDataWithExtras(CFAllocatorRef alloca
 Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat format) {
     initStatics();
     CFAssert1(plist != NULL, __kCFLogAssertion, "%s(): NULL is not a property list", __PRETTY_FUNCTION__);
-    CFMutableSetRef set = CFSetCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, NULL);
+    CFMutableSetRef set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
     CFStringRef error = NULL;
     bool result = __CFPropertyListIsValidAux(plist, true, set, format, &error);
     if (error) {
@@ -699,7 +707,7 @@ Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat form
 #endif
        CFRelease(error);
     }
-    if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(set);
+    CFRelease(set);
     return result;
 }
 
@@ -1071,8 +1079,6 @@ static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableDataRe
     CFDataAppendBytes(stringData, (const UInt8 *)&ch, 1);
 }
 
-extern void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len);
-
 static void _createStringMap(_CFXMLPlistParseInfo *pInfo) {
     pInfo->stringTrie = CFBurstTrieCreate();
     pInfo->stringCache = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
@@ -1080,24 +1086,31 @@ static void _createStringMap(_CFXMLPlistParseInfo *pInfo) {
 
 static void _cleanupStringMap(_CFXMLPlistParseInfo *pInfo) {
     CFBurstTrieRelease(pInfo->stringTrie);
-    if (!_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRelease(pInfo->stringCache);
+    CFRelease(pInfo->stringCache);
+    pInfo->stringTrie = NULL;
+    pInfo->stringCache = NULL;
 }
 
-static CFStringRef _uniqueStringForUTF8Bytes(_CFXMLPlistParseInfo *pInfo, const char *base, CFIndex length) {
-    if (length == 0) return !_CFAllocatorIsGCRefZero(pInfo->allocator) ? (CFStringRef)CFRetain(CFSTR("")) : CFSTR("");    
+static CFStringRef _createUniqueStringWithUTF8Bytes(_CFXMLPlistParseInfo *pInfo, const char *base, CFIndex length) {
+    if (length == 0) return !(0) ? (CFStringRef)CFRetain(CFSTR("")) : CFSTR("");    
     
     CFStringRef result = NULL;
     uint32_t payload = 0;
     Boolean uniqued = CFBurstTrieContainsUTF8String(pInfo->stringTrie, (UInt8 *)base, length, &payload);
-    if (uniqued) {
-        result = (CFStringRef)CFArrayGetValueAtIndex(pInfo->stringCache, (CFIndex)payload);
-        if (!_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(result);
+    if (uniqued && payload > 0) {
+        // The index is at payload - 1 (see below).
+        result = (CFStringRef)CFArrayGetValueAtIndex(pInfo->stringCache, (CFIndex)payload - 1);
+        CFRetain(result);
     } else {
         result = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)base, length, kCFStringEncodingUTF8, NO);
         if (!result) return NULL;
-        payload = CFArrayGetCount(pInfo->stringCache);
-        CFArrayAppendValue(pInfo->stringCache, result);
-        CFBurstTrieAddUTF8String(pInfo->stringTrie, (UInt8 *)base, length, payload);
+        // Payload must be >0, so the actual index of the value is at payload - 1
+        // We also get add to the array after we make sure that CFBurstTrieAddUTF8String succeeds (it can fail, if the string is too large, for example)
+        payload = CFArrayGetCount(pInfo->stringCache) + 1;
+        Boolean didAddToBurstTrie = CFBurstTrieAddUTF8String(pInfo->stringTrie, (UInt8 *)base, length, payload);
+        if (didAddToBurstTrie) {
+            CFArrayAppendValue(pInfo->stringCache, result);
+        }
     }
     return result;
 }
@@ -1136,7 +1149,7 @@ static Boolean parseStringTag(_CFXMLPlistParseInfo *pInfo, CFStringRef *out) {
             *out = NULL;
         } else {
             if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-                CFStringRef s = _uniqueStringForUTF8Bytes(pInfo, mark, pInfo->curr - mark);
+                CFStringRef s = _createUniqueStringWithUTF8Bytes(pInfo, mark, pInfo->curr - mark);
                 if (!s) {
                     pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                     return false;
@@ -1159,7 +1172,7 @@ static Boolean parseStringTag(_CFXMLPlistParseInfo *pInfo, CFStringRef *out) {
         } else {
             CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
             if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-                CFStringRef s = _uniqueStringForUTF8Bytes(pInfo, (const char *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData));
+                CFStringRef s = _createUniqueStringWithUTF8Bytes(pInfo, (const char *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData));
                 if (!s) {
                     pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
                     return false;
@@ -1275,7 +1288,7 @@ static CFSetRef createTopLevelKeypaths(CFAllocatorRef allocator, CFSetRef keyPat
 }
 
 // This splits up the keypaths into the ones relevant for this level (of array or dictionary), and the ones for the next level (of array or dictionary)
-__private_extern__ void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys) {
+CF_PRIVATE void __CFPropertyListCreateSplitKeypaths(CFAllocatorRef allocator, CFSetRef currentKeys, CFSetRef *theseKeys, CFSetRef *nextKeys) {
     if (!currentKeys) { *theseKeys = NULL; *nextKeys = NULL; return; }
     
     CFIndex count = CFSetGetCount(currentKeys);
@@ -1529,6 +1542,7 @@ static Boolean parseDictTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
         return true;
     }
     
+    if (dict) __CFPListRelease(dict, pInfo->allocator);
     return false;
 }
 
@@ -1622,11 +1636,15 @@ static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
 
 CF_INLINE Boolean read2DigitNumber(_CFXMLPlistParseInfo *pInfo, int32_t *result) {
     char ch1, ch2;
-    if (pInfo->curr + 2 >= pInfo->end) return false;
+    if (pInfo->curr + 2 >= pInfo->end) {
+        return false;
+    }
     ch1 = *pInfo->curr;
     ch2 = *(pInfo->curr + 1);
     pInfo->curr += 2;
-    if (!isdigit(ch1) || !isdigit(ch2)) return false;
+    if (!isdigit(ch1) || !isdigit(ch2)) {
+        return false;
+    }
     *result = (ch1 - '0')*10 + (ch2 - '0');
     return true;
 }
@@ -1794,12 +1812,12 @@ CF_INLINE bool isWhitespace(const char *utf8bytes, const char *end) {
      3000 -> <e38080>
      */
     // Except we consider some additional values from 0x0 to 0x21 and 0x7E to 0xA1 as whitespace, for compatability
-    char byte1 = *utf8bytes;
+    unsigned char byte1 = *utf8bytes;
     if (byte1 < 0x21 || (byte1 > 0x7E && byte1 < 0xA1)) return true;
     if ((byte1 == 0xe2 || byte1 == 0xe3) && (end - utf8bytes >= 3)) {
         // Check other possibilities in the 3-bytes range
-        char byte2 = *(utf8bytes + 1);
-        char byte3 = *(utf8bytes + 2);
+        unsigned char byte2 = *(utf8bytes + 1);
+        unsigned char byte3 = *(utf8bytes + 2);
         if (byte1 == 0xe2 && byte2 == 0x80) {
             return ((byte3 >= 80 && byte3 <= 0x8b) || byte3 == 0xaf);
         } else if (byte1 == 0xe2 && byte2 == 0x81) {
@@ -1942,7 +1960,9 @@ static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTy
         }
         pInfo->curr ++;
     }
-    if (pInfo->curr >= pInfo->end) return false;
+    if (pInfo->curr >= pInfo->end) {
+        return false;
+    }
     isEmpty = (*(pInfo->curr-1) == '/');
     if (markerLength == -1)
         markerLength = pInfo->curr - (isEmpty ? 1 : 0) - marker;
@@ -2338,7 +2358,7 @@ static Boolean _CFPropertyListCreateFromUTF8Data(CFAllocatorRef allocator, CFDat
     if (success && result && format) *format = kCFPropertyListXMLFormat_v1_0;
     
     _cleanupStringMap(pInfo);
-    if (pInfo->keyPaths && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(pInfo->keyPaths);
+    if (pInfo->keyPaths && !(0)) CFRelease(pInfo->keyPaths);
     CFRelease(xmlData);
 
     if (success) {
@@ -2348,7 +2368,7 @@ static Boolean _CFPropertyListCreateFromUTF8Data(CFAllocatorRef allocator, CFDat
     
     // Try again, old-style
     CFErrorRef oldStyleError = NULL;
-    result = __CFParseOldStylePropertyListOrStringsFile(allocator, xmlData, originalString, guessedEncoding, option, outError ? &oldStyleError : NULL, format);
+    result = __CFCreateOldStylePropertyListOrStringsFile(allocator, xmlData, originalString, guessedEncoding, option, outError ? &oldStyleError : NULL, format);
     if (result) {
         // Release old error, return
         if (pInfo->error) CFRelease(pInfo->error);
@@ -2453,12 +2473,17 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef
     
     // Convert to UTF8 first
     CFStringRef xmlString = CFStringCreateWithBytes(allocator, CFDataGetBytePtr(data) + skip, CFDataGetLength(data) - skip, encoding, false);
+    if (!xmlString) {
+        if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not determine the encoding of the XML data (string creation failed)"));
+        return false;
+    }
+    
     CFDataRef utf8Data = _createUTF8DataFromString(allocator, xmlString);
 
     Boolean result = _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, outError, allowNewTypes, format, topLevelKeys, out);
     
-    if (xmlString && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(xmlString);
-    if (utf8Data && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(utf8Data);
+    if (xmlString && !(0)) CFRelease(xmlString);
+    if (utf8Data && !(0)) CFRelease(utf8Data);
     
     return result;
 }
@@ -2473,7 +2498,7 @@ CFTypeRef _CFPropertyListCreateFromXMLStringError(CFAllocatorRef allocator, CFSt
     CFDataRef utf8Data = _createUTF8DataFromString(allocator, xmlString);
     CFTypeRef result = NULL;
     _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, error, allowNewTypes, format, NULL, &result);    
-    if (utf8Data && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(utf8Data);
+    if (utf8Data && !(0)) CFRelease(utf8Data);
 
     return result;
 }
@@ -2506,8 +2531,8 @@ CFTypeRef _CFPropertyListCreateFromXMLString(CFAllocatorRef allocator, CFStringR
             
             CFRelease(oldStyleParserUserInfo);
         } else {
-            debugString = (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey); 
-            CFRetain(debugString);
+            debugString = (CFStringRef)CFDictionaryGetValue(userInfo, kCFErrorDebugDescriptionKey);
+            if (debugString) CFRetain(debugString);
         }
         
         // Give the debugString to the caller, who is responsible for releasing it
@@ -2522,7 +2547,7 @@ CFTypeRef _CFPropertyListCreateFromXMLString(CFAllocatorRef allocator, CFStringR
     return result;
 }
 
-__private_extern__ bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist);
+CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist);
 
 // Returns a subset of the property list, only including the key paths in the CFSet.
 bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) {
@@ -2552,8 +2577,8 @@ bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFO
         CFMutableDictionaryRef objects = CFDictionaryCreateMutable(allocator, 0, NULL, &kCFTypeDictionaryValueCallBacks);
         success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, splitKeyPaths, &out);
         
-        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(splitKeyPaths);
-        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(objects);        
+        CFRelease(splitKeyPaths);
+        CFRelease(objects);        
     } else {
        // Try an XML property list
         success = _CFPropertyListCreateWithData(allocator, data, option, error, true, NULL, keyPaths, &out);
@@ -2594,11 +2619,11 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
     // First check to see if it is a binary property list
     if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {
         // Split up the key path
-        CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefaultGCRefZero, keyPath, CFSTR(":"));
+        CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefault, keyPath, CFSTR(":"));
         uint64_t keyOffset, valueOffset = offset;
         
         // Create a dictionary to cache objects in
-        CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, NULL, &kCFTypeDictionaryValueCallBacks);
+        CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
         CFIndex keyPathCount = CFArrayGetCount(keyPathArray);
         _CFDictionarySetCapacity(objects, keyPathCount + 1);
 
@@ -2628,16 +2653,16 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
            }
        }
         
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(keyPathArray);
-        if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(objects);
+        CFRelease(keyPathArray);
+        CFRelease(objects);
     } else {
        // Try an XML property list
        // Note: This is currently not any more efficient than grabbing the whole thing. This could be improved in the future.
        CFPropertyListRef plist = CFPropertyListCreateWithData(allocator, data, option, NULL, error);
-        CFPropertyListRef nextObject = plist;  
-        success = true;
-       if (!(*error) && plist) {
-            CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefaultGCRefZero, keyPath, CFSTR(":"));
+        if (plist) {
+            CFPropertyListRef nextObject = plist;
+            success = true;
+            CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefault, keyPath, CFSTR(":"));
             for (CFIndex i = 0;  i < CFArrayGetCount(keyPathArray); i++) {
                 CFStringRef oneKey = (CFStringRef)CFArrayGetValueAtIndex(keyPathArray, i);
                 SInt32 intValue = CFStringGetIntValue(oneKey);
@@ -2661,9 +2686,9 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
                 success = false;
             }
             
-            if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(keyPathArray);
-       }
-        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(plist);
+            CFRelease(keyPathArray);
+            CFRelease(plist);
+        }
     }
     
     return success;
@@ -2773,6 +2798,10 @@ CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef str
     }
     if (format == kCFPropertyListXMLFormat_v1_0) {
         CFDataRef data = _CFPropertyListCreateXMLData(kCFAllocatorSystemDefault, propertyList, true);
+        if (!data) {
+            CFLog(kCFLogLevelError, CFSTR("Property list format kCFPropertyListXMLFormat_v1_0 specified but was not a valid property list type"));
+            return 0;
+        }
         CFIndex len = CFDataGetLength(data);
        const uint8_t *ptr = CFDataGetBytePtr(data);
        while (0 < len) {
@@ -2842,7 +2871,7 @@ CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStrea
     return result;    
 }
 
-static void __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint8_t **buffer, CFIndex *length, CFErrorRef *error) {
+static bool __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint8_t **buffer, CFIndex *length, CFErrorRef *error) {
     int32_t buflen = 0, bufsize = 0, retlen;
     uint8_t *buf = NULL, sbuf[8192];
     for (;;) {
@@ -2854,9 +2883,10 @@ static void __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint
             if (retlen < 0 && error) {
                 // Copy the error out
                 *error = CFReadStreamCopyError(stream);
+                return false;
             }
             
-           return;
+           return true;
        }
         if (bufsize < buflen + retlen) {
            if (bufsize < 256 * 1024) {
@@ -2878,9 +2908,10 @@ static void __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint
        if (max <= 0) {
            *buffer = buf;
            *length = buflen;
-           return;
+           return true;
        }
     }
+    return true;
 }
 
 CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFErrorRef *error) {
@@ -2895,17 +2926,20 @@ CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFRea
     CFErrorRef underlyingError = NULL;
     CFIndex buflen = 0;
     uint8_t *buffer = NULL;
-    __convertReadStreamToBytes(stream, streamLength, &buffer, &buflen, &underlyingError);
-    if (underlyingError) {
+    if (!__convertReadStreamToBytes(stream, streamLength, &buffer, &buflen, &underlyingError)) {
         if (error) {
             // Wrap the error from CFReadStream in a new error in the cocoa domain
             CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); 
-            CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, CFSTR("Property list reading could not be completed because the stream had an unknown error."));
-            CFDictionarySetValue(userInfo, kCFErrorUnderlyingErrorKey, underlyingError);
+            CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, CFSTR("Property list reading could not be completed because the stream had an unknown error. Did you forget to open the stream?"));
+            if (underlyingError) {
+                CFDictionarySetValue(userInfo, kCFErrorUnderlyingErrorKey, underlyingError);
+            }
             *error = CFErrorCreate(kCFAllocatorSystemDefault, kCFErrorDomainCocoa, kCFPropertyListReadStreamError, userInfo);
             CFRelease(userInfo);
         }
-        CFRelease(underlyingError);
+        if (underlyingError) {
+            CFRelease(underlyingError);
+        }
         return NULL;
     }
     
@@ -2957,9 +2991,7 @@ static CFArrayRef _arrayDeepImmutableCopy(CFAllocatorRef allocator, CFArrayRef a
         }
         result = (i == c) ? CFArrayCreate(allocator, values, c, &kCFTypeArrayCallBacks) : NULL;
         c = i;
-        if (!_CFAllocatorIsGCRefZero(allocator)) {
-            for (i = 0; i < c; i ++) CFRelease(values[i]);
-        }
+        for (i = 0; i < c; i ++) CFRelease(values[i]);
         free_cftype_array(values);
     }
     return result;
@@ -2973,10 +3005,10 @@ static CFMutableArrayRef _arrayDeepMutableCopy(CFAllocatorRef allocator, CFArray
             CFTypeRef newValue = CFPropertyListCreateDeepCopy(allocator, CFArrayGetValueAtIndex(array, i), mutabilityOption);
             if (!newValue) break;
             CFArrayAppendValue(result, newValue);
-            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(newValue);
+            CFRelease(newValue);
         }
         if (i != c) {
-            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(result);
+            CFRelease(result);
             result = NULL;
         }
     }
@@ -3012,7 +3044,7 @@ CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPrope
                 __CFAssignWithWriteBarrier((void **)keys + i, (void *)newKey);
                 CFTypeRef newValue = CFPropertyListCreateDeepCopy(allocator, values[i], mutabilityOption);
                 if (newValue == NULL) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(keys[i]);
+                    CFRelease(keys[i]);
                     break;
                 }
                 __CFAssignWithWriteBarrier((void **)values + i, (void *)newValue);
@@ -3023,15 +3055,15 @@ CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPrope
                     if (isMutable) {
                         CFDictionarySetValue((CFMutableDictionaryRef)result, keys[i], values[i]);
                     }
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(keys[i]);
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(values[i]);
+                    CFRelease(keys[i]);
+                    CFRelease(values[i]);
                 }
             } else {
                 result = NULL;
                 count = i;
                 for (i = 0; i < count; i ++) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(keys[i]);
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(values[i]);
+                    CFRelease(keys[i]);
+                    CFRelease(values[i]);
                 }
             }
             free_cftype_array(keys);
@@ -3049,9 +3081,9 @@ CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPrope
             result = CFDataCreateCopy(allocator, (CFDataRef)propertyList);
         }
     } else if (typeID == numbertype) {
-        // Warning - this will break if byteSize is ever greater than 32
-        uint8_t bytes[32];
-        CFNumberType numType = CFNumberGetType((CFNumberRef)propertyList);
+        // Warning - this will break if byteSize is ever greater than 128
+        uint8_t bytes[128];
+        CFNumberType numType = _CFNumberGetType2((CFNumberRef)propertyList);
         CFNumberGetValue((CFNumberRef)propertyList, numType, (void *)bytes);
         result = CFNumberCreate(allocator, numType, (void *)bytes);
     } else if (typeID == booltype) {
index 35ba94a60134f2fe8a95e0ec983c586493653f15..99ba0a7e0e01366613e6091af668586e887c990b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFPropertyList.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPROPERTYLIST__)
index 8a151fc46d7e7953516aa3c2aefee2d0da2c6e10..1566156872cfb0300ed6659f564b3baefe94ad27 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  */
 
 /*     CFRunLoop.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
 #include <CoreFoundation/CFRunLoop.h>
 #include <CoreFoundation/CFSet.h>
 #include <CoreFoundation/CFBag.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFPreferences.h>
 #include "CFInternal.h"
 #include <math.h>
 #include <stdio.h>
 #include <limits.h>
 #include <pthread.h>
 #include <dispatch/dispatch.h>
+
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#include <typeinfo.h>
+#endif
+#include <checkint.h>
+
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#include <sys/param.h>
 #include <dispatch/private.h>
 #include <CoreFoundation/CFUserNotification.h>
 #include <mach/mach.h>
@@ -43,6 +53,7 @@
 #include <mach/clock.h>
 #include <unistd.h>
 #include <dlfcn.h>
+#include <pthread/private.h>
 extern mach_port_t _dispatch_get_main_queue_port_4CF(void);
 extern void _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg);
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -52,16 +63,33 @@ DISPATCH_EXPORT void _dispatch_main_queue_callback_4CF(void);
 
 #define MACH_PORT_NULL 0
 #define mach_port_name_t HANDLE
+#define mach_port_t HANDLE
 #define _dispatch_get_main_queue_port_4CF _dispatch_get_main_queue_handle_4CF
 #define _dispatch_main_queue_callback_4CF(x) _dispatch_main_queue_callback_4CF()
 
 #define AbsoluteTime LARGE_INTEGER 
 
 #endif
+
+#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_IPHONESIMULATOR
+CF_EXPORT pthread_t _CF_pthread_main_thread_np(void);
+#define pthread_main_thread_np() _CF_pthread_main_thread_np()
+#endif
+
 #include <Block.h>
+#include <Block_private.h>
+
+#if DEPLOYMENT_TARGET_MACOSX
+#define USE_DISPATCH_SOURCE_FOR_TIMERS 1
+#define USE_MK_TIMER_TOO 1
+#else
+#define USE_DISPATCH_SOURCE_FOR_TIMERS 0
+#define USE_MK_TIMER_TOO 1
+#endif
 
 
 static int _LogCFRunLoop = 0;
+static void _runLoopTimerWithBlockContext(CFRunLoopTimerRef timer, void *opaqueBlock);
 
 // for conservative arithmetic safety, such that (TIMER_DATE_LIMIT + TIMER_INTERVAL_LIMIT + kCFAbsoluteTimeIntervalSince1970) * 10^9 < 2^63
 #define TIMER_DATE_LIMIT       4039289856.0
@@ -69,6 +97,8 @@ static int _LogCFRunLoop = 0;
 
 #define HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY 0
 
+#define CRASH(string, errcode) do { char msg[256]; snprintf(msg, 256, string, errcode); CRSetCrashLogMessage(msg); HALT; } while (0)
+
 #if DEPLOYMENT_TARGET_WINDOWS
 
 static pthread_t kNilPthreadT = { nil, nil };
@@ -83,14 +113,48 @@ static pthread_t kNilPthreadT = (pthread_t)0;
 #define lockCount(a) a
 #endif
 
+#pragma mark -
+
+#define CF_RUN_LOOP_PROBES 0
 
-CF_EXPORT bool CFDictionaryGetKeyIfPresent(CFDictionaryRef dict, const void *key, const void **actualkey);
+#if CF_RUN_LOOP_PROBES
+#include "CFRunLoopProbes.h"
+#else
+#define        CFRUNLOOP_NEXT_TIMER_ARMED(arg0) do { } while (0)
+#define        CFRUNLOOP_NEXT_TIMER_ARMED_ENABLED() (0)
+#define        CFRUNLOOP_POLL() do { } while (0)
+#define        CFRUNLOOP_POLL_ENABLED() (0)
+#define        CFRUNLOOP_SLEEP() do { } while (0)
+#define        CFRUNLOOP_SLEEP_ENABLED() (0)
+#define        CFRUNLOOP_SOURCE_FIRED(arg0, arg1, arg2) do { } while (0)
+#define        CFRUNLOOP_SOURCE_FIRED_ENABLED() (0)
+#define        CFRUNLOOP_TIMER_CREATED(arg0, arg1, arg2, arg3, arg4, arg5, arg6) do { } while (0)
+#define        CFRUNLOOP_TIMER_CREATED_ENABLED() (0)
+#define        CFRUNLOOP_TIMER_FIRED(arg0, arg1, arg2, arg3, arg4) do { } while (0)
+#define        CFRUNLOOP_TIMER_FIRED_ENABLED() (0)
+#define        CFRUNLOOP_TIMER_RESCHEDULED(arg0, arg1, arg2, arg3, arg4, arg5) do { } while (0)
+#define        CFRUNLOOP_TIMER_RESCHEDULED_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP(arg0) do { } while (0)
+#define        CFRUNLOOP_WAKEUP_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_DISPATCH() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_DISPATCH_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_NOTHING() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_NOTHING_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_SOURCE() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_SOURCE_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_TIMEOUT() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_TIMEOUT_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_TIMER() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_TIMER_ENABLED() (0)
+#define        CFRUNLOOP_WAKEUP_FOR_WAKEUP() do { } while (0)
+#define        CFRUNLOOP_WAKEUP_FOR_WAKEUP_ENABLED() (0)
+#endif
 
 // In order to reuse most of the code across Mach and Windows v1 RunLoopSources, we define a
 // simple abstraction layer spanning Mach ports and Windows HANDLES
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
-__private_extern__ uint32_t __CFGetProcessPortCount(void) {
+CF_PRIVATE uint32_t __CFGetProcessPortCount(void) {
     ipc_info_space_t info;
     ipc_info_name_array_t table = 0;
     mach_msg_type_number_t tableCount = 0;
@@ -110,7 +174,7 @@ __private_extern__ uint32_t __CFGetProcessPortCount(void) {
     return (uint32_t)tableCount;
 }
 
-__private_extern__ CFArrayRef __CFStopAllThreads(void) {
+CF_PRIVATE CFArrayRef __CFStopAllThreads(void) {
     CFMutableArrayRef suspended_list = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
     mach_port_t my_task = mach_task_self();
     mach_port_t my_thread = mach_thread_self();
@@ -137,16 +201,11 @@ __private_extern__ CFArrayRef __CFStopAllThreads(void) {
     return suspended_list;
 }
 
-__private_extern__ void __CFRestartAllThreads(CFArrayRef threads) {
+CF_PRIVATE void __CFRestartAllThreads(CFArrayRef threads) {
     for (CFIndex idx = 0; idx < CFArrayGetCount(threads); idx++) {
         thread_act_t thread = (thread_act_t)(uintptr_t)CFArrayGetValueAtIndex(threads, idx);
         kern_return_t ret = thread_resume(thread);
-        if (ret != KERN_SUCCESS) {
-            char msg[256];
-            snprintf(msg, 256, "*** Failure from thread_resume (%d) ***", ret);
-            CRSetCrashLogMessage(msg); 
-            HALT;
-        }
+        if (ret != KERN_SUCCESS) CRASH("*** Failure from thread_resume (%d) ***", ret);
         mach_port_deallocate(mach_task_self(), thread);
     }
 }
@@ -192,32 +251,22 @@ static void __THE_SYSTEM_HAS_NO_PORTS_AVAILABLE__(kern_return_t ret) { HALT; };
 static __CFPort __CFPortAllocate(void) {
     __CFPort result = CFPORT_NULL;
     kern_return_t ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &result);
-    if (KERN_SUCCESS != ret) { 
+    if (KERN_SUCCESS != ret) {
         char msg[256];
         snprintf(msg, 256, "*** The system has no mach ports available. You may be able to diagnose which application(s) are using ports by using 'top' or Activity Monitor. (%d) ***", ret);
         CRSetCrashLogMessage(msg); 
         __THE_SYSTEM_HAS_NO_PORTS_AVAILABLE__(ret); 
-        return CFPORT_NULL; 
+        return CFPORT_NULL;
     }
 
     ret = mach_port_insert_right(mach_task_self(), result, result, MACH_MSG_TYPE_MAKE_SEND);
-    if (KERN_SUCCESS != ret) {
-        char msg[256];
-        snprintf(msg, 256, "*** Unable to set send right on mach port. (%d) ***", ret);
-        CRSetCrashLogMessage(msg); 
-        HALT;
-    }
+    if (KERN_SUCCESS != ret) CRASH("*** Unable to set send right on mach port. (%d) ***", ret);
+
 
     mach_port_limits_t limits;
     limits.mpl_qlimit = 1;
     ret = mach_port_set_attributes(mach_task_self(), result, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&limits, MACH_PORT_LIMITS_INFO_COUNT);
-    if (KERN_SUCCESS != ret) {
-        char msg[256];
-        snprintf(msg, 256, "*** Unable to set attributes on mach port. (%d) ***", ret);
-        CRSetCrashLogMessage(msg); 
-        mach_port_destroy(mach_task_self(), result);
-        HALT;
-    }
+    if (KERN_SUCCESS != ret) CRASH("*** Unable to set attributes on mach port. (%d) ***", ret);
     
     return result;
 }
@@ -374,17 +423,22 @@ typedef UnsignedWide              AbsoluteTime;
 #endif
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+#endif
+#if USE_MK_TIMER_TOO
 extern mach_port_name_t mk_timer_create(void);
 extern kern_return_t mk_timer_destroy(mach_port_name_t name);
 extern kern_return_t mk_timer_arm(mach_port_name_t name, AbsoluteTime expire_time);
 extern kern_return_t mk_timer_cancel(mach_port_name_t name, AbsoluteTime *result_time);
 
-CF_INLINE AbsoluteTime __CFUInt64ToAbsoluteTime(int64_t x) {
+CF_INLINE AbsoluteTime __CFUInt64ToAbsoluteTime(uint64_t x) {
     AbsoluteTime a;
     a.hi = x >> 32;
-    a.lo = x & (int64_t)0xFFFFFFFF;
+    a.lo = x & (uint64_t)0xFFFFFFFF;
     return a;
 }
+#endif
 
 static uint32_t __CFSendTrivialMachMessage(mach_port_t port, uint32_t msg_id, CFOptionFlags options, uint32_t timeout) {
     kern_return_t result;
@@ -432,13 +486,14 @@ static kern_return_t mk_timer_cancel(HANDLE name, LARGE_INTEGER *result_time) {
 }
 
 // The name of this function is a lie on Windows. The return value matches the argument of the fake mk_timer functions above. Note that the Windows timers expect to be given "system time". We have to do some calculations to get the right value, which is a FILETIME-like value.
-CF_INLINE LARGE_INTEGER __CFUInt64ToAbsoluteTime(int64_t desiredFireTime) {
+CF_INLINE LARGE_INTEGER __CFUInt64ToAbsoluteTime(uint64_t desiredFireTime) {
     LARGE_INTEGER result;
-    // There is a race we know about here, (timer fire time calculated -> thread suspended -> timer armed == late timer fire), but we don't have a way to avoid it at this time, since the only way to specify an absolute value to the timer is to calculate the relative time first. Fixing that would probably require not using the TSR for timers on Windows.    
-    int64_t timeDiff = desiredFireTime - (int64_t)mach_absolute_time();
-    if (timeDiff < 0) {
+    // There is a race we know about here, (timer fire time calculated -> thread suspended -> timer armed == late timer fire), but we don't have a way to avoid it at this time, since the only way to specify an absolute value to the timer is to calculate the relative time first. Fixing that would probably require not using the TSR for timers on Windows.
+    uint64_t now = mach_absolute_time();
+    if (now > desiredFireTime) {
         result.QuadPart = 0;
     } else {
+        uint64_t timeDiff = desiredFireTime - now;
         CFTimeInterval amountOfTimeToWait = __CFTSRToTimeInterval(timeDiff);
         // Result is in 100 ns (10**-7 sec) units to be consistent with a FILETIME.
         // CFTimeInterval is in seconds.
@@ -449,6 +504,9 @@ CF_INLINE LARGE_INTEGER __CFUInt64ToAbsoluteTime(int64_t desiredFireTime) {
 
 #endif
 
+#pragma mark -
+#pragma mark Modes
+
 /* unlock a run loop and modes before doing callouts/sleeping */
 /* never try to take the run loop lock with a mode locked */
 /* be very careful of common subexpression elimination and compacting code, particular across locks and unlocks! */
@@ -475,23 +533,31 @@ struct __CFRunLoopMode {
     CFMutableDictionaryRef _portToV1SourceMap;
     __CFPortSet _portSet;
     CFIndex _observerMask;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+    dispatch_source_t _timerSource;
+    dispatch_queue_t _queue;
+    Boolean _timerFired; // set to true by the source when a timer has fired
+    Boolean _dispatchTimerArmed;
+#endif
+#if USE_MK_TIMER_TOO
     mach_port_t _timerPort;
+    Boolean _mkTimerArmed;
 #endif
 #if DEPLOYMENT_TARGET_WINDOWS
-    HANDLE _timerPort;
     DWORD _msgQMask;
     void (*_msgPump)(void);
 #endif
+    uint64_t _timerSoftDeadline; /* TSR */
+    uint64_t _timerHardDeadline; /* TSR */
 };
 
 CF_INLINE void __CFRunLoopModeLock(CFRunLoopModeRef rlm) {
     pthread_mutex_lock(&(rlm->_lock));
-//    CFLog(6, CFSTR("__CFRunLoopModeLock locked %p"), rlm);
+    //CFLog(6, CFSTR("__CFRunLoopModeLock locked %p"), rlm);
 }
 
 CF_INLINE void __CFRunLoopModeUnlock(CFRunLoopModeRef rlm) {
-//    CFLog(6, CFSTR("__CFRunLoopModeLock unlocking %p"), rlm);
+    //CFLog(6, CFSTR("__CFRunLoopModeLock unlocking %p"), rlm);
     pthread_mutex_unlock(&(rlm->_lock));
 }
 
@@ -511,12 +577,18 @@ static CFStringRef __CFRunLoopModeCopyDescription(CFTypeRef cf) {
     CFMutableStringRef result;
     result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
     CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoopMode %p [%p]>{name = %@, "), rlm, CFGetAllocator(rlm), rlm->_name);
-    CFStringAppendFormat(result, NULL, CFSTR("port set = %p, "), rlm->_portSet);
-    CFStringAppendFormat(result, NULL, CFSTR("timer port = %p, "), rlm->_timerPort);
+    CFStringAppendFormat(result, NULL, CFSTR("port set = 0x%x, "), rlm->_portSet);
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+    CFStringAppendFormat(result, NULL, CFSTR("queue = %p, "), rlm->_queue);
+    CFStringAppendFormat(result, NULL, CFSTR("source = %p (%s), "), rlm->_timerSource, rlm->_timerFired ? "fired" : "not fired");
+#endif
+#if USE_MK_TIMER_TOO
+    CFStringAppendFormat(result, NULL, CFSTR("timer port = 0x%x, "), rlm->_timerPort);
+#endif
 #if DEPLOYMENT_TARGET_WINDOWS
     CFStringAppendFormat(result, NULL, CFSTR("MSGQ mask = %p, "), rlm->_msgQMask);
 #endif
-    CFStringAppendFormat(result, NULL, CFSTR("\n\tsources0 = %@,\n\tsources1 = %@,\n\tobservers = %@,\n\ttimers = %@\n},\n"), rlm->_sources0, rlm->_sources1, rlm->_observers, rlm->_timers);
+    CFStringAppendFormat(result, NULL, CFSTR("\n\tsources0 = %@,\n\tsources1 = %@,\n\tobservers = %@,\n\ttimers = %@,\n\tcurrently %0.09g (%lld) / soft deadline in: %0.09g sec (@ %lld) / hard deadline in: %0.09g sec (@ %lld)\n},\n"), rlm->_sources0, rlm->_sources1, rlm->_observers, rlm->_timers, CFAbsoluteTimeGetCurrent(), mach_absolute_time(), __CFTSRToTimeInterval(rlm->_timerSoftDeadline - mach_absolute_time()), rlm->_timerSoftDeadline, __CFTSRToTimeInterval(rlm->_timerHardDeadline - mach_absolute_time()), rlm->_timerHardDeadline);
     return result;
 }
 
@@ -529,11 +601,25 @@ static void __CFRunLoopModeDeallocate(CFTypeRef cf) {
     if (NULL != rlm->_portToV1SourceMap) CFRelease(rlm->_portToV1SourceMap);
     CFRelease(rlm->_name);
     __CFPortSetFree(rlm->_portSet);
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+    if (rlm->_timerSource) {
+        dispatch_source_cancel(rlm->_timerSource);
+        dispatch_release(rlm->_timerSource);
+    }
+    if (rlm->_queue) {
+        dispatch_release(rlm->_queue);
+    }
+#endif
+#if USE_MK_TIMER_TOO
     if (MACH_PORT_NULL != rlm->_timerPort) mk_timer_destroy(rlm->_timerPort);
+#endif
     pthread_mutex_destroy(&rlm->_lock);
     memset((char *)cf + sizeof(CFRuntimeBase), 0x7C, sizeof(struct __CFRunLoopMode) - sizeof(CFRuntimeBase));
 }
 
+#pragma mark -
+#pragma mark Run Loops
+
 struct _block_item {
     struct _block_item *_next;
     CFTypeRef _mode;   // CFString or CFSet
@@ -629,11 +715,11 @@ CF_INLINE void __CFRunLoopSetDeallocating(CFRunLoopRef rl) {
 
 CF_INLINE void __CFRunLoopLock(CFRunLoopRef rl) {
     pthread_mutex_lock(&(((CFRunLoopRef)rl)->_lock));
-//    CFLog(6, CFSTR("__CFRunLoopLock locked %p"), rl);
+    //    CFLog(6, CFSTR("__CFRunLoopLock locked %p"), rl);
 }
 
 CF_INLINE void __CFRunLoopUnlock(CFRunLoopRef rl) {
-//    CFLog(6, CFSTR("__CFRunLoopLock unlocking %p"), rl);
+    //    CFLog(6, CFSTR("__CFRunLoopLock unlocking %p"), rl);
     pthread_mutex_unlock(&(((CFRunLoopRef)rl)->_lock));
 }
 
@@ -650,7 +736,7 @@ static CFStringRef __CFRunLoopCopyDescription(CFTypeRef cf) {
     return result;
 }
 
-__private_extern__ void __CFRunLoopDump() { // __private_extern__ to keep the compiler from discarding it
+CF_PRIVATE void __CFRunLoopDump() { // __private_extern__ to keep the compiler from discarding it
     CFShow(CFCopyDescription(CFRunLoopGetCurrent()));
 }
 
@@ -664,14 +750,13 @@ CF_INLINE void __CFRunLoopLockInit(pthread_mutex_t *lock) {
     }
 }
 
-/* call with rl locked */
+/* call with rl locked, returns mode locked */
 static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeName, Boolean create) {
     CHECK_FOR_FORK();
     CFRunLoopModeRef rlm;
     struct __CFRunLoopMode srlm;
     memset(&srlm, 0, sizeof(srlm));
-    srlm._base._cfisa = __CFISAForTypeID(__kCFRunLoopModeTypeID);
-    _CFRuntimeSetInstanceTypeID(&srlm, __kCFRunLoopModeTypeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(&srlm, __kCFRunLoopModeTypeID);
     srlm._name = modeName;
     rlm = (CFRunLoopModeRef)CFSetGetValue(rl->_modes, &srlm);
     if (NULL != rlm) {
@@ -695,22 +780,40 @@ static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeNam
     rlm->_timers = NULL;
     rlm->_observerMask = 0;
     rlm->_portSet = __CFPortSetAllocate();
+    rlm->_timerSoftDeadline = UINT64_MAX;
+    rlm->_timerHardDeadline = UINT64_MAX;
+    
+    kern_return_t ret = KERN_SUCCESS;
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+    rlm->_timerFired = false;
+    rlm->_queue = _dispatch_runloop_root_queue_create_4CF("Run Loop Mode Queue", 0);
+    mach_port_t queuePort = _dispatch_runloop_root_queue_get_port_4CF(rlm->_queue);
+    if (queuePort == MACH_PORT_NULL) CRASH("*** Unable to create run loop mode queue port. (%d) ***", -1);
+    rlm->_timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, rlm->_queue);
+    
+    __block Boolean *timerFiredPointer = &(rlm->_timerFired);
+    dispatch_source_set_event_handler(rlm->_timerSource, ^{
+        *timerFiredPointer = true;
+    });
+    
+    // Set timer to far out there. The unique leeway makes this timer easy to spot in debug output.
+    _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 321);
+    dispatch_resume(rlm->_timerSource);
+    
+    ret = __CFPortSetInsert(queuePort, rlm->_portSet);
+    if (KERN_SUCCESS != ret) CRASH("*** Unable to insert timer port into port set. (%d) ***", ret);
+    
+#endif
+#if USE_MK_TIMER_TOO
     rlm->_timerPort = mk_timer_create();
-    kern_return_t ret = __CFPortSetInsert(rlm->_timerPort, rlm->_portSet);
-    if (KERN_SUCCESS != ret) {
-        char msg[256];
-        snprintf(msg, 256, "*** Unable to insert timer port into port set. (%d) ***", ret);
-        CRSetCrashLogMessage(msg); 
-        HALT;
-    }
+    ret = __CFPortSetInsert(rlm->_timerPort, rlm->_portSet);
+    if (KERN_SUCCESS != ret) CRASH("*** Unable to insert timer port into port set. (%d) ***", ret);
+#endif
+    
     ret = __CFPortSetInsert(rl->_wakeUpPort, rlm->_portSet);
-    if (KERN_SUCCESS != ret) {
-        char msg[256];
-        snprintf(msg, 256, "*** Unable to insert wake up port into port set. (%d) ***", ret);
-        CRSetCrashLogMessage(msg); 
-        HALT;
-    }
-#if DEPLOYMENT_TARGET_WINDOWS    
+    if (KERN_SUCCESS != ret) CRASH("*** Unable to insert wake up port into port set. (%d) ***", ret);
+    
+#if DEPLOYMENT_TARGET_WINDOWS
     rlm->_msgQMask = 0;
     rlm->_msgPump = NULL;
 #endif
@@ -820,6 +923,9 @@ void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeNa
 
 #endif
 
+#pragma mark -
+#pragma mark Sources
+
 /* Bit 3 in the base reserved bits is used for invalid state in run loop objects */
 
 CF_INLINE Boolean __CFIsValid(const void *cf) {
@@ -870,6 +976,7 @@ CF_INLINE void __CFRunLoopSourceUnlock(CFRunLoopSourceRef rls) {
     pthread_mutex_unlock(&(rls->_lock));
 }
 
+#pragma mark Observers
 
 struct __CFRunLoopObserver {
     CFRuntimeBase _base;
@@ -937,6 +1044,8 @@ static void __CFRunLoopObserverCancel(CFRunLoopObserverRef rlo, CFRunLoopRef rl,
     __CFRunLoopObserverUnlock(rlo);
 }
 
+#pragma mark Timers
+
 struct __CFRunLoopTimer {
     CFRuntimeBase _base;
     uint16_t _bits;
@@ -945,7 +1054,8 @@ struct __CFRunLoopTimer {
     CFMutableSetRef _rlModes;
     CFAbsoluteTime _nextFireDate;
     CFTimeInterval _interval;          /* immutable */
-    int64_t _fireTSR;                  /* TSR units */
+    CFTimeInterval _tolerance;          /* mutable */
+    uint64_t _fireTSR;                 /* TSR units */
     CFIndex _order;                    /* immutable */
     CFRunLoopTimerCallBack _callout;   /* immutable */
     CFRunLoopTimerContext _context;    /* immutable, except invalidation */
@@ -953,6 +1063,7 @@ struct __CFRunLoopTimer {
 
 /* Bit 0 of the base reserved bits is used for firing state */
 /* Bit 1 of the base reserved bits is used for fired-during-callout state */
+/* Bit 2 of the base reserved bits is used for waking state */
 
 CF_INLINE Boolean __CFRunLoopTimerIsFiring(CFRunLoopTimerRef rlt) {
     return (Boolean)__CFBitfieldGetValue(rlt->_bits, 0, 0);
@@ -994,40 +1105,7 @@ CF_INLINE void __CFRunLoopTimerFireTSRUnlock(void) {
     __CFSpinUnlock(&__CFRLTFireTSRLock);
 }
 
-#if DEPLOYMENT_TARGET_WINDOWS
-
-struct _collectTimersContext {
-    CFMutableArrayRef results;
-    int64_t cutoffTSR;
-};
-
-static void __CFRunLoopCollectTimers(const void *value, void *ctx) {
-    CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)value;
-    struct _collectTimersContext *context = (struct _collectTimersContext *)ctx;
-    if (rlt->_fireTSR <= context->cutoffTSR) {
-        if (NULL == context->results)
-            context->results = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        CFArrayAppendValue(context->results, rlt);
-    }
-}
-
-// RunLoop and RunLoopMode must be locked
-static void __CFRunLoopTimersToFireRecursive(CFRunLoopRef rl, CFRunLoopModeRef rlm, struct _collectTimersContext *ctxt) {
-    __CFRunLoopTimerFireTSRLock();
-    if (NULL != rlm->_timers && 0 < CFArrayGetCount(rlm->_timers)) {
-        CFArrayApplyFunction(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)),  __CFRunLoopCollectTimers, ctxt);
-    }
-    __CFRunLoopTimerFireTSRUnlock();
-}
-
-// RunLoop and RunLoopMode must be locked
-static CFArrayRef __CFRunLoopTimersToFire(CFRunLoopRef rl, CFRunLoopModeRef rlm) {
-    struct _collectTimersContext ctxt = {NULL, mach_absolute_time()};
-    __CFRunLoopTimersToFireRecursive(rl, rlm, &ctxt);
-    return ctxt.results;
-}
-
-#endif
+#pragma mark -
 
 /* CFRunLoop */
 
@@ -1129,37 +1207,40 @@ static void __CFRunLoopDeallocateObservers(const void *value, void *context) {
 
 static void __CFRunLoopDeallocateTimers(const void *value, void *context) {
     CFRunLoopModeRef rlm = (CFRunLoopModeRef)value;
-    CFIndex idx, cnt;
-    const void **list, *buffer[256];
     if (NULL == rlm->_timers) return;
-    cnt = CFArrayGetCount(rlm->_timers);
-    list = (const void **)((cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0));
-    CFArrayGetValues(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)), list);
-    for (idx = 0; idx < cnt; idx++) {
-       CFRetain(list[idx]);
-    }
-    CFArrayRemoveAllValues(rlm->_timers);
-    for (idx = 0; idx < cnt; idx++) {
-        CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)list[idx];
-        __CFRunLoopTimerLock(rlt);
-        // if the run loop is deallocating, and since a timer can only be in one
-        // run loop, we're going to be removing the timer from all modes, so be
-        // a little heavy-handed and direct
-        CFSetRemoveAllValues(rlt->_rlModes);
-        rlt->_runLoop = NULL;
-        __CFRunLoopTimerUnlock(rlt);
-       CFRelease(list[idx]);
-    }
-    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    void (^deallocateTimers)(CFMutableArrayRef timers) = ^(CFMutableArrayRef timers) {
+        CFIndex idx, cnt;
+        const void **list, *buffer[256];
+        cnt = CFArrayGetCount(timers);
+        list = (const void **)((cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0));
+        CFArrayGetValues(timers, CFRangeMake(0, CFArrayGetCount(timers)), list);
+        for (idx = 0; idx < cnt; idx++) {
+            CFRetain(list[idx]);
+        }
+        CFArrayRemoveAllValues(timers);
+        for (idx = 0; idx < cnt; idx++) {
+            CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)list[idx];
+            __CFRunLoopTimerLock(rlt);
+            // if the run loop is deallocating, and since a timer can only be in one
+            // run loop, we're going to be removing the timer from all modes, so be
+            // a little heavy-handed and direct
+            CFSetRemoveAllValues(rlt->_rlModes);
+            rlt->_runLoop = NULL;
+            __CFRunLoopTimerUnlock(rlt);
+            CFRelease(list[idx]);
+        }
+        if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list);
+    };
+    
+    if (rlm->_timers && CFArrayGetCount(rlm->_timers)) deallocateTimers(rlm->_timers);
 }
 
-CF_EXPORT pthread_t _CFMainPThread;
 CF_EXPORT CFRunLoopRef _CFRunLoopGet0b(pthread_t t);
 
 static void __CFRunLoopDeallocate(CFTypeRef cf) {
     CFRunLoopRef rl = (CFRunLoopRef)cf;
 
-    if (_CFRunLoopGet0b(_CFMainPThread) == cf) HALT;
+    if (_CFRunLoopGet0b(pthread_main_thread_np()) == cf) HALT;
 
     /* We try to keep the run loop in a valid state as long as possible,
        since sources may have non-retained references to the run loop.
@@ -1226,12 +1307,9 @@ static const CFRuntimeClass __CFRunLoopClass = {
     __CFRunLoopCopyDescription
 };
 
-__private_extern__ void __CFFinalizeRunLoop(uintptr_t data);
-
-static int64_t tenus = 0LL;
+CF_PRIVATE void __CFFinalizeRunLoop(uintptr_t data);
 
-__private_extern__ void __CFRunLoopInitialize(void) {
-    tenus = __CFTimeIntervalToTSR(0.000010000);
+CF_PRIVATE void __CFRunLoopInitialize(void) {
     __kCFRunLoopTypeID = _CFRuntimeRegisterClass(&__CFRunLoopClass);
     __kCFRunLoopModeTypeID = _CFRuntimeRegisterClass(&__CFRunLoopModeClass);
 }
@@ -1279,14 +1357,14 @@ static CFSpinLock_t loopsLock = CFSpinLockInit;
 // t==0 is a synonym for "main thread" that always works
 CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
     if (pthread_equal(t, kNilPthreadT)) {
-       t = _CFMainPThread;
+       t = pthread_main_thread_np();
     }
     __CFSpinLock(&loopsLock);
     if (!__CFRunLoops) {
         __CFSpinUnlock(&loopsLock);
        CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks);
-       CFRunLoopRef mainLoop = __CFRunLoopCreate(_CFMainPThread);
-       CFDictionarySetValue(dict, pthreadPointer(_CFMainPThread), mainLoop);
+       CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np());
+       CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop);
        if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dict, (void * volatile *)&__CFRunLoops)) {
            CFRelease(dict);
        }
@@ -1319,7 +1397,7 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
 // should only be called by Foundation
 CFRunLoopRef _CFRunLoopGet0b(pthread_t t) {
     if (pthread_equal(t, kNilPthreadT)) {
-       t = _CFMainPThread;
+       t = pthread_main_thread_np();
     }
     __CFSpinLock(&loopsLock);
     CFRunLoopRef loop = NULL;
@@ -1333,7 +1411,7 @@ CFRunLoopRef _CFRunLoopGet0b(pthread_t t) {
 static void __CFRunLoopRemoveAllSources(CFRunLoopRef rl, CFStringRef modeName);
 
 // Called for each thread as it exits
-__private_extern__ void __CFFinalizeRunLoop(uintptr_t data) {
+CF_PRIVATE void __CFFinalizeRunLoop(uintptr_t data) {
     CFRunLoopRef rl = NULL;
     if (data <= 1) {
        __CFSpinLock(&loopsLock);
@@ -1404,7 +1482,7 @@ void _CFRunLoopSetCurrent(CFRunLoopRef rl) {
 CFRunLoopRef CFRunLoopGetMain(void) {
     CHECK_FOR_FORK();
     static CFRunLoopRef __main = NULL; // no retain needed
-    if (!__main) __main = _CFRunLoopGet0(_CFMainPThread); // no CAS needed
+    if (!__main) __main = _CFRunLoopGet0(pthread_main_thread_np()); // no CAS needed
     return __main;
 }
 
@@ -1507,6 +1585,12 @@ void CFRunLoopAddCommonMode(CFRunLoopRef rl, CFStringRef modeName) {
 }
 
 
+static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__() __attribute__((noinline));
+static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) {
+    _dispatch_main_queue_callback_4CF(msg);
+    getpid(); // thwart tail-call optimization
+}
+
 static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline));
 static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) {
     if (func) {
@@ -1737,6 +1821,9 @@ static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Bool
     return sourceHandled;
 }
 
+CF_INLINE void __CFRunLoopDebugInfoForRunLoopSource(CFRunLoopSourceRef rls) {
+}
+
 // msg, size and reply are unused on Windows
 static Boolean __CFRunLoopDoSource1() __attribute__((noinline));
 static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls
@@ -1755,6 +1842,7 @@ static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRun
     if (__CFIsValid(rls)) {
        __CFRunLoopSourceUnsetSignaled(rls);
        __CFRunLoopSourceUnlock(rls);
+        __CFRunLoopDebugInfoForRunLoopSource(rls);
         __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(rls->_context.version1.perform,
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             msg, size, reply,
@@ -1808,52 +1896,140 @@ static CFIndex __CFRunLoopInsertionIndexInTimerArray(CFArrayRef array, CFRunLoop
     return lastTestLEQ ? idx + 1 : idx;
 }
 
-static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm) {
-    CFRunLoopTimerRef nextTimer = NULL;
-    for (CFIndex idx = 0, cnt = CFArrayGetCount(rlm->_timers); idx < cnt; idx++) {
-        CFRunLoopTimerRef t = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(rlm->_timers, idx);
-        if (!__CFRunLoopTimerIsFiring(t)) {
-            nextTimer = t;
-            break;
+static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) {    
+    uint64_t nextHardDeadline = UINT64_MAX;
+    uint64_t nextSoftDeadline = UINT64_MAX;
+
+    if (rlm->_timers) {
+        // Look at the list of timers. We will calculate two TSR values; the next soft and next hard deadline.
+        // The next soft deadline is the first time we can fire any timer. This is the fire date of the first timer in our sorted list of timers.
+        // The next hard deadline is the last time at which we can fire the timer before we've moved out of the allowable tolerance of the timers in our list.
+        for (CFIndex idx = 0, cnt = CFArrayGetCount(rlm->_timers); idx < cnt; idx++) {
+            CFRunLoopTimerRef t = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(rlm->_timers , idx);
+            // discount timers currently firing
+            if (__CFRunLoopTimerIsFiring(t)) continue;
+            
+            int32_t err = CHECKINT_NO_ERROR;
+            uint64_t oneTimerSoftDeadline = t->_fireTSR;
+            uint64_t oneTimerHardDeadline = check_uint64_add(t->_fireTSR, __CFTimeIntervalToTSR(t->_tolerance), &err);
+            if (err != CHECKINT_NO_ERROR) oneTimerHardDeadline = UINT64_MAX;
+            
+            // We can stop searching if the soft deadline for this timer exceeds the current hard deadline. Otherwise, later timers with lower tolerance could still have earlier hard deadlines.
+            if (oneTimerSoftDeadline > nextHardDeadline) {
+                break;
+            }
+            
+            if (oneTimerSoftDeadline < nextSoftDeadline) {
+                nextSoftDeadline = oneTimerSoftDeadline;
+            }
+            
+            if (oneTimerHardDeadline < nextHardDeadline) {
+                nextHardDeadline = oneTimerHardDeadline;
+            }
+        }
+        
+        if (nextSoftDeadline < UINT64_MAX && (nextHardDeadline != rlm->_timerHardDeadline || nextSoftDeadline != rlm->_timerSoftDeadline)) {
+            if (CFRUNLOOP_NEXT_TIMER_ARMED_ENABLED()) {
+                CFRUNLOOP_NEXT_TIMER_ARMED((unsigned long)(nextSoftDeadline - mach_absolute_time()));
+            }
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+            // We're going to hand off the range of allowable timer fire date to dispatch and let it fire when appropriate for the system.
+            uint64_t leeway = __CFTSRToNanoseconds(nextHardDeadline - nextSoftDeadline);
+            dispatch_time_t deadline = __CFTSRToDispatchTime(nextSoftDeadline);
+#if USE_MK_TIMER_TOO
+            if (leeway > 0) {
+                // Only use the dispatch timer if we have any leeway
+                // <rdar://problem/14447675>
+                
+                // Cancel the mk timer
+                if (rlm->_mkTimerArmed && rlm->_timerPort) {
+                    AbsoluteTime dummy;
+                    mk_timer_cancel(rlm->_timerPort, &dummy);
+                    rlm->_mkTimerArmed = false;
+                }
+                
+                // Arm the dispatch timer
+                _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway);
+                rlm->_dispatchTimerArmed = true;
+            } else {
+                // Cancel the dispatch timer
+                if (rlm->_dispatchTimerArmed) {
+                    // Cancel the dispatch timer
+                    _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 888);
+                    rlm->_dispatchTimerArmed = false;
+                }
+                
+                // Arm the mk timer
+                if (rlm->_timerPort) {
+                    mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(nextSoftDeadline));
+                    rlm->_mkTimerArmed = true;
+                }
+            }
+#else
+            _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway);
+#endif
+#else
+            if (rlm->_timerPort) {
+                mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(nextSoftDeadline));
+            }
+#endif
+        } else if (nextSoftDeadline == UINT64_MAX) {
+            // Disarm the timers - there is no timer scheduled
+            
+            if (rlm->_mkTimerArmed && rlm->_timerPort) {
+                AbsoluteTime dummy;
+                mk_timer_cancel(rlm->_timerPort, &dummy);
+                rlm->_mkTimerArmed = false;
+            }
+            
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+            if (rlm->_dispatchTimerArmed) {
+                _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 333);
+                rlm->_dispatchTimerArmed = false;
+            }
+#endif
         }
     }
-    if (nextTimer) {
-        int64_t fireTSR = nextTimer->_fireTSR;
-        fireTSR = (fireTSR / tenus + 1) * tenus;
-        mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
-    }
+    rlm->_timerHardDeadline = nextHardDeadline;
+    rlm->_timerSoftDeadline = nextSoftDeadline;
 }
 
 // call with rlm and its run loop locked, and the TSRLock locked; rlt not locked; returns with same state
 static void __CFRepositionTimerInMode(CFRunLoopModeRef rlm, CFRunLoopTimerRef rlt, Boolean isInArray) __attribute__((noinline));
 static void __CFRepositionTimerInMode(CFRunLoopModeRef rlm, CFRunLoopTimerRef rlt, Boolean isInArray) {
-    if (!rlt || !rlm->_timers) return;
+    if (!rlt) return;
+    
+    CFMutableArrayRef timerArray = rlm->_timers;
+    if (!timerArray) return;
     Boolean found = false;
+    
+    // If we know in advance that the timer is not in the array (just being added now) then we can skip this search
     if (isInArray) {
-       CFIndex idx = CFArrayGetFirstIndexOfValue(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)), rlt);
-       if (kCFNotFound != idx) {
-           CFRetain(rlt);
-           CFArrayRemoveValueAtIndex(rlm->_timers, idx);
-           found = true;
-       }
+        CFIndex idx = CFArrayGetFirstIndexOfValue(timerArray, CFRangeMake(0, CFArrayGetCount(timerArray)), rlt);
+        if (kCFNotFound != idx) {
+            CFRetain(rlt);
+            CFArrayRemoveValueAtIndex(timerArray, idx);
+            found = true;
+        }
     }
     if (!found && isInArray) return;
-    CFIndex newIdx = __CFRunLoopInsertionIndexInTimerArray(rlm->_timers, rlt);
-    CFArrayInsertValueAtIndex(rlm->_timers, newIdx, rlt);
-    __CFArmNextTimerInMode(rlm);
+    CFIndex newIdx = __CFRunLoopInsertionIndexInTimerArray(timerArray, rlt);
+    CFArrayInsertValueAtIndex(timerArray, newIdx, rlt);
+    __CFArmNextTimerInMode(rlm, rlt->_runLoop);
     if (isInArray) CFRelease(rlt);
 }
 
+
 // mode and rl are locked on entry and exit
 static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopTimerRef rlt) {      /* DOES CALLOUT */
     Boolean timerHandled = false;
-    int64_t oldFireTSR = 0;
+    uint64_t oldFireTSR = 0;
 
     /* Fire a timer */
     CFRetain(rlt);
     __CFRunLoopTimerLock(rlt);
 
-    if (__CFIsValid(rlt) && rlt->_fireTSR <= (int64_t)mach_absolute_time() && !__CFRunLoopTimerIsFiring(rlt) && rlt->_runLoop == rl) {
+    if (__CFIsValid(rlt) && rlt->_fireTSR <= mach_absolute_time() && !__CFRunLoopTimerIsFiring(rlt) && rlt->_runLoop == rl) {
         void *context_info = NULL;
         void (*context_release)(const void *) = NULL;
         if (rlt->_context.retain) {
@@ -1864,12 +2040,15 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
         }
         Boolean doInvalidate = (0.0 == rlt->_interval);
        __CFRunLoopTimerSetFiring(rlt);
+        // Just in case the next timer has exactly the same deadlines as this one, we reset these values so that the arm next timer code can correctly find the next timer in the list and arm the underlying timer.
+        rlm->_timerSoftDeadline = UINT64_MAX;
+        rlm->_timerHardDeadline = UINT64_MAX;
         __CFRunLoopTimerUnlock(rlt);
        __CFRunLoopTimerFireTSRLock();
        oldFireTSR = rlt->_fireTSR;
        __CFRunLoopTimerFireTSRUnlock();
 
-        __CFArmNextTimerInMode(rlm);
+        __CFArmNextTimerInMode(rlm, rl);
 
        __CFRunLoopModeUnlock(rlm);
        __CFRunLoopUnlock(rl);
@@ -1901,10 +2080,10 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
             // skipped because it was firing.  Need to redo the
             // min timer calculation in case rlt should now be that
             // timer instead of whatever was chosen.
-            __CFArmNextTimerInMode(rlm);
+            __CFArmNextTimerInMode(rlm, rl);
         } else {
-           int64_t nextFireTSR = 0LL;
-            int64_t intervalTSR = 0LL;
+           uint64_t nextFireTSR = 0LL;
+            uint64_t intervalTSR = 0LL;
             if (rlt->_interval <= 0.0) {
             } else if (TIMER_INTERVAL_LIMIT < rlt->_interval) {
                intervalTSR = __CFTimeIntervalToTSR(TIMER_INTERVAL_LIMIT);
@@ -1914,7 +2093,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
             if (LLONG_MAX - intervalTSR <= oldFireTSR) {
                 nextFireTSR = LLONG_MAX;
             } else {
-                int64_t currentTSR = (int64_t)mach_absolute_time();
+                uint64_t currentTSR = mach_absolute_time();
                 nextFireTSR = oldFireTSR;
                 while (nextFireTSR <= currentTSR) {
                     nextFireTSR += intervalTSR;
@@ -1941,11 +2120,11 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
                }
                __CFRunLoopTimerFireTSRLock();
                rlt->_fireTSR = nextFireTSR;
-                rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTSRToTimeInterval(nextFireTSR - (int64_t)mach_absolute_time());
+                rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTimeIntervalUntilTSR(nextFireTSR);
                for (CFIndex idx = 0; idx < cnt; idx++) {
                    CFRunLoopModeRef rlm = (CFRunLoopModeRef)modes[idx];
                    if (rlm) {
-                       __CFRepositionTimerInMode(rlm, rlt, true);
+                        __CFRepositionTimerInMode(rlm, rlt, true);
                    }
                }
                __CFRunLoopTimerFireTSRUnlock();
@@ -1957,7 +2136,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
                __CFRunLoopTimerUnlock(rlt);
                __CFRunLoopTimerFireTSRLock();
                rlt->_fireTSR = nextFireTSR;
-                rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTSRToTimeInterval(nextFireTSR - (int64_t)mach_absolute_time());
+                rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTimeIntervalUntilTSR(nextFireTSR);
                __CFRunLoopTimerFireTSRUnlock();
             }
         }
@@ -1968,17 +2147,22 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
     return timerHandled;
 }
 
+
 // rl and rlm are locked on entry and exit
-static Boolean __CFRunLoopDoTimers(CFRunLoopRef rl, CFRunLoopModeRef rlm, int64_t limitTSR) {  /* DOES CALLOUT */
+static Boolean __CFRunLoopDoTimers(CFRunLoopRef rl, CFRunLoopModeRef rlm, uint64_t limitTSR) { /* DOES CALLOUT */
     Boolean timerHandled = false;
     CFMutableArrayRef timers = NULL;
     for (CFIndex idx = 0, cnt = rlm->_timers ? CFArrayGetCount(rlm->_timers) : 0; idx < cnt; idx++) {
         CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(rlm->_timers, idx);
-        if (__CFIsValid(rlt) && rlt->_fireTSR <= limitTSR && !__CFRunLoopTimerIsFiring(rlt)) {
-            if (!timers) timers = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-            CFArrayAppendValue(timers, rlt);
+        
+        if (__CFIsValid(rlt) && !__CFRunLoopTimerIsFiring(rlt)) {
+            if (rlt->_fireTSR <= limitTSR) {
+                if (!timers) timers = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+                CFArrayAppendValue(timers, rlt);
+            }
         }
     }
+    
     for (CFIndex idx = 0, cnt = timers ? CFArrayGetCount(timers) : 0; idx < cnt; idx++) {
         CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)CFArrayGetValueAtIndex(timers, idx);
         Boolean did = __CFRunLoopDoTimer(rl, rlm, rlt);
@@ -2009,8 +2193,9 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
 
 #define TIMEOUT_INFINITY (~(mach_msg_timeout_t)0)
 
-static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_msg_timeout_t timeout) {
+static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_port_t *livePort, mach_msg_timeout_t timeout) {
     Boolean originalBuffer = true;
+    kern_return_t ret = KERN_SUCCESS;
     for (;;) {         /* In that sleep of death what nightmares may come ... */
         mach_msg_header_t *msg = (mach_msg_header_t *)*buffer;
         msg->msgh_bits = 0;
@@ -2018,11 +2203,17 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header
         msg->msgh_remote_port = MACH_PORT_NULL;
         msg->msgh_size = buffer_size;
         msg->msgh_id = 0;
-        kern_return_t ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_LARGE|((TIMEOUT_INFINITY != timeout) ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, timeout, MACH_PORT_NULL);
-        if (MACH_MSG_SUCCESS == ret) return true;
+        if (TIMEOUT_INFINITY == timeout) { CFRUNLOOP_SLEEP(); } else { CFRUNLOOP_POLL(); }
+        ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_LARGE|((TIMEOUT_INFINITY != timeout) ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, timeout, MACH_PORT_NULL);
+        CFRUNLOOP_WAKEUP(ret);
+        if (MACH_MSG_SUCCESS == ret) {
+            *livePort = msg ? msg->msgh_local_port : MACH_PORT_NULL;
+            return true;
+        }
         if (MACH_RCV_TIMED_OUT == ret) {
             if (!originalBuffer) free(msg);
             *buffer = NULL;
+            *livePort = MACH_PORT_NULL;
             return false;
         }
         if (MACH_RCV_TOO_LARGE != ret) break;
@@ -2095,7 +2286,7 @@ static Boolean __CFRunLoopWaitForMultipleObjects(__CFPortSet portSet, HANDLE *on
 struct __timeout_context {
     dispatch_source_t ds;
     CFRunLoopRef rl;
-    int64_t termTSR;
+    uint64_t termTSR;
 };
 
 static void __CFRunLoopTimeoutCancel(void *arg) {
@@ -2107,14 +2298,15 @@ static void __CFRunLoopTimeoutCancel(void *arg) {
 
 static void __CFRunLoopTimeout(void *arg) {
     struct __timeout_context *context = (struct __timeout_context *)arg;
-    context->termTSR = 0LL;
+    context->termTSR = 0ULL;
+    CFRUNLOOP_WAKEUP_FOR_TIMEOUT();
     CFRunLoopWakeUp(context->rl);
     // The interval is DISPATCH_TIME_FOREVER, so this won't fire again
 }
 
 /* rl, rlm are locked on entrance and exit */
 static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
-    int64_t startTSR = (int64_t)mach_absolute_time();
+    uint64_t startTSR = mach_absolute_time();
 
     if (__CFRunLoopIsStopped(rl)) {
         __CFRunLoopUnsetStopped(rl);
@@ -2127,12 +2319,22 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
     mach_port_name_t dispatchPort = MACH_PORT_NULL;
     Boolean libdispatchQSafe = pthread_main_np() && ((HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && NULL == previousMode) || (!HANDLE_DISPATCH_ON_BASE_INVOCATION_ONLY && 0 == _CFGetTSD(__CFTSDKeyIsInGCDMainQ)));
     if (libdispatchQSafe && (CFRunLoopGetMain() == rl) && CFSetContainsValue(rl->_commonModes, rlm->_name)) dispatchPort = _dispatch_get_main_queue_port_4CF();
-
+    
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+    mach_port_name_t modeQueuePort = MACH_PORT_NULL;
+    if (rlm->_queue) {
+        modeQueuePort = _dispatch_runloop_root_queue_get_port_4CF(rlm->_queue);
+        if (!modeQueuePort) {
+            CRASH("Unable to get port for run loop mode queue (%d)", -1);
+        }
+    }
+#endif
+    
     dispatch_source_t timeout_timer = NULL;
     struct __timeout_context *timeout_context = (struct __timeout_context *)malloc(sizeof(*timeout_context));
     if (seconds <= 0.0) { // instant timeout
         seconds = 0.0;
-        timeout_context->termTSR = 0LL;
+        timeout_context->termTSR = 0ULL;
     } else if (seconds <= TIMER_INTERVAL_LIMIT) {
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, DISPATCH_QUEUE_OVERCOMMIT);
        timeout_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
@@ -2143,12 +2345,12 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
        dispatch_set_context(timeout_timer, timeout_context); // source gets ownership of context
        dispatch_source_set_event_handler_f(timeout_timer, __CFRunLoopTimeout);
         dispatch_source_set_cancel_handler_f(timeout_timer, __CFRunLoopTimeoutCancel);
-        uint64_t nanos = (uint64_t)(seconds * 1000 * 1000 + 1) * 1000;
-       dispatch_source_set_timer(timeout_timer, dispatch_time(DISPATCH_TIME_NOW, nanos), DISPATCH_TIME_FOREVER, 0);
-       dispatch_resume(timeout_timer);
+        uint64_t ns_at = (uint64_t)((__CFTSRToTimeInterval(startTSR) + seconds) * 1000000000ULL);
+        dispatch_source_set_timer(timeout_timer, dispatch_time(1, ns_at), DISPATCH_TIME_FOREVER, 1000ULL);
+        dispatch_resume(timeout_timer);
     } else { // infinite timeout
         seconds = 9999999999.0;
-        timeout_context->termTSR = INT64_MAX;
+        timeout_context->termTSR = UINT64_MAX;
     }
 
     Boolean didDispatchPortLastTime = true;
@@ -2157,6 +2359,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         uint8_t msg_buffer[3 * 1024];
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         mach_msg_header_t *msg = NULL;
+        mach_port_t livePort = MACH_PORT_NULL;
 #elif DEPLOYMENT_TARGET_WINDOWS
         HANDLE livePort = NULL;
         Boolean windowsMessageReceived = false;
@@ -2175,12 +2378,12 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
             __CFRunLoopDoBlocks(rl, rlm);
        }
 
-        Boolean poll = sourceHandledThisLoop || (0LL == timeout_context->termTSR);
+        Boolean poll = sourceHandledThisLoop || (0ULL == timeout_context->termTSR);
 
         if (MACH_PORT_NULL != dispatchPort && !didDispatchPortLastTime) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             msg = (mach_msg_header_t *)msg_buffer;
-            if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), 0)) {
+            if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0)) {
                 goto handle_msg;
             }
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -2201,17 +2404,45 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         // want these ports to get serviced.
 
         __CFPortSetInsert(dispatchPort, waitSet);
-                
+        
        __CFRunLoopModeUnlock(rlm);
        __CFRunLoopUnlock(rl);
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+        do {
+            if (kCFUseCollectableAllocator) {
+                objc_clear_stack(0);
+                memset(msg_buffer, 0, sizeof(msg_buffer));
+            }
+            msg = (mach_msg_header_t *)msg_buffer;
+            __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY);
+            
+            if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) {
+                // Drain the internal queue. If one of the callout blocks sets the timerFired flag, break out and service the timer.
+                while (_dispatch_runloop_root_queue_perform_4CF(rlm->_queue));
+                if (rlm->_timerFired) {
+                    // Leave livePort as the queue port, and service timers below
+                    rlm->_timerFired = false;
+                    break;
+                } else {
+                    if (msg && msg != (mach_msg_header_t *)msg_buffer) free(msg);
+                }
+            } else {
+                // Go ahead and leave the inner loop.
+                break;
+            }
+        } while (1);
+#else
         if (kCFUseCollectableAllocator) {
             objc_clear_stack(0);
             memset(msg_buffer, 0, sizeof(msg_buffer));
         }
         msg = (mach_msg_header_t *)msg_buffer;
-        __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), poll ? 0 : TIMEOUT_INFINITY);
+        __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY);
+#endif
+        
+        
 #elif DEPLOYMENT_TARGET_WINDOWS
         // Here, use the app-supplied message queue mask. They will set this if they are interested in having this run loop receive windows messages.
         __CFRunLoopWaitForMultipleObjects(waitSet, NULL, poll ? 0 : TIMEOUT_INFINITY, rlm->_msgQMask, &livePort, &windowsMessageReceived);
@@ -2236,9 +2467,6 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         handle_msg:;
         __CFRunLoopSetIgnoreWakeUps(rl);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-        mach_port_t livePort = msg ? msg->msgh_local_port : MACH_PORT_NULL;
-#endif
 #if DEPLOYMENT_TARGET_WINDOWS
         if (windowsMessageReceived) {
             // These Win32 APIs cause a callout, so make sure we're unlocked first and relocked after
@@ -2277,35 +2505,52 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         
 #endif
         if (MACH_PORT_NULL == livePort) {
+            CFRUNLOOP_WAKEUP_FOR_NOTHING();
             // handle nothing
         } else if (livePort == rl->_wakeUpPort) {
+            CFRUNLOOP_WAKEUP_FOR_WAKEUP();
             // do nothing on Mac OS
 #if DEPLOYMENT_TARGET_WINDOWS
             // Always reset the wake up port, or risk spinning forever
             ResetEvent(rl->_wakeUpPort);
 #endif
-        } else if (livePort == rlm->_timerPort) {
-#if DEPLOYMENT_TARGET_WINDOWS
-            // On Windows, we have observed an issue where the timer port is set before the time which we requested it to be set. For example, we set the fire time to be TSR 167646765860, but it is actually observed firing at TSR 167646764145, which is 1715 ticks early. On the hardware where this was observed, multiplying by the TSR to seconds conversion rate shows that this was 0.000478~ seconds early, but the tenus used when setting fire dates is 0.00001 seconds. The result is that, when __CFRunLoopDoTimers checks to see if any of the run loop timers should be firing, it appears to be 'too early' for the next timer, and no timers are handled.
+        }
+#if USE_DISPATCH_SOURCE_FOR_TIMERS
+        else if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) {
+            CFRUNLOOP_WAKEUP_FOR_TIMER();
+            if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) {
+                // Re-arm the next timer, because we apparently fired early
+                __CFArmNextTimerInMode(rlm, rl);
+            }
+        }
+#endif
+#if USE_MK_TIMER_TOO
+        else if (rlm->_timerPort != MACH_PORT_NULL && livePort == rlm->_timerPort) {
+            CFRUNLOOP_WAKEUP_FOR_TIMER();
+            // On Windows, we have observed an issue where the timer port is set before the time which we requested it to be set. For example, we set the fire time to be TSR 167646765860, but it is actually observed firing at TSR 167646764145, which is 1715 ticks early. The result is that, when __CFRunLoopDoTimers checks to see if any of the run loop timers should be firing, it appears to be 'too early' for the next timer, and no timers are handled.
             // In this case, the timer port has been automatically reset (since it was returned from MsgWaitForMultipleObjectsEx), and if we do not re-arm it, then no timers will ever be serviced again unless something adjusts the timer list (e.g. adding or removing timers). The fix for the issue is to reset the timer here if CFRunLoopDoTimers did not handle a timer itself. 9308754
             if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) {
                 // Re-arm the next timer
-                __CFArmNextTimerInMode(rlm);
+                __CFArmNextTimerInMode(rlm, rl);
             }
-#else
-            __CFRunLoopDoTimers(rl, rlm, mach_absolute_time());
+        }
 #endif
-        } else if (livePort == dispatchPort) {
-               __CFRunLoopModeUnlock(rlm);
-               __CFRunLoopUnlock(rl);
+        else if (livePort == dispatchPort) {
+            CFRUNLOOP_WAKEUP_FOR_DISPATCH();
+            __CFRunLoopModeUnlock(rlm);
+            __CFRunLoopUnlock(rl);
             _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL);
-               _dispatch_main_queue_callback_4CF(msg);
+#if DEPLOYMENT_TARGET_WINDOWS
+            void *msg = 0;
+#endif
+            __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg);
             _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL);
                __CFRunLoopLock(rl);
                __CFRunLoopModeLock(rlm);
                sourceHandledThisLoop = true;
             didDispatchPortLastTime = true;
         } else {
+            CFRUNLOOP_WAKEUP_FOR_SOURCE();
             // Despite the name, this works for windows handles as well
             CFRunLoopSourceRef rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort);
             if (rls) {
@@ -2326,10 +2571,11 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
 #endif
         
        __CFRunLoopDoBlocks(rl, rlm);
+        
 
        if (sourceHandledThisLoop && stopAfterHandle) {
            retVal = kCFRunLoopRunHandledSource;
-        } else if (timeout_context->termTSR < (int64_t)mach_absolute_time()) {
+        } else if (timeout_context->termTSR < mach_absolute_time()) {
             retVal = kCFRunLoopRunTimedOut;
        } else if (__CFRunLoopIsStopped(rl)) {
             __CFRunLoopUnsetStopped(rl);
@@ -2366,10 +2612,12 @@ SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterva
     volatile _per_run_data *previousPerRun = __CFRunLoopPushPerRunData(rl);
     CFRunLoopModeRef previousMode = rl->_currentMode;
     rl->_currentMode = currentMode;
-    int32_t result;
+    int32_t result = kCFRunLoopRunFinished;
+
        if (currentMode->_observerMask & kCFRunLoopEntry ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry);
        result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
        if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
+
         __CFRunLoopModeUnlock(currentMode);
         __CFRunLoopPopPerRunData(rl, previousPerRun);
        rl->_currentMode = previousMode;
@@ -2395,8 +2643,10 @@ CFAbsoluteTime CFRunLoopGetNextTimerFireDate(CFRunLoopRef rl, CFStringRef modeNa
     __CFRunLoopLock(rl);
     CFRunLoopModeRef rlm = __CFRunLoopFindMode(rl, modeName, false);
     CFAbsoluteTime at = 0.0;
-    CFRunLoopTimerRef timer = (rlm && rlm->_timers && 0 < CFArrayGetCount(rlm->_timers)) ? (CFRunLoopTimerRef)CFArrayGetValueAtIndex(rlm->_timers, 0) : NULL;
-    if (timer) at = CFRunLoopTimerGetNextFireDate(timer);
+    CFRunLoopTimerRef nextTimer = (rlm && rlm->_timers && 0 < CFArrayGetCount(rlm->_timers)) ? (CFRunLoopTimerRef)CFArrayGetValueAtIndex(rlm->_timers, 0) : NULL;
+    if (nextTimer) {
+        at = CFRunLoopTimerGetNextFireDate(nextTimer);
+    }
     if (rlm) __CFRunLoopModeUnlock(rlm);
     __CFRunLoopUnlock(rl);
     return at;
@@ -2421,12 +2671,7 @@ void CFRunLoopWakeUp(CFRunLoopRef rl) {
      * to lose a wakeup, but the send may fail if there is already a
      * wakeup pending, since the queue length is 1. */
     ret = __CFSendTrivialMachMessage(rl->_wakeUpPort, 0, MACH_SEND_TIMEOUT, 0);
-    if (ret != MACH_MSG_SUCCESS && ret != MACH_SEND_TIMED_OUT) {
-        char msg[256];
-        snprintf(msg, 256, "*** Unable to send message to wake up port. (%d) ***", ret);
-        CRSetCrashLogMessage(msg); 
-       HALT;
-    }
+    if (ret != MACH_MSG_SUCCESS && ret != MACH_SEND_TIMED_OUT) CRASH("*** Unable to send message to wake up port. (%d) ***", ret);
 #elif DEPLOYMENT_TARGET_WINDOWS
     SetEvent(rl->_wakeUpPort);
 #endif
@@ -2640,7 +2885,7 @@ void CFRunLoopRemoveSource(CFRunLoopRef rl, CFRunLoopSourceRef rls, CFStringRef
             }
             __CFRunLoopSourceUnlock(rls);
            if (0 == rls->_context.version0.version) {
-               if (NULL != rls->_context.version0.schedule) {
+               if (NULL != rls->_context.version0.cancel) {
                    doVer0Callout = true;
                }
            }
@@ -2821,11 +3066,11 @@ Boolean CFRunLoopContainsTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringR
        }
     } else {
        CFRunLoopModeRef rlm = __CFRunLoopFindMode(rl, modeName, false);
-       if (NULL != rlm && NULL != rlm->_timers) {
-            CFIndex idx = CFArrayGetFirstIndexOfValue(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)), rlt);
-            hasValue = (kCFNotFound != idx);
-       } 
-        if (NULL != rlm) {
+       if (NULL != rlm) {
+            if (NULL != rlm->_timers) {
+                CFIndex idx = CFArrayGetFirstIndexOfValue(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)), rlt);
+                hasValue = (kCFNotFound != idx);
+            }
            __CFRunLoopModeUnlock(rlm);
        }
     }
@@ -2852,10 +3097,12 @@ void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeN
        }
     } else {
        CFRunLoopModeRef rlm = __CFRunLoopFindMode(rl, modeName, true);
-       if (NULL != rlm && NULL == rlm->_timers) {
-           CFArrayCallBacks cb = kCFTypeArrayCallBacks;
-           cb.equal = NULL;
-           rlm->_timers = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+       if (NULL != rlm) {
+            if (NULL == rlm->_timers) {
+                CFArrayCallBacks cb = kCFTypeArrayCallBacks;
+                cb.equal = NULL;
+                rlm->_timers = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &cb);
+            }
        }
        if (NULL != rlm && !CFSetContainsValue(rlt->_rlModes, rlm->_name)) {
             __CFRunLoopTimerLock(rlt);
@@ -2870,7 +3117,7 @@ void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeN
            CFSetAddValue(rlt->_rlModes, rlm->_name);
             __CFRunLoopTimerUnlock(rlt);
             __CFRunLoopTimerFireTSRLock();
-           __CFRepositionTimerInMode(rlm, rlt, false);
+            __CFRepositionTimerInMode(rlm, rlt, false);
             __CFRunLoopTimerFireTSRUnlock();
             if (!_CFExecutableLinkedOnOrAfter(CFSystemVersionLion)) {
                 // Normally we don't do this on behalf of clients, but for
@@ -2903,8 +3150,12 @@ void CFRunLoopRemoveTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef mo
     } else {
        CFRunLoopModeRef rlm = __CFRunLoopFindMode(rl, modeName, false);
         CFIndex idx = kCFNotFound;
-       if (NULL != rlm && NULL != rlm->_timers) {
-            idx = CFArrayGetFirstIndexOfValue(rlm->_timers, CFRangeMake(0, CFArrayGetCount(rlm->_timers)), rlt);
+        CFMutableArrayRef timerList = NULL;
+        if (NULL != rlm) {
+            timerList = rlm->_timers;
+            if (NULL != timerList) {
+                idx = CFArrayGetFirstIndexOfValue(timerList, CFRangeMake(0, CFArrayGetCount(timerList)), rlt);
+            }
         }
         if (kCFNotFound != idx) {
             __CFRunLoopTimerLock(rlt);
@@ -2913,14 +3164,9 @@ void CFRunLoopRemoveTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef mo
                 rlt->_runLoop = NULL;
             }
             __CFRunLoopTimerUnlock(rlt);
-           CFArrayRemoveValueAtIndex(rlm->_timers, idx);
-            if (0 == CFArrayGetCount(rlm->_timers)) {
-                AbsoluteTime dummy;
-                mk_timer_cancel(rlm->_timerPort, &dummy);
-            } else if (0 == idx) {
-                __CFArmNextTimerInMode(rlm);
-            }
-       }
+           CFArrayRemoveValueAtIndex(timerList, idx);
+            __CFArmNextTimerInMode(rlm, rl);
+        }
         if (NULL != rlm) {
            __CFRunLoopModeUnlock(rlm);
        }
@@ -2973,7 +3219,7 @@ static CFStringRef __CFRunLoopSourceCopyDescription(CFTypeRef cf) {       /* DOES CALL
 #if DEPLOYMENT_TARGET_WINDOWS
     result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopSource %p [%p]>{signalled = %s, valid = %s, order = %d, context = %@}"), cf, CFGetAllocator(rls), __CFRunLoopSourceIsSignaled(rls) ? "Yes" : "No", __CFIsValid(rls) ? "Yes" : "No", rls->_order, contextDesc);
 #else
-    result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopSource %p [%p]>{signalled = %s, valid = %s, order = %d, context = %@}"), cf, CFGetAllocator(rls), __CFRunLoopSourceIsSignaled(rls) ? "Yes" : "No", __CFIsValid(rls) ? "Yes" : "No", rls->_order, contextDesc);
+    result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopSource %p [%p]>{signalled = %s, valid = %s, order = %ld, context = %@}"), cf, CFGetAllocator(rls), __CFRunLoopSourceIsSignaled(rls) ? "Yes" : "No", __CFIsValid(rls) ? "Yes" : "No", (unsigned long)rls->_order, contextDesc);
 #endif
     CFRelease(contextDesc);
     return result;
@@ -3001,7 +3247,7 @@ static const CFRuntimeClass __CFRunLoopSourceClass = {
     __CFRunLoopSourceCopyDescription
 };
 
-__private_extern__ void __CFRunLoopSourceInitialize(void) {
+CF_PRIVATE void __CFRunLoopSourceInitialize(void) {
     __kCFRunLoopSourceTypeID = _CFRuntimeRegisterClass(&__CFRunLoopSourceClass);
 }
 
@@ -3013,10 +3259,8 @@ CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order
     CHECK_FOR_FORK();
     CFRunLoopSourceRef memory;
     uint32_t size;
-    if (NULL == context) {
-        CRSetCrashLogMessage("*** NULL context value passed to CFRunLoopSourceCreate(). ***"); 
-        HALT;
-    }
+    if (NULL == context) CRASH("*** NULL context value passed to CFRunLoopSourceCreate(). (%d) ***", -1);
+    
     size = sizeof(struct __CFRunLoopSource) - sizeof(CFRuntimeBase);
     memory = (CFRunLoopSourceRef)_CFRuntimeCreateInstance(allocator, __kCFRunLoopSourceTypeID, size, NULL);
     if (NULL == memory) {
@@ -3142,7 +3386,7 @@ Boolean CFRunLoopSourceIsSignalled(CFRunLoopSourceRef rls) {
     return ret;
 }
 
-__private_extern__ void _CFRunLoopSourceWakeUpRunLoops(CFRunLoopSourceRef rls) {
+CF_PRIVATE void _CFRunLoopSourceWakeUpRunLoops(CFRunLoopSourceRef rls) {
     CFBagRef loops = NULL;
     __CFRunLoopSourceLock(rls);
     if (__CFIsValid(rls) && NULL != rls->_runLoops) {
@@ -3173,7 +3417,7 @@ static CFStringRef __CFRunLoopObserverCopyDescription(CFTypeRef cf) {     /* DOES CA
     void *addr = rlo->_callout;
     Dl_info info;
     const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
-    result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopObserver %p [%p]>{valid = %s, activities = 0x%x, repeats = %s, order = %d, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlo), __CFIsValid(rlo) ? "Yes" : "No", rlo->_activities, __CFRunLoopObserverRepeats(rlo) ? "Yes" : "No", rlo->_order, name, addr, contextDesc);
+    result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopObserver %p [%p]>{valid = %s, activities = 0x%lx, repeats = %s, order = %ld, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlo), __CFIsValid(rlo) ? "Yes" : "No", (long)rlo->_activities, __CFRunLoopObserverRepeats(rlo) ? "Yes" : "No", (long)rlo->_order, name, addr, contextDesc);
 #endif
     CFRelease(contextDesc);
     return result;
@@ -3197,7 +3441,7 @@ static const CFRuntimeClass __CFRunLoopObserverClass = {
     __CFRunLoopObserverCopyDescription
 };
 
-__private_extern__ void __CFRunLoopObserverInitialize(void) {
+CF_PRIVATE void __CFRunLoopObserverInitialize(void) {
     __kCFRunLoopObserverTypeID = _CFRuntimeRegisterClass(&__CFRunLoopObserverClass);
 }
 
@@ -3332,7 +3576,8 @@ void CFRunLoopObserverGetContext(CFRunLoopObserverRef rlo, CFRunLoopObserverCont
     *context = rlo->_context;
 }
 
-/* CFRunLoopTimer */
+#pragma mark -
+#pragma mark CFRunLoopTimer
 
 static CFStringRef __CFRunLoopTimerCopyDescription(CFTypeRef cf) {     /* DOES CALLOUT */
     CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)cf;
@@ -3344,12 +3589,27 @@ static CFStringRef __CFRunLoopTimerCopyDescription(CFTypeRef cf) {      /* DOES CALLO
        contextDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopTimer context %p>"), rlt->_context.info);
     }
     void *addr = (void *)rlt->_callout;
-    const char *name = "???";
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-    Dl_info info;
-    name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
-#endif
-    CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopTimer %p [%p]>{valid = %s, firing = %s, interval = %0.09g, next fire date = %0.09g, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlt), __CFIsValid(rlt) ? "Yes" : "No", __CFRunLoopTimerIsFiring(rlt) ? "Yes" : "No", rlt->_interval, rlt->_nextFireDate, name, addr, contextDesc);
+    char libraryName[2048];
+    char functionName[2048];
+    void *functionPtr = NULL;
+    libraryName[0] = '?'; libraryName[1] = '\0';
+    functionName[0] = '?'; functionName[1] = '\0';
+    CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL,
+        CFSTR("<CFRunLoopTimer %p [%p]>{valid = %s, firing = %s, interval = %0.09g, tolerance = %0.09g, next fire date = %0.09g (%0.09g @ %lld), callout = %s (%p / %p) (%s), context = %@}"),
+              cf,
+              CFGetAllocator(rlt),
+              __CFIsValid(rlt) ? "Yes" : "No",
+              __CFRunLoopTimerIsFiring(rlt) ? "Yes" : "No",
+              rlt->_interval,
+              rlt->_tolerance,
+              rlt->_nextFireDate,
+              rlt->_nextFireDate - CFAbsoluteTimeGetCurrent(),
+              rlt->_fireTSR,
+              functionName,
+              addr,
+              functionPtr,
+              libraryName,
+              contextDesc);
     CFRelease(contextDesc);
     return result;
 }
@@ -3376,7 +3636,7 @@ static const CFRuntimeClass __CFRunLoopTimerClass = {
     __CFRunLoopTimerCopyDescription
 };
 
-__private_extern__ void __CFRunLoopTimerInitialize(void) {
+CF_PRIVATE void __CFRunLoopTimerInitialize(void) {
     __kCFRunLoopTimerTypeID = _CFRuntimeRegisterClass(&__CFRunLoopTimerClass);
 }
 
@@ -3401,10 +3661,11 @@ CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime
     memory->_order = order;
     if (interval < 0.0) interval = 0.0;
     memory->_interval = interval;
+    memory->_tolerance = 0.0;
     if (TIMER_DATE_LIMIT < fireDate) fireDate = TIMER_DATE_LIMIT;
     memory->_nextFireDate = fireDate;
-    memory->_fireTSR = 0LL;
-    int64_t now2 = (int64_t)mach_absolute_time();
+    memory->_fireTSR = 0ULL;
+    uint64_t now2 = mach_absolute_time();
     CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
     if (fireDate < now1) {
        memory->_fireTSR = now2;
@@ -3469,8 +3730,8 @@ void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDat
     CHECK_FOR_FORK();
     if (!__CFIsValid(rlt)) return;
     if (TIMER_DATE_LIMIT < fireDate) fireDate = TIMER_DATE_LIMIT;
-    int64_t nextFireTSR = 0LL;
-    int64_t now2 = (int64_t)mach_absolute_time();
+    uint64_t nextFireTSR = 0ULL;
+    uint64_t now2 = mach_absolute_time();
     CFAbsoluteTime now1 = CFAbsoluteTimeGetCurrent();
     if (fireDate < now1) {
        nextFireTSR = now2;
@@ -3613,3 +3874,36 @@ void CFRunLoopTimerGetContext(CFRunLoopTimerRef rlt, CFRunLoopTimerContext *cont
     *context = rlt->_context;
 }
 
+CFTimeInterval CFRunLoopTimerGetTolerance(CFRunLoopTimerRef rlt) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, CFTimeInterval, (NSTimer *)rlt, tolerance);
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    return rlt->_tolerance;
+#else
+    return 0.0;
+#endif
+}
+
+void CFRunLoopTimerSetTolerance(CFRunLoopTimerRef rlt, CFTimeInterval tolerance) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    CHECK_FOR_FORK();
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, void, (NSTimer *)rlt, setTolerance:tolerance);
+    __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
+    /*
+     * dispatch rules:
+     *
+     * For the initial timer fire at 'start', the upper limit to the allowable
+     * delay is set to 'leeway' nanoseconds. For the subsequent timer fires at
+     * 'start' + N * 'interval', the upper limit is MIN('leeway','interval'/2).
+     */
+    if (rlt->_interval > 0) {
+        rlt->_tolerance = MIN(tolerance, rlt->_interval / 2);
+    } else {
+        // Tolerance must be a positive value or zero
+        if (tolerance < 0) tolerance = 0.0;
+        rlt->_tolerance = tolerance;
+    }
+#endif
+}
+
index e2eb7f3abced714bfb268506cbfcee63bcebc2b1..2744ea10464fa4939d6f4382c81dfdcfbec928c1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFRunLoop.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFRUNLOOP__)
@@ -193,6 +193,11 @@ CF_EXPORT void CFRunLoopTimerInvalidate(CFRunLoopTimerRef timer);
 CF_EXPORT Boolean CFRunLoopTimerIsValid(CFRunLoopTimerRef timer);
 CF_EXPORT void CFRunLoopTimerGetContext(CFRunLoopTimerRef timer, CFRunLoopTimerContext *context);
 
+// Setting a tolerance for a timer allows it to fire later than the scheduled fire date, improving the ability of the system to optimize for increased power savings and responsiveness. The timer may fire at any time between its scheduled fire date and the scheduled fire date plus the tolerance. The timer will not fire before the scheduled fire date. For repeating timers, the next fire date is calculated from the original fire date regardless of tolerance applied at individual fire times, to avoid drift. The default value is zero, which means no additional tolerance is applied. The system reserves the right to apply a small amount of tolerance to certain timers regardless of the value of this property.
+// As the user of the timer, you will have the best idea of what an appropriate tolerance for a timer may be. A general rule of thumb, though, is to set the tolerance to at least 10% of the interval, for a repeating timer. Even a small amount of tolerance will have a significant positive impact on the power usage of your application. The system may put a maximum value of the tolerance.
+CF_EXPORT CFTimeInterval CFRunLoopTimerGetTolerance(CFRunLoopTimerRef timer) CF_AVAILABLE(10_9, 7_0);
+CF_EXPORT void CFRunLoopTimerSetTolerance(CFRunLoopTimerRef timer, CFTimeInterval tolerance) CF_AVAILABLE(10_9, 7_0);
+
 CF_EXTERN_C_END
 
 #endif /* ! __COREFOUNDATION_CFRUNLOOP__ */
index 6a5ee6d29bcfaa3a5598c02484d8bf723da513a5..cb2d3fb46d936d415c2188f5c4d5b96886c08e9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFRuntime.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -70,7 +70,7 @@ __kCFReleaseEvent = 29
 #define FAKE_INSTRUMENTS 0
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-__private_extern__ void __CFOAInitializeNSObject(void);  // from NSObject.m
+CF_PRIVATE void __CFOAInitializeNSObject(void);  // from NSObject.m
 
 bool __CFOASafe = false;
 
@@ -199,10 +199,10 @@ static const CFRuntimeClass __CFTypeClass = {
 
 // the lock does not protect most reading of these; we just leak the old table to allow read-only accesses to continue to work
 static CFSpinLock_t __CFBigRuntimeFunnel = CFSpinLockInit;
-__private_extern__ CFRuntimeClass * __CFRuntimeClassTable[__CFRuntimeClassTableSize] = {0};
-__private_extern__ int32_t __CFRuntimeClassTableCount = 0;
+CF_PRIVATE CFRuntimeClass * __CFRuntimeClassTable[__CFRuntimeClassTableSize] = {0};
+CF_PRIVATE int32_t __CFRuntimeClassTableCount = 0;
 
-__private_extern__ uintptr_t __CFRuntimeObjCClassTable[__CFRuntimeClassTableSize] = {0};
+CF_PRIVATE uintptr_t __CFRuntimeObjCClassTable[__CFRuntimeClassTableSize] = {0};
 
 #if !defined(__CFObjCIsCollectable)
 bool (*__CFObjCIsCollectable)(void *) = NULL;
@@ -266,8 +266,8 @@ void _CFRuntimeUnregisterClassWithTypeID(CFTypeID typeID) {
 
 #if defined(DEBUG) || defined(ENABLE_ZOMBIES)
 
-__private_extern__ uint8_t __CFZombieEnabled = 0;
-__private_extern__ uint8_t __CFDeallocateZombies = 0;
+CF_PRIVATE uint8_t __CFZombieEnabled = 0;
+CF_PRIVATE uint8_t __CFDeallocateZombies = 0;
 
 extern void __CFZombifyNSObject(void);  // from NSObject.m
 
@@ -299,11 +299,11 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF
         CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeCreateInstance() found inconsistent class '%s'."), cls->className);
         return NULL;
     }
-    if (customRC && kCFUseCollectableAllocator && (kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) {
+    if (customRC && kCFUseCollectableAllocator && (0 || 0)) {
         CFLog(kCFLogLevelWarning, CFSTR("*** _CFRuntimeCreateInstance(): special zero-ref allocators cannot be used with class '%s' with custom ref counting."), cls->className);
         return NULL;
     }
-    CFAllocatorRef realAllocator = _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
+    CFAllocatorRef realAllocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
     if (kCFAllocatorNull == realAllocator) {
        return NULL;
     }
@@ -330,10 +330,9 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF
        *(CFAllocatorRef *)((char *)memory) = (CFAllocatorRef)CFRetain(realAllocator);
        memory = (CFRuntimeBase *)((char *)memory + sizeof(CFAllocatorRef));
     }
-    memory->_cfisa = __CFISAForTypeID(typeID);
     uint32_t rc = 0;
 #if __LP64__
-    if (!kCFUseCollectableAllocator || (kCFAllocatorSystemDefaultGCRefZero != allocator && kCFAllocatorDefaultGCRefZero != allocator)) {
+    if (!kCFUseCollectableAllocator || (1 && 1)) {
         memory->_rc = 1;
     }
     if (customRC) {
@@ -341,7 +340,7 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF
         rc = 0xFF;
     }
 #else
-    if (!kCFUseCollectableAllocator || (kCFAllocatorSystemDefaultGCRefZero != allocator && kCFAllocatorDefaultGCRefZero != allocator)) {
+    if (!kCFUseCollectableAllocator || (1 && 1)) {
         rc = 1;
     }
     if (customRC) {
@@ -350,6 +349,7 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF
 #endif
     uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfo);
     *cfinfop = (uint32_t)((rc << 24) | (customRC ? 0x800000 : 0x0) | ((uint32_t)typeID << 8) | (usesSystemDefaultAllocator ? 0x80 : 0x00));
+    memory->_cfisa = 0;
     if (NULL != cls->init) {
        (cls->init)(memory);
     }
@@ -366,12 +366,12 @@ void _CFRuntimeInitStaticInstance(void *ptr, CFTypeID typeID) {
         return;
     }
     CFRuntimeBase *memory = (CFRuntimeBase *)ptr;
-    memory->_cfisa = __CFISAForTypeID(typeID);
     uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfo);
     *cfinfop = (uint32_t)(((customRC ? 0xFF : 0) << 24) | (customRC ? 0x800000 : 0x0) | ((uint32_t)typeID << 8) | 0x80);
 #if __LP64__
     memory->_rc = customRC ? 0xFFFFFFFFU : 0x0;
 #endif
+    memory->_cfisa = 0;
     if (NULL != cfClass->init) {
        (cfClass->init)(memory);
     }
@@ -397,6 +397,10 @@ void _CFRuntimeSetInstanceTypeID(CFTypeRef cf, CFTypeID newTypeID) {
     *cfinfop = (*cfinfop & 0xFFF000FFU) | ((uint32_t)newTypeID << 8);
 }
 
+CF_PRIVATE void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID) {
+    _CFRuntimeSetInstanceTypeID(cf, newTypeID);
+}
+
 
 enum {
     __kCFObjectRetainedEvent = 12,
@@ -453,68 +457,6 @@ CF_EXPORT uintptr_t __CFDoExternRefOperation(uintptr_t op, id obj) {
     return 0;
 }
 
-static void __CFExternRefNullFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-}
-    
-static uintptr_t __CFExternRefNullRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    return stack_value;
-}
-
-static uintptr_t __CFExternRefNullRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    return stack_key;
-}
-
-static void __CFExternRefNullReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-}
-
-static void __CFExternRefNullReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-}
-
-static Boolean __CFExternRefNullEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    return coll_value1 == stack_value2;
-}
-
-static Boolean __CFExternRefNullEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    return coll_key1 == stack_key2;
-}
-
-static uintptr_t __CFExternRefNullHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    return stack_key;
-}
-
-static uintptr_t __CFExternRefNullGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFExternRefNullCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
-}
-
-static CFStringRef __CFExternRefNullCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
-}
-
-static CFBasicHashCallbacks *__CFExternRefNullCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-
-static const CFBasicHashCallbacks CFExternRefCallbacks = {
-    __CFExternRefNullCopyCallbacks,
-    __CFExternRefNullFreeCallbacks,
-    __CFExternRefNullRetainValue,
-    __CFExternRefNullRetainKey,
-    __CFExternRefNullReleaseValue,
-    __CFExternRefNullReleaseKey,
-    __CFExternRefNullEquateValues,
-    __CFExternRefNullEquateKeys,
-    __CFExternRefNullHashKey,
-    __CFExternRefNullGetIndirectKey,
-    __CFExternRefNullCopyValueDescription,
-    __CFExternRefNullCopyKeyDescription
-};
-
-static CFBasicHashCallbacks *__CFExternRefNullCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    return (CFBasicHashCallbacks *)&CFExternRefCallbacks;
-}
-
 CF_EXPORT CFTypeID CFNumberGetTypeID(void);
 
 CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf) {
@@ -532,7 +474,7 @@ CFTypeID CFTypeGetTypeID(void) {
     return __kCFTypeTypeID;
 }
 
-__private_extern__ void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func) {
+CF_PRIVATE void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func) {
     if (cf && CF_IS_OBJC(type, cf)) return;
     CFAssert2((cf != NULL) && (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]) && (__kCFNotATypeTypeID != __CFGenericTypeID_inline(cf)) && (__kCFTypeTypeID != __CFGenericTypeID_inline(cf)), __kCFLogAssertion, "%s(): pointer %p is not a CF object", func, cf); \
     CFAssert3(__CFGenericTypeID_inline(cf) == type, __kCFLogAssertion, "%s(): pointer %p is not a %s", func, cf, __CFRuntimeClassTable[type]->className);      \
@@ -571,6 +513,11 @@ CFTypeRef CFRetain(CFTypeRef cf) {
     return _CFRetain(cf, false);
 }
 
+CFTypeRef CFAutorelease(CFTypeRef __attribute__((cf_consumed)) cf) {
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFAutorelease() called with NULL ***"); HALT; }
+    return cf;
+}
+
 static void _CFRelease(CFTypeRef cf);
 
 void CFRelease(CFTypeRef cf) {
@@ -591,18 +538,21 @@ void CFRelease(CFTypeRef cf) {
 }
 
 
-__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
+CF_PRIVATE void __CFAllocatorDeallocate(CFTypeRef cf);
 
-__private_extern__ const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr) {
+CF_PRIVATE const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr) {
     if (NULL == ptr) { CRSetCrashLogMessage("*** __CFStringCollectionCopy() called with NULL ***"); HALT; }
     CFStringRef theString = (CFStringRef)ptr;
-    CFStringRef result = CFStringCreateCopy(_CFConvertAllocatorToGCRefZeroEquivalent(allocator), theString);
+    CFStringRef result = CFStringCreateCopy((allocator), theString);
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        result = (CFStringRef)CFMakeCollectable(result);
+    }
     return (const void *)result;
 }
 
 extern void CFCollection_non_gc_storage_error(void);
 
-__private_extern__ const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr) {
+CF_PRIVATE const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr) {
     if (NULL == ptr) { CRSetCrashLogMessage("*** __CFTypeCollectionRetain() called with NULL; likely a collection has been corrupted ***"); HALT; }
     CFTypeRef cf = (CFTypeRef)ptr;
     // only collections allocated in the GC zone can opt-out of reference counting.
@@ -637,7 +587,7 @@ __private_extern__ const void *__CFTypeCollectionRetain(CFAllocatorRef allocator
 }
 
 
-__private_extern__ void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr) {
+CF_PRIVATE void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr) {
     if (NULL == ptr) { CRSetCrashLogMessage("*** __CFTypeCollectionRelease() called with NULL; likely a collection has been corrupted ***"); HALT; }
     CFTypeRef cf = (CFTypeRef)ptr;
     // only collections allocated in the GC zone can opt-out of reference counting.
@@ -775,7 +725,7 @@ CFStringRef CFCopyDescription(CFTypeRef cf) {
 }
 
 // Definition: if type produces a formatting description, return that string, otherwise NULL
-__private_extern__ CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
+CF_PRIVATE CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
     if (NULL == cf) return NULL;
     __CFGenericAssertIsCF(cf);
     if (NULL != __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->copyFormattingDesc) {
@@ -821,14 +771,15 @@ extern void __CFPlugInInstanceInitialize(void);
 extern void __CFUUIDInitialize(void);
 extern void __CFBinaryHeapInitialize(void);
 extern void __CFBitVectorInitialize(void);
+CF_PRIVATE void __CFDateInitialize(void);
 #if DEPLOYMENT_TARGET_LINUX
-__private_extern__ void __CFTSDLinuxInitialize();
+CF_PRIVATE void __CFTSDLinuxInitialize();
 #endif
 #if DEPLOYMENT_TARGET_WINDOWS
 // From CFPlatform.c
-__private_extern__ void __CFTSDWindowsInitialize(void);
-__private_extern__ void __CFTSDWindowsCleanup(void);
-__private_extern__ void __CFFinalizeWindowsThreadData();
+CF_PRIVATE void __CFTSDWindowsInitialize(void);
+CF_PRIVATE void __CFTSDWindowsCleanup(void);
+CF_PRIVATE void __CFFinalizeWindowsThreadData();
 #endif
 extern void __CFStreamInitialize(void);
 extern void __CFCalendarInitialize();
@@ -842,10 +793,10 @@ extern void __CFXPreferencesInitialize(void);
 #endif
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-__private_extern__ uint8_t __CF120290 = false;
-__private_extern__ uint8_t __CF120291 = false;
-__private_extern__ uint8_t __CF120293 = false;
-__private_extern__ char * __crashreporter_info__ = NULL; // Keep this symbol, since it was exported and other things may be linking against it, like GraphicsServices.framework on iOS
+CF_PRIVATE uint8_t __CF120290 = false;
+CF_PRIVATE uint8_t __CF120291 = false;
+CF_PRIVATE uint8_t __CF120293 = false;
+CF_PRIVATE char * __crashreporter_info__ = NULL; // Keep this symbol, since it was exported and other things may be linking against it, like GraphicsServices.framework on iOS
 asm(".desc ___crashreporter_info__, 0x10");
 
 static void __01121__(void) {
@@ -872,7 +823,7 @@ static void __01123__(void) {
 #define EXEC_WARNING_STRING_1 "The process has forked and you cannot use this CoreFoundation functionality safely. You MUST exec().\n"
 #define EXEC_WARNING_STRING_2 "Break on __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__() to debug.\n"
 
-__private_extern__ void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void) {
+CF_PRIVATE void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void) {
     write(2, EXEC_WARNING_STRING_1, sizeof(EXEC_WARNING_STRING_1) - 1);
     write(2, EXEC_WARNING_STRING_2, sizeof(EXEC_WARNING_STRING_2) - 1);
 //    HALT;
@@ -882,7 +833,7 @@ __private_extern__ void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOU
 
 CF_EXPORT const void *__CFArgStuff;
 const void *__CFArgStuff = NULL;
-__private_extern__ void *__CFAppleLanguages = NULL;
+CF_PRIVATE void *__CFAppleLanguages = NULL;
 
 // do not cache CFFIXED_USER_HOME or HOME, there are situations where they can change
 
@@ -915,16 +866,21 @@ static struct {
     {"__CFPREFERENCES_LOG_FAILURES", NULL},
     {"CFNumberDisableCache", NULL},
     {"__CFPREFERENCES_AVOID_DAEMON", NULL},
+    {"APPLE_FRAMEWORKS_ROOT", NULL},
     {NULL, NULL}, // the last one is for optional "COMMAND_MODE" "legacy", do not use this slot, insert before
 };
 
-__private_extern__ const char *__CFgetenv(const char *n) {
+CF_PRIVATE const char *__CFgetenv(const char *n) {
     for (CFIndex idx = 0; idx < sizeof(__CFEnv) / sizeof(__CFEnv[0]); idx++) {
        if (__CFEnv[idx].name && 0 == strcmp(n, __CFEnv[idx].name)) return __CFEnv[idx].value;
     }
     return getenv(n);
 }
 
+CF_PRIVATE Boolean __CFProcessIsRestricted() {
+    return issetugid();
+}
+
 #if DEPLOYMENT_TARGET_WINDOWS
 #define kNilPthreadT  { nil, nil }
 #else
@@ -932,16 +888,26 @@ __private_extern__ const char *__CFgetenv(const char *n) {
 #endif
 
 
-CF_EXPORT pthread_t _CFMainPThread;
-pthread_t _CFMainPThread = kNilPthreadT;
-
 #undef kCFUseCollectableAllocator
 CF_EXPORT bool kCFUseCollectableAllocator;
 bool kCFUseCollectableAllocator = false;
 
-__private_extern__ Boolean __CFProphylacticAutofsAccess = false;
-__private_extern__ Boolean __CFInitializing = 0;
-__private_extern__ Boolean __CFInitialized = 0;
+CF_PRIVATE Boolean __CFProphylacticAutofsAccess = false;
+CF_PRIVATE Boolean __CFInitializing = 0;
+CF_PRIVATE Boolean __CFInitialized = 0;
+
+// move the next 2 lines down into the #if below, and make it static, after Foundation gets off this symbol on other platforms
+CF_EXPORT pthread_t _CFMainPThread;
+pthread_t _CFMainPThread = kNilPthreadT;
+#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_IPHONESIMULATOR
+
+CF_EXPORT pthread_t _CF_pthread_main_thread_np(void);
+pthread_t _CF_pthread_main_thread_np(void) {
+    return _CFMainPThread;
+}
+#define pthread_main_thread_np() _CF_pthread_main_thread_np()
+
+#endif
 
 #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 static void __CFInitialize(void) __attribute__ ((constructor));
@@ -955,11 +921,11 @@ void __CFInitialize(void) {
     if (!__CFInitialized && !__CFInitializing) {
         __CFInitializing = 1;
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
-       if (!pthread_main_np()) HALT;   // CoreFoundation must be initialized on the main thread
+#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_IPHONESIMULATOR
+        if (!pthread_main_np()) HALT;   // CoreFoundation must be initialized on the main thread
 #endif
-
-       _CFMainPThread = pthread_self();
+       // move this next line up into the #if above after Foundation gets off this symbol
+        _CFMainPThread = pthread_self();
 
 #if DEPLOYMENT_TARGET_WINDOWS
         // Must not call any CF functions
@@ -1022,7 +988,8 @@ void __CFInitialize(void) {
         CFBagGetTypeID();
 
        for (CFIndex idx = 0; idx < NUM_EXTERN_TABLES; idx++) {
-           __NSRetainCounters[idx].table = CFBasicHashCreate(kCFAllocatorSystemDefault, kCFBasicHashHasCounts | kCFBasicHashLinearHashing | kCFBasicHashAggressiveGrowth, &CFExternRefCallbacks);
+            CFBasicHashCallbacks callbacks = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
+           __NSRetainCounters[idx].table = CFBasicHashCreate(kCFAllocatorSystemDefault, kCFBasicHashHasCounts | kCFBasicHashLinearHashing | kCFBasicHashAggressiveGrowth, &callbacks);
            CFBasicHashSetCapacity(__NSRetainCounters[idx].table, 40);
            __NSRetainCounters[idx].lock = CFSpinLockInit;
        }
@@ -1070,6 +1037,9 @@ void __CFInitialize(void) {
 #if DEPLOYMENT_TARGET_WINDOWS
         __CFWindowsNamedPipeInitialize();
 #endif
+        
+        __CFDateInitialize();
+
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
         __CFRunLoopInitialize();
         __CFRunLoopObserverInitialize();
@@ -1086,8 +1056,8 @@ void __CFInitialize(void) {
 #endif
 
         {
-            CFIndex idx, cnt;
-            char **args;
+            CFIndex idx, cnt = 0;
+            char **args = NULL;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             args = *_NSGetArgv();
             cnt = *_NSGetArgc();
@@ -1152,10 +1122,10 @@ void __CFInitialize(void) {
 
 #if DEPLOYMENT_TARGET_WINDOWS
 
-__private_extern__ void __CFStringCleanup(void);
-__private_extern__ void __CFSocketCleanup(void);
-__private_extern__ void __CFUniCharCleanup(void);
-__private_extern__ void __CFStreamCleanup(void);
+CF_PRIVATE void __CFStringCleanup(void);
+CF_PRIVATE void __CFSocketCleanup(void);
+CF_PRIVATE void __CFUniCharCleanup(void);
+CF_PRIVATE void __CFStreamCleanup(void);
 
 static CFBundleRef RegisterCoreFoundationBundle(void) {
 #ifdef _DEBUG
@@ -1345,13 +1315,17 @@ static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR) {
 // Never called under GC, only called via ARR weak subsystem; a return of NULL is failure
 CFTypeRef _CFTryRetain(CFTypeRef cf) {
     if (NULL == cf) return NULL;
-    if (CF_IS_TAGGED_OBJ(cf)) return cf; // success
+#if OBJC_HAVE_TAGGED_POINTERS
+    if (_objc_isTaggedPointer(cf)) return cf; // success
+#endif
     return _CFRetain(cf, true);
 }
 
 Boolean _CFIsDeallocating(CFTypeRef cf) {
     if (NULL == cf) return false;
-    if (CF_IS_TAGGED_OBJ(cf)) return false;
+#if OBJC_HAVE_TAGGED_POINTERS
+    if (_objc_isTaggedPointer(cf)) return false;
+#endif
     uint32_t cfinfo = *(uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo);
     if (cfinfo & 0x800000) { // custom ref counting for object
         return true;   // lie for now; this weak references to these objects cannot be formed
index 4ee6137c3d0ed3a130319d76c645599ed76f4576..3e2351593defaedb404d73c158038b2ca7017d87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFRuntime.h
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFRUNTIME__)
@@ -40,54 +40,18 @@ CF_EXTERN_C_BEGIN
 CF_EXPORT bool kCFUseCollectableAllocator;
 CF_EXPORT bool (*__CFObjCIsCollectable)(void *);
 
-// Only CoreFoundation and Foundation should use these *GCRefZero constants;
-// do not listen to anyone who tells you otherwise.
-
-CF_EXPORT
-const CFAllocatorRef kCFAllocatorSystemDefaultGCRefZero; // DO NOT USE THIS
-CF_EXPORT
-const CFAllocatorRef kCFAllocatorDefaultGCRefZero; // DO NOT USE THIS
-
-CF_INLINE CFAllocatorRef _CFConvertAllocatorToNonGCRefZeroEquivalent(CFAllocatorRef allocator) {
-    if (kCFAllocatorSystemDefaultGCRefZero == allocator) {
-        allocator = kCFAllocatorSystemDefault;
-    } else if (kCFAllocatorDefaultGCRefZero == allocator || NULL == allocator || kCFAllocatorDefault == allocator) {
-        allocator = CFAllocatorGetDefault();
-    }
-    return allocator;
-}
-
-CF_INLINE CFAllocatorRef _CFConvertAllocatorToGCRefZeroEquivalent(CFAllocatorRef allocator) { // DO NOT USE THIS
-    if (!kCFUseCollectableAllocator) return allocator;
-    if (kCFAllocatorDefault == allocator || NULL == allocator) {
-        allocator = CFAllocatorGetDefault();
-    }
-    if (kCFAllocatorSystemDefault == allocator) {
-        allocator = kCFAllocatorSystemDefaultGCRefZero;
-    } else if (CFAllocatorGetDefault() == allocator) {
-        allocator = kCFAllocatorDefaultGCRefZero;
-    }
-    return allocator;
-}
-
 CF_INLINE Boolean _CFAllocatorIsSystemDefault(CFAllocatorRef allocator) {
-    if (allocator == kCFAllocatorSystemDefaultGCRefZero || allocator == kCFAllocatorSystemDefault) return true;
-    if (kCFAllocatorDefaultGCRefZero == allocator || NULL == allocator || kCFAllocatorDefault == allocator) {
+    if (allocator == kCFAllocatorSystemDefault) return true;
+    if (NULL == allocator || kCFAllocatorDefault == allocator) {
         return (kCFAllocatorSystemDefault == CFAllocatorGetDefault());
     }
     return false;
 }
 
-CF_INLINE Boolean _CFAllocatorIsGCRefZero(CFAllocatorRef allocator) {
-    // not intended as a literal test, but as a behavioral test
-    if (!kCFUseCollectableAllocator) return false;
-    return (kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator);
-}
-
 // is GC on?
 #define CF_USING_COLLECTABLE_MEMORY (kCFUseCollectableAllocator)
 // is GC on and is this the GC allocator?
-#define CF_IS_COLLECTABLE_ALLOCATOR(allocator) (kCFUseCollectableAllocator && (NULL == (allocator) || kCFAllocatorSystemDefault == (allocator) || _CFAllocatorIsGCRefZero(allocator)))
+#define CF_IS_COLLECTABLE_ALLOCATOR(allocator) (kCFUseCollectableAllocator && (NULL == (allocator) || kCFAllocatorSystemDefault == (allocator) || 0))
 // is this allocated by the collector?
 #define CF_IS_COLLECTABLE(obj) (__CFObjCIsCollectable ? __CFObjCIsCollectable((void*)obj) : false)
 
@@ -95,11 +59,6 @@ CF_INLINE Boolean _CFAllocatorIsGCRefZero(CFAllocatorRef allocator) {
 
 #define kCFUseCollectableAllocator 0
 #define __CFObjCIsCollectable 0
-#define kCFAllocatorSystemDefaultGCRefZero kCFAllocatorSystemDefault
-#define kCFAllocatorDefaultGCRefZero kCFAllocatorDefault
-
-#define _CFConvertAllocatorToNonGCRefZeroEquivalent(A) (A)
-#define _CFConvertAllocatorToGCRefZeroEquivalent(A) (A)
 
 CF_INLINE Boolean _CFAllocatorIsSystemDefault(CFAllocatorRef allocator) {
     if (allocator == kCFAllocatorSystemDefault) return true;
@@ -109,7 +68,6 @@ CF_INLINE Boolean _CFAllocatorIsSystemDefault(CFAllocatorRef allocator) {
     return false;
 }
 
-#define _CFAllocatorIsGCRefZero(A) (0)
 #define CF_USING_COLLECTABLE_MEMORY 0
 #define CF_IS_COLLECTABLE_ALLOCATOR(allocator) 0
 #define CF_IS_COLLECTABLE(obj) 0
diff --git a/CFSet.c b/CFSet.c
index 775b4e8b9861adb72ecf6700ae9fd4750ab2ef4d..fff082acb87e27313d80c272aa44bdeb63a4bac0 100644 (file)
--- a/CFSet.c
+++ b/CFSet.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSet.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -47,7 +47,6 @@
 const CFSetKeyCallBacks kCFTypeSetKeyCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFSetKeyCallBacks kCFCopyStringSetKeyCallBacks = {0, __CFStringCollectionCopy, __CFTypeCollectionRelease, CFCopyDescription, CFEqual, CFHash};
 const CFSetValueCallBacks kCFTypeSetValueCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
-__private_extern__ const CFSetValueCallBacks kCFTypeSetValueCompactableCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
 static const CFSetKeyCallBacks __kCFNullSetKeyCallBacks = {0, NULL, NULL, NULL, NULL, NULL};
 static const CFSetValueCallBacks __kCFNullSetValueCallBacks = {0, NULL, NULL, NULL, NULL};
 
@@ -133,328 +132,131 @@ CFTypeID CFSetGetTypeID(void) {
     return __kCFSetTypeID;
 }
 
-#define GCRETAIN(A, B) kCFTypeSetCallBacks.retain(A, B)
-#define GCRELEASE(A, B) kCFTypeSetCallBacks.release(A, B)
-
-static uintptr_t __CFSetStandardRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0100) return stack_value;
-    return (CFBasicHashHasStrongValues(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_value) : (uintptr_t)CFRetain((CFTypeRef)stack_value);
-}
-
-static uintptr_t __CFSetStandardRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0001) return stack_key;
-    return (CFBasicHashHasStrongKeys(ht)) ? (uintptr_t)GCRETAIN(kCFAllocatorSystemDefault, (CFTypeRef)stack_key) : (uintptr_t)CFRetain((CFTypeRef)stack_key);
-}
-
-static void __CFSetStandardReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0200) return;
-    if (CFBasicHashHasStrongValues(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_value); else CFRelease((CFTypeRef)stack_value);
-}
-
-static void __CFSetStandardReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0002) return;
-    if (CFBasicHashHasStrongKeys(ht)) GCRELEASE(kCFAllocatorSystemDefault, (CFTypeRef)stack_key); else CFRelease((CFTypeRef)stack_key);
-}
-
-static Boolean __CFSetStandardEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0400) return coll_value1 == stack_value2;
-    return CFEqual((CFTypeRef)coll_value1, (CFTypeRef)stack_value2);
-}
-
-static Boolean __CFSetStandardEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0004) return coll_key1 == stack_key2;
-    return CFEqual((CFTypeRef)coll_key1, (CFTypeRef)stack_key2);
-}
-
-static uintptr_t __CFSetStandardHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0008) return stack_key;
-    return (uintptr_t)CFHash((CFTypeRef)stack_key);
-}
-
-static uintptr_t __CFSetStandardGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFSetStandardCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0800) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value);
-    return CFCopyDescription((CFTypeRef)stack_value);
-}
-
-static CFStringRef __CFSetStandardCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (CFBasicHashGetSpecialBits(ht) & 0x0010) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key);
-    return CFCopyDescription((CFTypeRef)stack_key);
-}
-
-static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb);
-
-static const CFBasicHashCallbacks CFSetStandardCallbacks = {
-    __CFSetStandardCopyCallbacks,
-    __CFSetStandardFreeCallbacks,
-    __CFSetStandardRetainValue,
-    __CFSetStandardRetainKey,
-    __CFSetStandardReleaseValue,
-    __CFSetStandardReleaseKey,
-    __CFSetStandardEquateValues,
-    __CFSetStandardEquateKeys,
-    __CFSetStandardHashKey,
-    __CFSetStandardGetIndirectKey,
-    __CFSetStandardCopyValueDescription,
-    __CFSetStandardCopyKeyDescription
-};
-
-static CFBasicHashCallbacks *__CFSetStandardCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    return (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
-}
-
-static void __CFSetStandardFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-}
-    
-
-static CFBasicHashCallbacks *__CFSetCopyCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    CFBasicHashCallbacks *newcb = NULL;
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-    } else {
-        newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
-    }
-    if (!newcb) return NULL;
-    memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
-    return newcb;
-}
-
-static void __CFSetFreeCallbacks(CFConstBasicHashRef ht, CFAllocatorRef allocator, CFBasicHashCallbacks *cb) {
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-    } else {
-       CFAllocatorDeallocate(allocator, cb);
-    }
-}
-    
-static uintptr_t __CFSetRetainValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[0];
-    if (NULL == value_retain) return stack_value;
-    return (uintptr_t)INVOKE_CALLBACK2(value_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_value);
-}
-
-static uintptr_t __CFSetRetainKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = (const_any_pointer_t (*)(CFAllocatorRef, const_any_pointer_t))cb->context[1];
-    if (NULL == key_retain) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK2(key_retain, CFGetAllocator(ht), (const_any_pointer_t)stack_key);
-}
-
-static void __CFSetReleaseValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[2];
-    if (NULL != value_release) INVOKE_CALLBACK2(value_release, CFGetAllocator(ht), (const_any_pointer_t) stack_value);
-}
-
-static void __CFSetReleaseKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = (void (*)(CFAllocatorRef, const_any_pointer_t))cb->context[3];
-    if (NULL != key_release) INVOKE_CALLBACK2(key_release, CFGetAllocator(ht), (const_any_pointer_t) stack_key);
-}
-
-static Boolean __CFSetEquateValues(CFConstBasicHashRef ht, uintptr_t coll_value1, uintptr_t stack_value2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[4];
-    if (NULL == value_equal) return (coll_value1 == stack_value2);
-    return INVOKE_CALLBACK2(value_equal, (const_any_pointer_t) coll_value1, (const_any_pointer_t) stack_value2) ? 1 : 0;
-}
-
-static Boolean __CFSetEquateKeys(CFConstBasicHashRef ht, uintptr_t coll_key1, uintptr_t stack_key2) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = (Boolean (*)(const_any_pointer_t, const_any_pointer_t))cb->context[5];
-    if (NULL == key_equal) return (coll_key1 == stack_key2);
-    return INVOKE_CALLBACK2(key_equal, (const_any_pointer_t) coll_key1, (const_any_pointer_t) stack_key2) ? 1 : 0;
-}
-
-static uintptr_t __CFSetHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFHashCode (*hash)(const_any_pointer_t) = (CFHashCode (*)(const_any_pointer_t))cb->context[6];
-    if (NULL == hash) return stack_key;
-    return (uintptr_t)INVOKE_CALLBACK1(hash, (const_any_pointer_t) stack_key);
-}
-
-static uintptr_t __CFSetGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_value) {
-    return 0;
-}
-
-static CFStringRef __CFSetCopyValueDescription(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*value_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[8];
-    if (NULL == value_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_value);
-    return (CFStringRef)INVOKE_CALLBACK1(value_describe, (const_any_pointer_t) stack_value);
-}
-
-static CFStringRef __CFSetCopyKeyDescription(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    const CFBasicHashCallbacks *cb = CFBasicHashGetCallbacks(ht);
-    CFStringRef (*key_describe)(const_any_pointer_t) = (CFStringRef (*)(const_any_pointer_t))cb->context[9];
-    if (NULL == key_describe) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (const_any_pointer_t) stack_key);
-    return (CFStringRef)INVOKE_CALLBACK1(key_describe, (const_any_pointer_t) stack_key);
-}
 
 static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHashKeyCallBacks *keyCallBacks, const CFHashValueCallBacks *valueCallBacks, Boolean useValueCB) {
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
 
-    CFBasicHashCallbacks *cb = NULL;
-    Boolean std_cb = false;
-    uint16_t specialBits = 0;
-    const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
-    void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
-
-    if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
-        Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
-        Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
-        Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
-        Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
-        Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
-
-        Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
-        Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
-        Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
-        Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
-
-        Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
-        Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
-        Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
-        Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
-        Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
-
-        Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
-        Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
-        Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
-        Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
-
-        if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
-            cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
-            if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
-                std_cb = true;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) { // all this crap is just for figuring out two flags for GC in the way done historically; it probably simplifies down to three lines, but we let the compiler worry about that
+        Boolean set_cb = false;
+        Boolean std_cb = false;
+        const_any_pointer_t (*key_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*key_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        const_any_pointer_t (*value_retain)(CFAllocatorRef, const_any_pointer_t) = NULL;
+        void (*value_release)(CFAllocatorRef, const_any_pointer_t) = NULL;
+
+       if ((NULL == keyCallBacks || 0 == keyCallBacks->version) && (!useValueCB || NULL == valueCallBacks || 0 == valueCallBacks->version)) {
+           Boolean keyRetainNull = NULL == keyCallBacks || NULL == keyCallBacks->retain;
+           Boolean keyReleaseNull = NULL == keyCallBacks || NULL == keyCallBacks->release;
+           Boolean keyEquateNull = NULL == keyCallBacks || NULL == keyCallBacks->equal;
+           Boolean keyHashNull = NULL == keyCallBacks || NULL == keyCallBacks->hash;
+           Boolean keyDescribeNull = NULL == keyCallBacks || NULL == keyCallBacks->copyDescription;
+
+           Boolean valueRetainNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->retain)) || (!useValueCB && keyRetainNull);
+           Boolean valueReleaseNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->release)) || (!useValueCB && keyReleaseNull);
+           Boolean valueEquateNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->equal)) || (!useValueCB && keyEquateNull);
+           Boolean valueDescribeNull = (useValueCB && (NULL == valueCallBacks || NULL == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeNull);
+
+           Boolean keyRetainStd = keyRetainNull || __CFTypeCollectionRetain == keyCallBacks->retain;
+           Boolean keyReleaseStd = keyReleaseNull || __CFTypeCollectionRelease == keyCallBacks->release;
+           Boolean keyEquateStd = keyEquateNull || CFEqual == keyCallBacks->equal;
+           Boolean keyHashStd = keyHashNull || CFHash == keyCallBacks->hash;
+           Boolean keyDescribeStd = keyDescribeNull || CFCopyDescription == keyCallBacks->copyDescription;
+
+           Boolean valueRetainStd = (useValueCB && (valueRetainNull || __CFTypeCollectionRetain == valueCallBacks->retain)) || (!useValueCB && keyRetainStd);
+           Boolean valueReleaseStd = (useValueCB && (valueReleaseNull || __CFTypeCollectionRelease == valueCallBacks->release)) || (!useValueCB && keyReleaseStd);
+           Boolean valueEquateStd = (useValueCB && (valueEquateNull || CFEqual == valueCallBacks->equal)) || (!useValueCB && keyEquateStd);
+           Boolean valueDescribeStd = (useValueCB && (valueDescribeNull || CFCopyDescription == valueCallBacks->copyDescription)) || (!useValueCB && keyDescribeStd);
+
+           if (keyRetainStd && keyReleaseStd && keyEquateStd && keyHashStd && keyDescribeStd && valueRetainStd && valueReleaseStd && valueEquateStd && valueDescribeStd) {
+               set_cb = true;
+               if (!(keyRetainNull || keyReleaseNull || keyEquateNull || keyHashNull || keyDescribeNull || valueRetainNull || valueReleaseNull || valueEquateNull || valueDescribeNull)) {
+                   std_cb = true;
+               } else {
+                   // just set these to tickle the GC Strong logic below in a way that mimics past practice
+                   key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+                   key_release = keyCallBacks ? keyCallBacks->release : NULL;
+                   if (useValueCB) {
+                       value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                       value_release = valueCallBacks ? valueCallBacks->release : NULL;
+                   } else {
+                       value_retain = key_retain;
+                       value_release = key_release;
+                   }
+               }
+           }
+       }
+
+        if (!set_cb) {
+            key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
+            key_release = keyCallBacks ? keyCallBacks->release : NULL;
+            if (useValueCB) {
+                value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
+                value_release = valueCallBacks ? valueCallBacks->release : NULL;
             } else {
-                // just set these to tickle the GC Strong logic below in a way that mimics past practice
-                key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-                key_release = keyCallBacks ? keyCallBacks->release : NULL;
-                if (useValueCB) {
-                    value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-                    value_release = valueCallBacks ? valueCallBacks->release : NULL;
-                } else {
-                    value_retain = key_retain;
-                    value_release = key_release;
-                }
+                value_retain = key_retain;
+                value_release = key_release;
             }
-            if (keyRetainNull) specialBits |= 0x0001;
-            if (keyReleaseNull) specialBits |= 0x0002;
-            if (keyEquateNull) specialBits |= 0x0004;
-            if (keyHashNull) specialBits |= 0x0008;
-            if (keyDescribeNull) specialBits |= 0x0010;
-            if (valueRetainNull) specialBits |= 0x0100;
-            if (valueReleaseNull) specialBits |= 0x0200;
-            if (valueEquateNull) specialBits |= 0x0400;
-            if (valueDescribeNull) specialBits |= 0x0800;
-        }
-    }
-
-    if (!cb) {
-        Boolean (*key_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        Boolean (*value_equal)(const_any_pointer_t, const_any_pointer_t) = NULL;
-        CFStringRef (*key_describe)(const_any_pointer_t) = NULL;
-        CFStringRef (*value_describe)(const_any_pointer_t) = NULL;
-        CFHashCode (*hash_key)(const_any_pointer_t) = NULL;
-        key_retain = keyCallBacks ? keyCallBacks->retain : NULL;
-        key_release = keyCallBacks ? keyCallBacks->release : NULL;
-        key_equal = keyCallBacks ? keyCallBacks->equal : NULL;
-        key_describe = keyCallBacks ? keyCallBacks->copyDescription : NULL;
-        if (useValueCB) {
-            value_retain = valueCallBacks ? valueCallBacks->retain : NULL;
-            value_release = valueCallBacks ? valueCallBacks->release : NULL;
-            value_equal = valueCallBacks ? valueCallBacks->equal : NULL;
-            value_describe = valueCallBacks ? valueCallBacks->copyDescription : NULL;
-        } else {
-            value_retain = key_retain;
-            value_release = key_release;
-            value_equal = key_equal;
-            value_describe = key_describe;
-        }
-        hash_key = keyCallBacks ? keyCallBacks->hash : NULL;
-
-        CFBasicHashCallbacks *newcb = NULL;
-        if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            newcb = (CFBasicHashCallbacks *)auto_zone_allocate_object(objc_collectableZone(), sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), AUTO_MEMORY_UNSCANNED, false, false);
-        } else {
-            newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) return NULL;
-        newcb->copyCallbacks = __CFSetCopyCallbacks;
-        newcb->freeCallbacks = __CFSetFreeCallbacks;
-        newcb->retainValue = __CFSetRetainValue;
-        newcb->retainKey = __CFSetRetainKey;
-        newcb->releaseValue = __CFSetReleaseValue;
-        newcb->releaseKey = __CFSetReleaseKey;
-        newcb->equateValues = __CFSetEquateValues;
-        newcb->equateKeys = __CFSetEquateKeys;
-        newcb->hashKey = __CFSetHashKey;
-        newcb->getIndirectKey = __CFSetGetIndirectKey;
-        newcb->copyValueDescription = __CFSetCopyValueDescription;
-        newcb->copyKeyDescription = __CFSetCopyKeyDescription;
-        newcb->context[0] = (uintptr_t)value_retain;
-        newcb->context[1] = (uintptr_t)key_retain;
-        newcb->context[2] = (uintptr_t)value_release;
-        newcb->context[3] = (uintptr_t)key_release;
-        newcb->context[4] = (uintptr_t)value_equal;
-        newcb->context[5] = (uintptr_t)key_equal;
-        newcb->context[6] = (uintptr_t)hash_key;
-        newcb->context[8] = (uintptr_t)value_describe;
-        newcb->context[9] = (uintptr_t)key_describe;
-        cb = newcb;
-    }
 
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
         if (std_cb || value_retain != NULL || value_release != NULL) {
             flags |= kCFBasicHashStrongValues;
         }
         if (std_cb || key_retain != NULL || key_release != NULL) {
             flags |= kCFBasicHashStrongKeys;
         }
-#if CFDictionary
-        if (valueCallBacks == &kCFTypeDictionaryValueCompactableCallBacks) {
-            // Foundation allocated collections will have compactable values
-            flags |= kCFBasicHashCompactableValues;
-        }
-#endif
     }
 
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
-    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = keyCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))keyCallBacks->retain : NULL;
+    callbacks.releaseKey = keyCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))keyCallBacks->release : NULL;
+    callbacks.equateKeys = keyCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))keyCallBacks->equal : NULL;
+    callbacks.hashKey = keyCallBacks ? (CFHashCode (*)(uintptr_t))keyCallBacks->hash : NULL;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = keyCallBacks ? (CFStringRef (*)(uintptr_t))keyCallBacks->copyDescription : NULL;
+    callbacks.retainValue = useValueCB ? (valueCallBacks ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))valueCallBacks->retain : NULL) : (callbacks.retainKey);
+    callbacks.releaseValue = useValueCB ? (valueCallBacks ? (void (*)(CFAllocatorRef, uintptr_t))valueCallBacks->release : NULL) : (callbacks.releaseKey);
+    callbacks.equateValues = useValueCB ? (valueCallBacks ? (Boolean (*)(uintptr_t, uintptr_t))valueCallBacks->equal : NULL) : (callbacks.equateKeys);
+    callbacks.copyValueDescription = useValueCB ? (valueCallBacks ? (CFStringRef (*)(uintptr_t))valueCallBacks->copyDescription : NULL) : (callbacks.copyKeyDescription);
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
     return ht;
 }
 
 #if CFDictionary
-__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, const_any_pointer_t *vlist, CFIndex numValues) {
 #endif
 #if CFSet || CFBag
-__private_extern__ CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
+CF_PRIVATE CFHashRef __CFSetCreateTransfer(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIndex numValues) {
     const_any_pointer_t *vlist = klist;
 #endif
     CFTypeID typeID = CFSetGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFOptionFlags flags = kCFBasicHashLinearHashing; // kCFBasicHashExponentialHashing
     flags |= (CFDictionary ? kCFBasicHashHasKeys : 0) | (CFBag ? kCFBasicHashHasCounts : 0);
-    CFBasicHashCallbacks *cb = (CFBasicHashCallbacks *)&CFSetStandardCallbacks;
-    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, 0x0303);
+
+    CFBasicHashCallbacks callbacks;
+    callbacks.retainKey = (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeSetKeyCallBacks.retain;
+    callbacks.releaseKey = (void (*)(CFAllocatorRef, uintptr_t))kCFTypeSetKeyCallBacks.release;
+    callbacks.equateKeys = (Boolean (*)(uintptr_t, uintptr_t))kCFTypeSetKeyCallBacks.equal;
+    callbacks.hashKey = (CFHashCode (*)(uintptr_t))kCFTypeSetKeyCallBacks.hash;
+    callbacks.getIndirectKey = NULL;
+    callbacks.copyKeyDescription = (CFStringRef (*)(uintptr_t))kCFTypeSetKeyCallBacks.copyDescription;
+    callbacks.retainValue = CFDictionary ? (uintptr_t (*)(CFAllocatorRef, uintptr_t))kCFTypeSetValueCallBacks.retain : callbacks.retainKey;
+    callbacks.releaseValue = CFDictionary ? (void (*)(CFAllocatorRef, uintptr_t))kCFTypeSetValueCallBacks.release : callbacks.releaseKey;
+    callbacks.equateValues = CFDictionary ? (Boolean (*)(uintptr_t, uintptr_t))kCFTypeSetValueCallBacks.equal : callbacks.equateKeys;
+    callbacks.copyValueDescription = CFDictionary ? (CFStringRef (*)(uintptr_t))kCFTypeSetValueCallBacks.copyDescription : callbacks.copyKeyDescription;
+
+    CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, &callbacks);
+    CFBasicHashSuppressRC(ht);
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
-    CFBasicHashSetSpecialBits(ht, 0x0000);
+    CFBasicHashUnsuppressRC(ht);
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
     return (CFHashRef)ht;
 }
@@ -476,8 +278,7 @@ CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
     }
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
     return (CFHashRef)ht;
 }
@@ -493,8 +294,7 @@ CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity,
     CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity);
     CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
     return (CFMutableHashRef)ht;
 }
@@ -528,8 +328,7 @@ CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     }
     if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (immutable)");
     return (CFHashRef)ht;
 }
@@ -563,8 +362,7 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
     if (!ht) return NULL;
-    *(uintptr_t *)ht = __CFISAForTypeID(typeID);
-    _CFRuntimeSetInstanceTypeID(ht, typeID);
+    _CFRuntimeSetInstanceTypeIDAndIsa(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
     return (CFMutableHashRef)ht;
 }
@@ -781,7 +579,7 @@ void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
     if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key);
-    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, replaceObject:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, replaceObject:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -799,7 +597,7 @@ void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_point
 void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, setObject:(id)value forKey:(id)key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key);
     if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, setObject:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
diff --git a/CFSet.h b/CFSet.h
index 0ee1ce86c8ebac383227355506b681bf3b89379b..538d9dcce4f72028f97c1c716964fcdadced4159 100644 (file)
--- a/CFSet.h
+++ b/CFSet.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSet.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 /*!
         @header CFSet
index f07069a2411eb8efac2b4cedf19f0c7669ef9d35..3bce4453ec0ac31053fc536d81432bc719209e61 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocket.c
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -983,7 +983,7 @@ typedef int32_t fd_mask;
 typedef int socklen_t;
 
 #define gettimeofday _NS_gettimeofday
-__private_extern__ int _NS_gettimeofday(struct timeval *tv, struct timezone *tz);
+CF_PRIVATE int _NS_gettimeofday(struct timeval *tv, struct timezone *tz);
 
 // although this is only used for debug info, we define it for compatibility
 #define        timersub(tvp, uvp, vvp) \
@@ -1330,7 +1330,7 @@ CF_EXPORT void __CFSocketInitializeWinSock(void) {
     __CFSpinUnlock(&__CFActiveSocketsLock);
 }
 
-__private_extern__ void __CFSocketCleanup(void) {
+CF_PRIVATE void __CFSocketCleanup(void) {
     if (INVALID_SOCKET != __CFWakeupSocketPair[0]) {
         closesocket(__CFWakeupSocketPair[0]);
         __CFWakeupSocketPair[0] = INVALID_SOCKET;
@@ -1583,8 +1583,8 @@ static void __CFSocketHandleRead(CFSocketRef s, Boolean causedByTimeout)
 #if defined(LOG_CFSOCKET)
                        fprintf(stdout, "TIMEOUT RECEIVED - WILL SIGNAL IMMEDIATELY TO FLUSH (%ld buffered)\n", s->_bytesToBufferPos);
 #endif
-            /* we've got a timeout, but no bytes read.  Ignore the timeout. */
-            if (s->_bytesToBufferPos == 0) {
+                    /* we've got a timeout, but no bytes read, and we don't have any bytes to send.  Ignore the timeout. */
+                    if (s->_bytesToBufferPos == 0 && s->_leftoverBytes == NULL) {
 #if defined(LOG_CFSOCKET)
                 fprintf(stdout, "TIMEOUT - but no bytes, restoring to active set\n");
                 fflush(stdout);
@@ -1913,6 +1913,81 @@ static void __CFSocketWriteSocketList(CFArrayRef sockets, CFDataRef fdSet, Boole
 }
 #endif
 
+static void
+clearInvalidFileDescriptors(CFMutableDataRef d)
+{
+    if (d) {
+        SInt32 count = __CFSocketFdGetSize(d);
+        fd_set* s = (fd_set*) CFDataGetMutableBytePtr(d);
+        for (SInt32 idx = 0;  idx < count;  idx++) {
+            if (FD_ISSET(idx, s))
+                if (! __CFNativeSocketIsValid(idx)) {
+                    FD_CLR(idx, s);
+                }
+        }
+    }
+}
+
+static void
+manageSelectError()
+{
+    SInt32 selectError = __CFSocketLastError();
+#if defined(LOG_CFSOCKET)
+    fprintf(stdout, "socket manager received error %ld from select\n", (long)selectError);
+#endif
+    if (EBADF == selectError) {
+        CFMutableArrayRef invalidSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+
+        __CFSpinLock(&__CFActiveSocketsLock);
+        CFIndex cnt = CFArrayGetCount(__CFWriteSockets);
+        CFIndex idx;
+        for (idx = 0; idx < cnt; idx++) {
+            CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFWriteSockets, idx);
+            if (!__CFNativeSocketIsValid(s->_socket)) {
+#if defined(LOG_CFSOCKET)
+                fprintf(stdout, "socket manager found write socket %d invalid\n", s->_socket);
+#endif
+                CFArrayAppendValue(invalidSockets, s);
+            }
+        }
+        cnt = CFArrayGetCount(__CFReadSockets);
+        for (idx = 0; idx < cnt; idx++) {
+            CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
+            if (!__CFNativeSocketIsValid(s->_socket)) {
+#if defined(LOG_CFSOCKET)
+                fprintf(stdout, "socket manager found read socket %d invalid\n", s->_socket);
+#endif
+                CFArrayAppendValue(invalidSockets, s);
+            }
+        }
+
+
+        cnt = CFArrayGetCount(invalidSockets);
+
+        /* Note that we're doing this only when we got EBADF but otherwise
+         * don't have an explicit bad descriptor.  Note that the lock is held now.
+         * Finally, note that cnt == 0 doesn't necessarily mean
+         * that this loop will do anything, since fd's may have been invalidated
+         * while we were in select.
+         */
+        if (cnt == 0) {
+#if defined(LOG_CFSOCKET)
+            fprintf(stdout, "socket manager received EBADF(1): No sockets were marked as invalid, cleaning out fdsets\n");
+#endif
+
+            clearInvalidFileDescriptors(__CFReadSocketsFds);
+            clearInvalidFileDescriptors(__CFWriteSocketsFds);
+        }
+
+        __CFSpinUnlock(&__CFActiveSocketsLock);
+
+        for (idx = 0; idx < cnt; idx++) {
+            CFSocketInvalidate(((CFSocketRef)CFArrayGetValueAtIndex(invalidSockets, idx)));
+        }
+        CFRelease(invalidSockets);
+    }
+}
+
 #ifdef __GNUC__
 __attribute__ ((noreturn))     // mostly interesting for shutting up a warning
 #endif /* __GNUC__ */
@@ -2047,42 +2122,8 @@ static void __CFSocketManager(void * arg)
                        /* and below, we dispatch through the normal read dispatch mechanism */
                } 
                
-               if (0 > nrfds) {
-            SInt32 selectError = __CFSocketLastError();
-#if defined(LOG_CFSOCKET)
-            fprintf(stdout, "socket manager received error %ld from select\n", (long)selectError);
-#endif
-            if (EBADF == selectError) {
-                CFMutableArrayRef invalidSockets = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-                __CFSpinLock(&__CFActiveSocketsLock);
-                cnt = CFArrayGetCount(__CFWriteSockets);
-                for (idx = 0; idx < cnt; idx++) {
-                    CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFWriteSockets, idx);
-                    if (!__CFNativeSocketIsValid(s->_socket)) {
-#if defined(LOG_CFSOCKET)
-                        fprintf(stdout, "socket manager found write socket %d invalid\n", s->_socket);
-#endif
-                        CFArrayAppendValue(invalidSockets, s);
-                    }
-                }
-                cnt = CFArrayGetCount(__CFReadSockets);
-                for (idx = 0; idx < cnt; idx++) {
-                    CFSocketRef s = (CFSocketRef)CFArrayGetValueAtIndex(__CFReadSockets, idx);
-                    if (!__CFNativeSocketIsValid(s->_socket)) {
-#if defined(LOG_CFSOCKET)
-                        fprintf(stdout, "socket manager found read socket %d invalid\n", s->_socket);
-#endif
-                        CFArrayAppendValue(invalidSockets, s);
-                    }
-                }
-                __CFSpinUnlock(&__CFActiveSocketsLock);
-        
-                cnt = CFArrayGetCount(invalidSockets);
-                for (idx = 0; idx < cnt; idx++) {
-                    CFSocketInvalidate(((CFSocketRef)CFArrayGetValueAtIndex(invalidSockets, idx)));
-                }
-                CFRelease(invalidSockets);
-            }
+        if (0 > nrfds) {
+            manageSelectError();
             continue;
         }
         if (FD_ISSET(__CFWakeupSocketPair[1], readfds)) {
@@ -2171,7 +2212,7 @@ static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) {
     // don't bother trying to figure out callout names
     const char *name = "<unknown>";
 #endif
-    CFStringAppendFormat(result, NULL, CFSTR("<CFSocket %p [%p]>{valid = %s, type = %d, socket = %d, socket set count = %ld,\n    callback types = 0x%x, callout = %s (%p), source = %p,\n    run loops = %@,\n    context = "), cf, CFGetAllocator(s), (__CFSocketIsValid(s) ? "Yes" : "No"), s->_socketType, s->_socket, s->_socketSetCount, __CFSocketCallBackTypes(s), name, addr, s->_source0, s->_runLoops);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFSocket %p [%p]>{valid = %s, type = %d, socket = %d, socket set count = %ld,\n    callback types = 0x%x, callout = %s (%p), source = %p,\n    run loops = %@,\n    context = "), cf, CFGetAllocator(s), (__CFSocketIsValid(s) ? "Yes" : "No"), (int)(s->_socketType), s->_socket, (long)s->_socketSetCount, __CFSocketCallBackTypes(s), name, addr, s->_source0, s->_runLoops);
     contextInfo = s->_context.info;
     contextCopyDescription = s->_context.copyDescription;
     __CFSocketUnlock(s);
@@ -3018,7 +3059,7 @@ CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeI
 #endif
         }
 #if defined(LOG_CFSOCKET)
-        fprintf(stdout, "connection attempt returns %d error %d on socket %d (flags 0x%x blocking %d)\n", result, connect_err, sock, flags, wasBlocking);
+        fprintf(stdout, "connection attempt returns %d error %d on socket %d (flags 0x%x blocking %d)\n", (int) result, (int) connect_err, sock, (int) flags, wasBlocking);
 #endif
         if (EINPROGRESS == connect_err && timeout >= 0.0) {
             /* select on socket */
@@ -3041,7 +3082,7 @@ CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeI
             }
             CFRelease(fds);
 #if defined(LOG_CFSOCKET)
-            fprintf(stdout, "timed connection attempt %s on socket %d, result %d, select returns %d error %d\n", (result == 0) ? "succeeds" : "fails", sock, result, nrfds, select_err);
+            fprintf(stdout, "timed connection attempt %s on socket %d, result %d, select returns %d error %d\n", (result == 0) ? "succeeds" : "fails", sock, (int) result, (int) nrfds, (int) select_err);
 #endif
         }
         if (wasBlocking && (timeout > 0.0 || timeout < 0.0)) ioctlsocket(sock, FIONBIO, (u_long *)&no);
index 80ddad92232adb088e790fe50cddc471e8c2c5d8..b8d0803defe14164b7a18282e04c0444bec29b45 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocket.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSOCKET__)
index bb9ca57adcc8f430de5ab8317c129aa0a07b0db1..662858e2652d1e064ce0277382572c85e61a492e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocketStream.c
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
        Responsibility: Jeremy Wyld
 */
 //     Original Author: Becky Willrich
@@ -203,7 +203,7 @@ CF_EXPORT void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, c
     createPair(alloc, NULL, 0, 0, sig, readStream, writeStream);
 }
 
-__private_extern__ CFStreamError _CFStreamErrorFromError(CFErrorRef error) {
+CF_PRIVATE CFStreamError _CFStreamErrorFromError(CFErrorRef error) {
     CFStreamError result;
     Boolean canUpCall;
     
@@ -230,7 +230,7 @@ __private_extern__ CFStreamError _CFStreamErrorFromError(CFErrorRef error) {
     return result;
 }
 
-__private_extern__ CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *streamError) {
+CF_PRIVATE CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *streamError) {
     CFErrorRef result;
     Boolean canUpCall;
     
index 40cdc9425c13cf13cbb72b77ac314fac146975ce..5e5e74f3451125891861f842913ea26e618ca213 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSortFunctions.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
index 22652dd4553593e5464aa2cd1e78e74611d662ac..7f6ceaa6cf6825baf97689ae76be5f0f57b0fcd3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStorage.c
- Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+ Copyright (c) 1999-2013, Apple Inc. All rights reserved.
  Responsibility: Ali Ozer
  */
 
@@ -976,7 +976,7 @@ static CFStringRef __CFStorageCopyDescription(CFTypeRef cf) {
     CFMutableStringRef result;
     CFAllocatorRef allocator = CFGetAllocator(storage);
     result = CFStringCreateMutable(allocator, 0);
-    CFStringAppendFormat(result, NULL, CFSTR("<CFStorage %p [%p]>[count = %u, capacity = %u]\n"), storage, allocator, __CFStorageGetCount(storage), __CFStorageGetCapacity(storage));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFStorage %p [%p]>[count = %lu, capacity = %lu]\n"), storage, allocator, (unsigned long)__CFStorageGetCount(storage), (unsigned long)__CFStorageGetCapacity(storage));
     __CFStorageDescribeNode(&storage->rootNode, result, 0);
     return result;
 }
@@ -1105,7 +1105,7 @@ static const CFRuntimeClass __CFStorageClass = {
     __CFStorageCopyDescription
 };
 
-__private_extern__ void __CFStorageInitialize(void) {
+CF_PRIVATE void __CFStorageInitialize(void) {
     __kCFStorageTypeID = _CFRuntimeRegisterClass(&__CFStorageClass);
 }
 
@@ -1471,7 +1471,7 @@ static void __CFStorageNodeSetUnscanned(CFStorageNode *node, auto_zone_t *zone)
     }
 }
 
-__private_extern__ void _CFStorageSetWeak(CFStorageRef storage) {
+CF_PRIVATE void _CFStorageSetWeak(CFStorageRef storage) {
     storage->nodeHint = 0;
     __CFStorageNodeSetUnscanned(&storage->rootNode, (auto_zone_t *)objc_collectableZone());
 }
index 7431f0b6d357ad17a4218817a7bb8c8d3868e609..eb455baccac0cbce7da2452e6182f55d28e7eb5b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStorage.h
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
 */
 /*!
         @header CFStorage
index b4c52fd9cb19f0212a6825133095da5aaf3a106d..60f3242762b1c64ec98a13b280c646ecd2663b0e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStream.c
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
 #include <assert.h>
 #endif
 
-
-struct CFStreamAux {
-       CFSpinLock_t streamLock;
+struct _CFStream {
+    CFRuntimeBase _cfBase;
+    CFOptionFlags flags;
+    CFErrorRef error; // if callBacks->version < 2, this is actually a pointer to a CFStreamError
+    struct _CFStreamClient *client;
+    /* NOTE: CFNetwork is still using _CFStreamGetInfoPointer, and so this slot needs to stay in this position (as the fifth field in the structure) */
+    /* NOTE: This can be taken out once CFNetwork rebuilds */
+    /* NOTE: <rdar://problem/13678879> Remove comment once CFNetwork has been rebuilt */
+    void *info;
+    const struct _CFStreamCallBacks *callBacks;  // This will not exist (will not be allocated) if the callbacks are from our known, "blessed" set.
+
+    CFSpinLock_t streamLock;
     CFArrayRef previousRunloopsAndModes;
+    dispatch_queue_t queue;
 };
 
+
 enum {
        MIN_STATUS_CODE_BIT     = 0,
         // ..status bits...
@@ -78,7 +89,7 @@ static CFTypeID __kCFWriteStreamTypeID = _kCFRuntimeNotATypeID;
 // Just reads the bits, for those cases where we don't want to go through any callback checking
 #define __CFStreamGetStatus(x) __CFBitfieldGetValue((x)->flags, MAX_STATUS_CODE_BIT, MIN_STATUS_CODE_BIT)
 
-__private_extern__ CFStreamStatus _CFStreamGetStatus(struct _CFStream *stream);
+CF_PRIVATE CFStreamStatus _CFStreamGetStatus(struct _CFStream *stream);
 static Boolean _CFStreamRemoveRunLoopAndModeFromArray(CFMutableArrayRef runLoopsAndModes, CFRunLoopRef rl, CFStringRef mode);
 static void _wakeUpRunLoop(struct _CFStream *stream);
 
@@ -89,50 +100,30 @@ CF_INLINE void checkRLMArray(CFArrayRef arr)
 #endif
 }
 
-CF_INLINE void* _CFStreamCreateReserved(CFAllocatorRef alloc) {
-       struct CFStreamAux* aux = (struct CFStreamAux*) CFAllocatorAllocate(alloc, sizeof(struct CFStreamAux), 0);
-       if (aux) {
-               aux->streamLock = CFSpinLockInit;
-        aux->previousRunloopsAndModes = NULL;
-       }
-       return aux;
-}
-
-CF_INLINE void _CFStreamDestroyReserved(CFAllocatorRef alloc, void* aux) {
-    struct CFStreamAux* paux = (struct CFStreamAux*) aux;
-    if (paux->previousRunloopsAndModes)
-        CFRelease(paux->previousRunloopsAndModes);
-       CFAllocatorDeallocate(alloc, aux);
-}
-
-CF_INLINE struct CFStreamAux* _CFStreamGetAuxRecord(struct _CFStream* stream) {
-       return (struct CFStreamAux*) stream->_reserved1;
-}
-
 CF_INLINE void _CFStreamLock(struct _CFStream* stream) {
-       __CFSpinLock(&_CFStreamGetAuxRecord(stream)->streamLock);
+       __CFSpinLock(&stream->streamLock);
 }
 
 CF_INLINE void _CFStreamUnlock(struct _CFStream* stream) {
-       __CFSpinUnlock(&_CFStreamGetAuxRecord(stream)->streamLock);
+       __CFSpinUnlock(&stream->streamLock);
 }
 
 CF_INLINE CFRunLoopSourceRef _CFStreamCopySource(struct _CFStream* stream) {
-       CFRunLoopSourceRef source = NULL;
-       
-       if (stream) {
-               _CFStreamLock(stream);
-               
-               if (stream->client)
-                       source = stream->client->rlSource;
+    CFRunLoopSourceRef source = NULL;
 
-               if (source)
-                       CFRetain(source);
-               
-               _CFStreamUnlock(stream);
-       }
-       
-       return source;
+    if (stream) {
+        _CFStreamLock(stream);
+
+        if (stream->client)
+            source = stream->client->rlSource;
+
+        if (source)
+            CFRetain(source);
+        
+        _CFStreamUnlock(stream);
+    }
+    
+    return source;
 }
 
 CF_INLINE void _CFStreamSetSource(struct _CFStream* stream, CFRunLoopSourceRef source, Boolean invalidateOldSource) {
@@ -266,23 +257,25 @@ static void _CFStreamDetachSource(struct _CFStream* stream) {
     }
 }
 
-__private_extern__ void _CFStreamClose(struct _CFStream *stream) {
+CF_PRIVATE void _CFStreamClose(struct _CFStream *stream) {
     CFStreamStatus status = _CFStreamGetStatus(stream);
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     if (status == kCFStreamStatusNotOpen || status == kCFStreamStatusClosed || (status == kCFStreamStatusError && __CFBitIsSet(stream->flags, HAVE_CLOSED))) {
         // Stream is not open from the client's perspective; do not callout and do not update our status to "closed"
         return;
     }
-    __CFBitSet(stream->flags, HAVE_CLOSED);
-    __CFBitSet(stream->flags, CALLING_CLIENT);
-    if (cb->close) {
-        cb->close(stream, _CFStreamGetInfoPointer(stream));
-    }
-    if (stream->client) {
-        _CFStreamDetachSource(stream);
+    if (! __CFBitIsSet(stream->flags, HAVE_CLOSED)) {
+        __CFBitSet(stream->flags, HAVE_CLOSED);
+        __CFBitSet(stream->flags, CALLING_CLIENT);
+        if (cb->close) {
+            cb->close(stream, _CFStreamGetInfoPointer(stream));
+        }
+        if (stream->client) {
+            _CFStreamDetachSource(stream);
+        }
+        _CFStreamSetStatusCode(stream, kCFStreamStatusClosed);
+        __CFBitClear(stream->flags, CALLING_CLIENT);
     }
-    _CFStreamSetStatusCode(stream, kCFStreamStatusClosed);
-    __CFBitClear(stream->flags, CALLING_CLIENT);
 }
 
 //static int numStreamInstances = 0;
@@ -302,7 +295,7 @@ static void __CFStreamDeallocate(CFTypeRef cf) {
         if (cbContext->info && cbContext->release) {
             cbContext->release(cbContext->info);
         }
-        _CFStreamDetachSource(stream);
+
         if (stream->client->runLoopsAndModes) {
             CFRelease(stream->client->runLoopsAndModes);
         }
@@ -327,8 +320,14 @@ static void __CFStreamDeallocate(CFTypeRef cf) {
     if (!__CFBitIsSet(stream->flags, CONSTANT_CALLBACKS)) {
         CFAllocatorDeallocate(alloc, (void *)stream->callBacks);
     }
-       if (stream->_reserved1)
-               _CFStreamDestroyReserved(alloc, stream->_reserved1);
+    if (stream->previousRunloopsAndModes) {
+        CFRelease(stream->previousRunloopsAndModes);
+        stream->previousRunloopsAndModes = NULL;
+    }
+    if (stream->queue) {
+        dispatch_release(stream->queue);
+        stream->queue = NULL;
+    }
 }
 
 static const CFRuntimeClass __CFReadStreamClass = {
@@ -361,7 +360,7 @@ CONST_STRING_DECL(kCFStreamPropertySocketRemotePortNumber, "kCFStreamPropertySoc
 CONST_STRING_DECL(kCFStreamPropertyDataWritten, "kCFStreamPropertyDataWritten")
 CONST_STRING_DECL(kCFStreamPropertyAppendToFile, "kCFStreamPropertyAppendToFile")
 
-__private_extern__ void __CFStreamInitialize(void) {
+CF_PRIVATE void __CFStreamInitialize(void) {
     __kCFReadStreamTypeID = _CFRuntimeRegisterClass(&__CFReadStreamClass);
     __kCFWriteStreamTypeID = _CFRuntimeRegisterClass(&__CFWriteStreamClass);
 }
@@ -386,12 +385,18 @@ static struct _CFStream *_CFStreamCreate(CFAllocatorRef allocator, Boolean isRea
         newStream->info = NULL;
         newStream->callBacks = NULL;
                
-               newStream->_reserved1 = _CFStreamCreateReserved(allocator);
+        newStream->streamLock = CFSpinLockInit;
+        newStream->previousRunloopsAndModes = NULL;
+        newStream->queue = NULL;
     }
     return newStream;
 }
 
-__private_extern__ struct _CFStream *_CFStreamCreateWithConstantCallbacks(CFAllocatorRef alloc, void *info,  const struct _CFStreamCallBacks *cb, Boolean isReading) {
+CF_EXPORT void* _CFStreamGetInfoPointer(struct _CFStream* stream) {
+    return stream == NULL? NULL : stream->info;
+}
+
+CF_PRIVATE struct _CFStream *_CFStreamCreateWithConstantCallbacks(CFAllocatorRef alloc, void *info,  const struct _CFStreamCallBacks *cb, Boolean isReading) {
     struct _CFStream *newStream;
     if (cb->version != 1) return NULL;
     newStream = _CFStreamCreate(alloc, isReading);
@@ -577,50 +582,80 @@ static void _signalEventSync(struct _CFStream* stream, CFOptionFlags whatToSigna
 
     __CFBitSet(stream->flags, CALLING_CLIENT);
 
-    void* info = NULL;
-    void (*release) (void*) = NULL;
+    _CFStreamLock(stream);
 
-    if (stream->client->cbContext.retain == NULL)
-       info = stream->client->cbContext.info;
-    else {
-       info = stream->client->cbContext.retain(stream->client->cbContext.info);
-       release = stream->client->cbContext.release;
-    }
+    struct _CFStreamClient* client = stream->client;
+    if (client == NULL) {
+        _CFStreamUnlock(stream);
+    } else {
+        void* info = NULL;
+        void (*release) (void*) = NULL;
+        void (*cb)(struct _CFStream *, CFStreamEventType, void *) = client == NULL? NULL : client->cb;
 
-    for (eventMask = 1; eventMask <= whatToSignal; eventMask = eventMask << 1) {
-       if ((eventMask & whatToSignal) && (stream->client->when & eventMask)) {
-           stream->client->cb(stream, eventMask, info);
-           
-           /* What happens if the callback sets the client to NULL?  We're in a loop here... Hmm. */
-           /* After writing that comment, I see: <rdar://problem/6793636> CFReadStreamSetClient(..., NULL) unsafely releases info pointer immediately */
-        /* Of note, when the stream callbacks are set to to NULL, we're re-initalized so as not to receive more events, so we 
-         * should break pout of this loop */
-       }
-    }
+        if (stream->client->cbContext.retain == NULL)
+            info = stream->client->cbContext.info;
+        else {
+            info = stream->client->cbContext.retain(stream->client->cbContext.info);
+            release = stream->client->cbContext.release;
+        }
+        _CFStreamUnlock(stream);
 
-    if (release)
-       (*release) (info);
+        for (eventMask = 1; eventMask <= whatToSignal; eventMask = eventMask << 1) {
+            _CFStreamLock(stream);
+            Boolean shouldSignal = ((eventMask & whatToSignal) && stream->client && (stream->client->when & eventMask));
+            _CFStreamUnlock(stream);
 
+            if (shouldSignal && client) {
+                cb(stream, eventMask, info);
+
+                /* What happens if the callback sets the client to NULL?  We're in a loop here... Hmm. */
+                /* After writing that comment, I see: <rdar://problem/6793636> CFReadStreamSetClient(..., NULL) unsafely releases info pointer immediately */
+                /* Of note, when the stream callbacks are set to to NULL, we're re-initalized so as not to receive more events, so we
+                 * should break pout of this loop */
+            }
+        }
+        
+        if (release)
+            (*release) (info);
+    }
     __CFBitClear(stream->flags, CALLING_CLIENT);
 }
 
+static void _signalEventQueue(dispatch_queue_t q, struct _CFStream* stream, CFOptionFlags whatToSignal)
+{
+    CFRetain(stream);
+    dispatch_async(q, ^{
+        _signalEventSync(stream, whatToSignal);
+        CFRelease(stream);
+    });
+}
+
 static void _cfstream_solo_signalEventSync(void* info)
 {
     CFTypeID typeID = CFGetTypeID((CFTypeRef) info);
     
     if (typeID != CFReadStreamGetTypeID() && typeID != CFWriteStreamGetTypeID()) {
-       CFLog(__kCFLogAssertion, CFSTR("Expected an read or write stream for %p"), info);
+       CFLog(__kCFLogAssertion, CFSTR("Expected a read or write stream for %p"), info);
 #if defined(DEBUG)
        abort();
 #endif
     } else {
        struct _CFStream* stream = (struct _CFStream*) info;
+        _CFStreamLock(stream);
        CFOptionFlags whatToSignal = stream->client->whatToSignal;
        stream->client->whatToSignal = 0;
-       
+        dispatch_queue_t queue = stream->queue;
+        if (queue) dispatch_retain(queue);
+        CFRetain(stream);
+        _CFStreamUnlock(stream);
+        
        /* Since the array version holds a retain, we do it here as well, as opposed to taking a second retain in the client callback */
-       CFRetain(stream);
-       _signalEventSync(stream, whatToSignal);
+        if (queue == 0)
+            _signalEventSync(stream, whatToSignal);
+        else {
+            _signalEventQueue(queue, stream, whatToSignal);
+            dispatch_release(queue);
+        }
        CFRelease(stream);
     }
 }
@@ -638,44 +673,52 @@ static void _cfstream_shared_signalEventSync(void* info)
        CFMutableArrayRef list = (CFMutableArrayRef) info;
        CFIndex c, i;
        CFOptionFlags whatToSignal = 0;
+        dispatch_queue_t queue = 0;
        struct _CFStream* stream = NULL;
-       
+
        __CFSpinLock(&sSourceLock);
-       
+
        /* Looks like, we grab the first stream that wants an event... */
        /* Note that I grab an extra retain when I pull out the stream here... */
        c = CFArrayGetCount(list);
        for (i = 0; i < c; i++) {
            struct _CFStream* s = (struct _CFStream*)CFArrayGetValueAtIndex(list, i);
-           
+
            if (s->client->whatToSignal) {
                stream = s;
                CFRetain(stream);
                whatToSignal = stream->client->whatToSignal;
                s->client->whatToSignal = 0;
+                queue = stream->queue;
+                if (queue) dispatch_retain(queue);
                break;
            }
        }
-       
+
        /* And then we also signal any other streams in this array so that we get them next go? */
        for (; i < c;  i++) {
            struct _CFStream* s = (struct _CFStream*)CFArrayGetValueAtIndex(list, i);
            if (s->client->whatToSignal) {
-                       CFRunLoopSourceRef source = _CFStreamCopySource(s);
-                       if (source) {
-                               CFRunLoopSourceSignal(source);
-                               CFRelease(source);
-                       }
-            break;
+                CFRunLoopSourceRef source = _CFStreamCopySource(s);
+                if (source) {
+                    CFRunLoopSourceSignal(source);
+                    CFRelease(source);
+                }
+                break;
            }
        }
-       
+
        __CFSpinUnlock(&sSourceLock);
-       
+
        /* We're sitting here now, possibly with a stream that needs to be processed by the common routine */
        if (stream) {
-           _signalEventSync(stream, whatToSignal);
-           
+            if (queue == 0)
+                _signalEventSync(stream, whatToSignal);
+            else {
+                _signalEventQueue(queue, stream, whatToSignal);
+                dispatch_release(queue);
+            }
+
            /* Lose our extra retain */
            CFRelease(stream);
        }
@@ -688,15 +731,14 @@ static CFArrayRef _CFStreamGetRunLoopsAndModes(struct _CFStream *stream)
     CFArrayRef result = NULL;
     if (stream && stream->client) {
         _CFStreamLock(stream);
-        struct CFStreamAux* aux = _CFStreamGetAuxRecord(stream);
-        if (aux->previousRunloopsAndModes) {
-            CFRelease(aux->previousRunloopsAndModes);
-            aux->previousRunloopsAndModes = NULL;
+        if (stream->previousRunloopsAndModes) {
+            CFRelease(stream->previousRunloopsAndModes);
+            stream->previousRunloopsAndModes = NULL;
         }
         if (stream->client->runLoopsAndModes) {
-            aux->previousRunloopsAndModes = CFArrayCreateCopy(CFGetAllocator(stream), stream->client->runLoopsAndModes);
+            stream->previousRunloopsAndModes = CFArrayCreateCopy(CFGetAllocator(stream), stream->client->runLoopsAndModes);
         }
-        result = aux->previousRunloopsAndModes;
+        result = stream->previousRunloopsAndModes;
         checkRLMArray(result);
         _CFStreamUnlock(stream);
     }
@@ -754,7 +796,7 @@ static void _wakeUpRunLoop(struct _CFStream *stream) {
     }
 }
 
-__private_extern__ void _CFStreamSignalEvent(struct _CFStream *stream, CFStreamEventType event, CFErrorRef error, Boolean synchronousAllowed) {
+CF_PRIVATE void _CFStreamSignalEvent(struct _CFStream *stream, CFStreamEventType event, CFErrorRef error, Boolean synchronousAllowed) {
     // Update our internal status; we must use the primitive __CFStreamGetStatus(), because CFStreamGetStatus() calls us, and we can end up in an infinite loop.
     CFStreamStatus status = __CFStreamGetStatus(stream);
 
@@ -826,12 +868,12 @@ __private_extern__ void _CFStreamSignalEvent(struct _CFStream *stream, CFStreamE
                 _wakeUpRunLoop(stream);
             }
                
-                       CFRelease(source);
+            CFRelease(source);
         }
     }
 }
 
-__private_extern__ CFStreamStatus _CFStreamGetStatus(struct _CFStream *stream) {
+CF_PRIVATE CFStreamStatus _CFStreamGetStatus(struct _CFStream *stream) {
   CFStreamStatus status = __CFStreamGetStatus(stream);
   // Status code just represents the value when last we checked; if we were in the middle of doing work at that time, we need to find out if the work has completed, now.  If we find out about a status change, we need to inform the client as well, so we call _CFStreamSignalEvent.  This will take care of updating our internal status correctly, too.
   __CFBitSet(stream->flags, CALLING_CLIENT);
@@ -921,7 +963,7 @@ CF_EXPORT CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) {
     CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFErrorRef, (NSOutputStream *)stream, streamError);
 }
 
-__private_extern__ Boolean _CFStreamOpen(struct _CFStream *stream) {
+CF_PRIVATE Boolean _CFStreamOpen(struct _CFStream *stream) {
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     Boolean success, openComplete;
     if (_CFStreamGetStatus(stream) != kCFStreamStatusNotOpen) {
@@ -1190,7 +1232,7 @@ CF_EXPORT CFIndex CFWriteStreamWrite(CFWriteStreamRef writeStream, const UInt8 *
     }
 }
 
-__private_extern__ CFTypeRef _CFStreamCopyProperty(struct _CFStream *stream, CFStringRef propertyName) {
+CF_PRIVATE CFTypeRef _CFStreamCopyProperty(struct _CFStream *stream, CFStringRef propertyName) {
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     if (cb->copyProperty == NULL) {
         return NULL;
@@ -1213,7 +1255,7 @@ CF_EXPORT CFTypeRef CFWriteStreamCopyProperty(CFWriteStreamRef stream, CFStringR
     return _CFStreamCopyProperty((struct _CFStream *)stream, propertyName);
 }
 
-__private_extern__ Boolean _CFStreamSetProperty(struct _CFStream *stream, CFStringRef prop, CFTypeRef val) {
+CF_PRIVATE Boolean _CFStreamSetProperty(struct _CFStream *stream, CFStringRef prop, CFTypeRef val) {
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     if (cb->setProperty == NULL) {
         return FALSE;
@@ -1246,7 +1288,7 @@ static void _initializeClient(struct _CFStream *stream) {
 }
 
 /* If we add a setClient callback to the concrete stream callbacks, we must set/clear CALLING_CLIENT around it */
-__private_extern__ Boolean _CFStreamSetClient(struct _CFStream *stream, CFOptionFlags streamEvents, void (*clientCB)(struct _CFStream *, CFStreamEventType, void *), CFStreamClientContext *clientCallBackContext) {
+CF_PRIVATE Boolean _CFStreamSetClient(struct _CFStream *stream, CFOptionFlags streamEvents, void (*clientCB)(struct _CFStream *, CFStreamEventType, void *), CFStreamClientContext *clientCallBackContext) {
 
     Boolean removingClient = (streamEvents == kCFStreamEventNone || clientCB == NULL || clientCallBackContext == NULL);
 
@@ -1293,13 +1335,47 @@ __private_extern__ Boolean _CFStreamSetClient(struct _CFStream *stream, CFOption
 }
 
 CF_EXPORT Boolean CFReadStreamSetClient(CFReadStreamRef readStream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext) {
-    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, Boolean, (NSInputStream *)readStream, _setCFClientFlags:streamEvents callback:clientCB context:clientContext);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFReadStreamTypeID, (const void *)(NSInputStream *)readStream)) {
+        NSInputStream* is = (NSInputStream*) readStream;
+
+        if ([is respondsToSelector:@selector(_setCFClientFlags:callback:context:)])
+            return [is _setCFClientFlags:streamEvents callback:clientCB context:clientContext];
+        else {
+            if (clientCB == NULL)
+                [is setDelegate:nil];
+            else {
+                _CFStreamDelegate* d = [[_CFStreamDelegate alloc] initWithStreamEvents:streamEvents callback:(void*) clientCB context:clientContext];
+                [is setDelegate:d];
+            }
+            return true;
+        }
+    }
+#endif
+    
     streamEvents &= ~kCFStreamEventCanAcceptBytes;
     return _CFStreamSetClient((struct _CFStream *)readStream, streamEvents, (void (*)(struct _CFStream *, CFStreamEventType, void *))clientCB, clientContext);
 }
 
 CF_EXPORT Boolean CFWriteStreamSetClient(CFWriteStreamRef writeStream, CFOptionFlags streamEvents, CFWriteStreamClientCallBack clientCB, CFStreamClientContext *clientContext) {
-    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, Boolean, (NSOutputStream *)writeStream, _setCFClientFlags:streamEvents callback:clientCB context:clientContext);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFWriteStreamTypeID, (const void *)(NSInputStream *)writeStream)) {
+        NSOutputStream* os = (NSOutputStream*) writeStream;
+
+        if ([os respondsToSelector:@selector(_setCFClientFlags:callback:context:)])
+            return [os _setCFClientFlags:streamEvents callback:clientCB context:clientContext];
+        else {
+            if (clientCB == NULL)
+                [os setDelegate:nil];
+            else {
+                _CFStreamDelegate* d = [[_CFStreamDelegate alloc] initWithStreamEvents:streamEvents callback:(void*) clientCB context:clientContext];
+                [os setDelegate:d];
+            }
+            return true;
+        }
+    }
+#endif
+
     streamEvents &= ~kCFStreamEventHasBytesAvailable;
     return _CFStreamSetClient((struct _CFStream *)writeStream, streamEvents, (void (*)(struct _CFStream *, CFStreamEventType, void *))clientCB, clientContext);
 }
@@ -1318,7 +1394,7 @@ CF_EXPORT void *_CFWriteStreamGetClient(CFWriteStreamRef writeStream) {
 }
 
 
-__private_extern__ void _CFStreamScheduleWithRunLoop(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
+CF_PRIVATE void _CFStreamScheduleWithRunLoop(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     
     if (! stream->client) {
@@ -1478,17 +1554,37 @@ __private_extern__ void _CFStreamScheduleWithRunLoop(struct _CFStream *stream, C
 }
 
 CF_EXPORT void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, void, (NSInputStream *)stream, _scheduleInCFRunLoop:runLoop forMode:runLoopMode);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFReadStreamTypeID, (const void *)(NSInputStream *)stream)) {
+        NSInputStream* is  = (NSInputStream*) stream;
+        if ([is respondsToSelector:@selector(_scheduleInCFRunLoop:forMode:)])
+            [is _scheduleInCFRunLoop:runLoop forMode:runLoopMode];
+        else
+            [is scheduleInRunLoop:cfToNSRL(runLoop) forMode:(id) runLoopMode];
+        return;
+    }
+#endif
+    
     _CFStreamScheduleWithRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
 CF_EXPORT void CFWriteStreamScheduleWithRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, void, (NSOutputStream *)stream, _scheduleInCFRunLoop:runLoop forMode:runLoopMode);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFWriteStreamTypeID, (const void *)(NSOutputStream *)stream)) {
+        NSOutputStream* os  = (NSOutputStream*) stream;
+        if ([os respondsToSelector:@selector(_scheduleInCFRunLoop:forMode:)])
+            [os _scheduleInCFRunLoop:runLoop forMode:runLoopMode];
+        else
+            [os scheduleInRunLoop:cfToNSRL(runLoop) forMode:(id) runLoopMode];
+        return;
+    }
+#endif
+
     _CFStreamScheduleWithRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
 
-__private_extern__ void _CFStreamUnscheduleFromRunLoop(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
+CF_PRIVATE void _CFStreamUnscheduleFromRunLoop(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
     if (!stream->client) return;
     if (!stream->client->rlSource) return;
@@ -1545,15 +1641,196 @@ __private_extern__ void _CFStreamUnscheduleFromRunLoop(struct _CFStream *stream,
 }
 
 CF_EXPORT void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, void, (NSInputStream *)stream, _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFReadStreamTypeID, (const void *)(NSInputStream *)stream)) {
+        NSInputStream* is  = (NSInputStream*) stream;
+        if ([is respondsToSelector:@selector(_unscheduleFromCFRunLoop:forMode:)])
+            [is _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode];
+        else
+            [is removeFromRunLoop:cfToNSRL(runLoop) forMode:(id) runLoopMode];
+        return;
+    }
+#endif
+
     _CFStreamUnscheduleFromRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
 void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, void, (NSOutputStream *)stream, _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode);
+#if defined(CFSTREAM_SUPPORTS_BRIDGING)
+    if (CF_IS_OBJC(__kCFWriteStreamTypeID, (const void *)(NSOutputStream *)stream)) {
+        NSOutputStream* os  = (NSOutputStream*) stream;
+        if ([os respondsToSelector:@selector(_unscheduleFromCFRunLoop:forMode:)])
+            [os _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode];
+        else
+            [os removeFromRunLoop:cfToNSRL(runLoop) forMode:(id) runLoopMode];
+        return;
+    }
+#endif
+
     _CFStreamUnscheduleFromRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
+static CFRunLoopRef sLegacyRL = NULL;
+
+static void _perform(void* info)
+{
+}
+
+static void* _legacyStreamRunLoop_workThread(void* arg)
+{
+    sLegacyRL = CFRunLoopGetCurrent();
+
+#if defined(LOG_STREAM)
+    fprintf(stderr, "Creating Schedulingset emulation thread.  Runloop: %p\n", sLegacyRL);
+#endif
+
+    CFStringRef s = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("<< CFStreamLegacySource for Runloop %p >>"), sLegacyRL);
+
+    CFRunLoopSourceContext ctxt = {
+        0,
+        (void*) s,
+        CFRetain,
+        CFRelease,
+        CFCopyDescription,
+        CFEqual,
+        CFHash,
+        NULL,
+        NULL,
+        _perform
+    };
+
+    CFRunLoopSourceRef rls = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &ctxt);
+    CFRelease(s);
+
+    CFRunLoopAddSource(sLegacyRL, rls, kCFRunLoopDefaultMode);
+    CFRelease(rls);
+
+    dispatch_semaphore_signal(*(dispatch_semaphore_t*) arg);
+    arg = NULL;
+
+    while (true) {
+        SInt32 why = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1E30, true);
+
+        (void) why;
+#if defined(LOG_STREAM)
+        switch (why) {
+            case kCFRunLoopRunFinished:
+                fprintf(stderr, "WOKE: kCFRunLoopRunFinished\n");
+                break;
+            case kCFRunLoopRunStopped:
+                fprintf(stderr, "WOKE: kCFRunLoopRunStopped\n");
+                break;
+            case kCFRunLoopRunTimedOut:
+                fprintf(stderr, "WOKE: kCFRunLoopRunTimedOut\n");
+                break;
+            case kCFRunLoopRunHandledSource:
+                fprintf(stderr, "WOKE: kCFRunLoopRunHandledSource\n");
+                break;
+        }
+#endif
+    }
+
+    return NULL;
+}
+static CFRunLoopRef _legacyStreamRunLoop()
+{
+    static dispatch_once_t sOnce = 0;
+
+    dispatch_once(&sOnce, ^{
+
+        if (sLegacyRL == NULL) {
+            dispatch_semaphore_t sem = dispatch_semaphore_create(0);
+
+            pthread_attr_t attr;
+            pthread_attr_init(&attr);
+            pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+            pthread_t workThread;
+            (void) pthread_create(&workThread, &attr, _legacyStreamRunLoop_workThread, &sem);
+            pthread_attr_destroy(&attr);
+
+            dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
+            dispatch_release(sem);
+        }
+    });
+    
+    return sLegacyRL;
+}
+
+static dispatch_queue_t _CFStreamCopyDispatchQueue(struct _CFStream* stream)
+{
+    dispatch_queue_t result = NULL;
+    
+    _CFStreamLock(stream);
+    if (stream->client) {
+        result = stream->queue;
+        if (result)
+            dispatch_retain(result);
+    }
+    _CFStreamUnlock(stream);
+
+    return result;
+}
+
+static void _CFStreamSetDispatchQueue(struct _CFStream* stream, dispatch_queue_t q)
+{
+    CFArrayRef rlm = _CFStreamCopyRunLoopsAndModes(stream);
+    if (rlm) {
+        CFIndex count = CFArrayGetCount(rlm);
+        for (CFIndex i = 0;  i < count;  i += 2) {
+            CFRunLoopRef rl = (CFRunLoopRef) CFArrayGetValueAtIndex(rlm, i);
+            CFStringRef mode = (CFStringRef) CFArrayGetValueAtIndex(rlm, i + 1);
+            _CFStreamUnscheduleFromRunLoop(stream, rl, mode);
+        }
+        CFRelease(rlm);
+    }
+
+    if (q == NULL) {
+        _CFStreamLock(stream);
+        if (stream->client) {
+            if (stream->queue)
+                dispatch_release(stream->queue);
+            stream->queue = NULL;
+        }
+        _CFStreamUnlock(stream);
+    } else {
+        _CFStreamScheduleWithRunLoop(stream, _legacyStreamRunLoop(), kCFRunLoopDefaultMode);
+
+        _CFStreamLock(stream);
+        if (stream->client) {
+            if (stream->queue != q) {
+                if (stream->queue)
+                    dispatch_release(stream->queue);
+                stream->queue = q;
+                if (stream->queue)
+                    dispatch_retain(stream->queue);
+            }
+        }
+
+        _CFStreamUnlock(stream);
+    }
+}
+
+void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q)
+{
+    _CFStreamSetDispatchQueue((struct _CFStream*) stream, q);
+}
+
+void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q)
+{
+    _CFStreamSetDispatchQueue((struct _CFStream*) stream, q);
+}
+
+dispatch_queue_t CFReadStreamCopyDispatchQueue(CFReadStreamRef stream)
+{
+    return _CFStreamCopyDispatchQueue((struct _CFStream*) stream);
+}
+
+dispatch_queue_t CFWriteStreamCopyDispatchQueue(CFWriteStreamRef stream)
+{
+    return _CFStreamCopyDispatchQueue((struct _CFStream*) stream);
+}
+
+
 static void waitForOpen(struct _CFStream *stream) {
     CFRunLoopRef runLoop = CFRunLoopGetCurrent();
     CFStringRef privateMode = CFSTR("_kCFStreamBlockingOpenMode");
index 0bd5dffc0586b795cd279c888221804d29d48e1e..4db4edf19bd6b2e3f1cc5c2cf94a14cd5a563fa1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStream.h
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAM__)
@@ -35,6 +35,7 @@
 #include <CoreFoundation/CFRunLoop.h>
 #include <CoreFoundation/CFSocket.h>
 #include <CoreFoundation/CFError.h>
+#include <dispatch/dispatch.h>
 
 CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
@@ -185,12 +186,12 @@ CF_EXPORT
 CFIndex CFReadStreamRead(CFReadStreamRef stream, UInt8 *buffer, CFIndex bufferLength);
 
 /* Returns a pointer to an internal buffer if possible (setting *numBytesRead
-   to the length of the returned buffer), otherwise returns NULL; guaranteed 
-   to return in O(1).  Bytes returned in the buffer are considered read from 
+   to the length of the returned buffer), otherwise returns NULL; guaranteed
+   to return in O(1).  Bytes returned in the buffer are considered read from
    the stream; if maxBytesToRead is greater than 0, not more than maxBytesToRead
    will be returned.  If maxBytesToRead is less than or equal to zero, as many bytes
-   as are readily available will be returned.  The returned buffer is good only 
-   until the next stream operation called on the stream.  Caller should neither 
+   as are readily available will be returned.  The returned buffer is good only
+   until the next stream operation called on the stream.  Caller should neither
    change the contents of the returned buffer nor attempt to deallocate the buffer;
    it is still owned by the stream. */
 CF_EXPORT
@@ -232,12 +233,11 @@ Boolean CFWriteStreamSetProperty(CFWriteStreamRef stream, CFStringRef propertyNa
 /* Asynchronous processing - If you wish to neither poll nor block, you may register 
    a client to hear about interesting events that occur on a stream.  Only one client
    per stream is allowed; registering a new client replaces the previous one.
-
-   Once you have set a client, you need to schedule a run loop on which that client
-   can be notified.  You may schedule multiple run loops (for instance, if you are 
-   using a thread pool).  The client callback will be triggered via one of the scheduled
-   run loops; It is the caller's responsibility to ensure that at least one of the 
-   scheduled run loops is being run.
+   Once you have set a client, the stream must be scheduled to provide the context in
+   which the client will be called.  Streams may be scheduled on a single dispatch queue
+   or on one or more run loops.  If scheduled on a run loop, it is the caller's responsibility
+   to ensure that at least one of the scheduled run loops is being run.
 
    NOTE: Unlike other CoreFoundation APIs, pasing a NULL clientContext here will remove
    the client.  If you do not care about the client context (i.e. your only concern
@@ -261,6 +261,29 @@ void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runL
 CF_EXPORT
 void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode);
 
+/*
+ * Specify the dispatch queue upon which the client callbacks will be invoked.
+ * Passing NULL for the queue will prevent future callbacks from being invoked.
+ * Specifying a dispatch queue using this API will unschedule the stream from
+ * any run loops it had previously been scheduled upon - similarly, scheduling
+ * with a runloop will disassociate the stream from any existing dispatch queue.
+ */
+CF_EXPORT
+void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0);
+
+CF_EXPORT
+void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0);
+
+/*
+ * Returns the previously set dispatch queue with an incremented retain count.  
+ * Note that the stream's queue may have been set to NULL if the stream was 
+ * scheduled on a runloop subsequent to it having had a dispatch queue set.
+ */
+CF_EXPORT
+dispatch_queue_t CFReadStreamCopyDispatchQueue(CFReadStreamRef stream) CF_AVAILABLE(10_9, 7_0);
+
+CF_EXPORT
+dispatch_queue_t CFWriteStreamCopyDispatchQueue(CFWriteStreamRef stream) CF_AVAILABLE(10_9, 7_0);
 
 /* The following API is deprecated starting in 10.5; please use CFRead/WriteStreamCopyError(), above, instead */
 typedef CF_ENUM(CFIndex, CFStreamErrorDomain) {
index ab4d070a5b4e1a7c5dfb50d9a83d7e6777ad4fcf..f1268870b2b52ae34b92e5031af58c3139ab8d30 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStreamAbstract.h
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAMABSTRACT__)
index 7d7f4eaf92c7bbfaa04d90eb17f69b0813925dd4..72cbe9d48d21f01a43d84531952f7800c128b938 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -64,8 +64,8 @@ struct _CFStreamCallBacksV1 {
 };
 
 // These two are defined in CFSocketStream.c because that's where the glue for CFNetwork is.
-__private_extern__ CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *err);
-__private_extern__ CFStreamError _CFStreamErrorFromError(CFErrorRef error);
+CF_PRIVATE CFErrorRef _CFErrorFromStreamError(CFAllocatorRef alloc, CFStreamError *err);
+CF_PRIVATE CFStreamError _CFStreamErrorFromError(CFErrorRef error);
 
 CF_EXTERN_C_END
 
index 37ee6f0598c24029ece362fe2ea8de58237b3d2e..15f9beccc383c09700d702c142033bd96a2cc520 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStreamPriv.h
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAMPRIV__)
@@ -69,21 +69,9 @@ struct _CFStreamCallBacks {
     void (*unschedule)(struct _CFStream *stream, CFRunLoopRef runLoop, CFStringRef runLoopMode, void *info);
 };
 
-struct _CFStream {
-    CFRuntimeBase _cfBase;
-    CFOptionFlags flags;  
-    CFErrorRef error; // if callBacks->version < 2, this is actually a pointer to a CFStreamError
-    struct _CFStreamClient *client;
-    void *info;
-    const struct _CFStreamCallBacks *callBacks;  // This will not exist (will not be allocated) if the callbacks are from our known, "blessed" set.
-    void *_reserved1;
-};
-
-
-CF_INLINE void *_CFStreamGetInfoPointer(struct _CFStream *stream) {
-    return stream->info;
-}
+struct _CFStream;
 
+CF_EXPORT void* _CFStreamGetInfoPointer(struct _CFStream* stream);
 
 // cb version must be > 0
 CF_EXPORT struct _CFStream *_CFStreamCreateWithConstantCallbacks(CFAllocatorRef alloc, void *info, const struct _CFStreamCallBacks *cb, Boolean isReading);
index e59d7d782dd22879d372b9f4205de12872615745..a852643c3887cb43547e070a9be81b88490000a1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFString.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
         
 !!! For performance reasons, it's important that all functions marked CF_INLINE in this file are inlined.
@@ -64,7 +64,7 @@
 #define INSTRUMENT_SHARED_STRINGS 0
 #endif
 
-__private_extern__ const CFStringRef __kCFLocaleCollatorID;
+CF_PRIVATE const CFStringRef __kCFLocaleCollatorID;
 
 #if INSTRUMENT_SHARED_STRINGS
 #include <sys/stat.h> /* for umask() */
@@ -112,7 +112,7 @@ extern size_t malloc_good_size(size_t size);
 #endif
 extern void __CFStrConvertBytesToUnicode(const uint8_t *bytes, UniChar *buffer, CFIndex numChars);
 
-static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args);
+static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args);
 
 #if defined(DEBUG)
 
@@ -284,8 +284,7 @@ CF_INLINE CFAllocatorRef __CFStrContentsDeallocator(CFStringRef str) {
 
 // Assumption: Called with immutable strings only, and on strings that are known to have a contentsDeallocator
 CF_INLINE void __CFStrSetContentsDeallocator(CFStringRef str, CFAllocatorRef allocator) {
-    allocator = kCFUseCollectableAllocator ? allocator : _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
-    if (!(kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) CFRetain(allocator);
+    if (!(0 || 0)) CFRetain(allocator);
     *__CFStrContentsDeallocatorPtr(str) = allocator;
 }
 
@@ -302,8 +301,7 @@ CF_INLINE CFAllocatorRef __CFStrContentsAllocator(CFMutableStringRef str) {
 
 // Assumption: Called with strings that have a contents allocator; also, contents allocator follows custom
 CF_INLINE void __CFStrSetContentsAllocator(CFMutableStringRef str, CFAllocatorRef allocator) {
-    allocator = kCFUseCollectableAllocator ? allocator : _CFConvertAllocatorToNonGCRefZeroEquivalent(allocator);
-    if (!(kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) CFRetain(allocator);
+    if (!(0 || 0)) CFRetain(allocator);
     *(__CFStrContentsAllocatorPtr(str)) = allocator;
 }
 
@@ -392,7 +390,7 @@ static void *__CFStrAllocateMutableContents(CFMutableStringRef str, CFIndex size
 
 static void __CFStrDeallocateMutableContents(CFMutableStringRef str, void *buffer) {
     CFAllocatorRef alloc = (__CFStrHasContentsAllocator(str)) ? __CFStrContentsAllocator(str) : __CFGetAllocator(str);
-    if (__CFStrIsMutable(str) && __CFStrHasContentsAllocator(str) && _CFAllocatorIsGCRefZero(alloc)) {
+    if (__CFStrIsMutable(str) && __CFStrHasContentsAllocator(str) && (0)) {
         // do nothing
     } else if (CF_IS_COLLECTABLE_ALLOCATOR(alloc)) {
         // GC:  for finalization safety, let collector reclaim the buffer in the next GC cycle.
@@ -512,20 +510,30 @@ CF_INLINE Boolean __CFStrEncodingCanBeStoredInEightBit(CFStringEncoding encoding
 }
 
 /* Returns the encoding used in eight bit CFStrings (can't be any encoding which isn't 1-to-1 with Unicode)
-   ??? Perhaps only ASCII fits the bill due to Unicode decomposition.
+   For 10.9-linked apps, we've set this encoding to ASCII for all cases; see <rdar://problem/3597233>
 */
 CFStringEncoding __CFStringComputeEightBitStringEncoding(void) {
-    if (__CFDefaultEightBitStringEncoding == kCFStringEncodingInvalidId) {
-        CFStringEncoding systemEncoding = CFStringGetSystemEncoding();
-       if (systemEncoding == kCFStringEncodingInvalidId) { // We're right in the middle of querying system encoding from default database. Delaying to set until system encoding is determined.
-           return kCFStringEncodingASCII;
-       } else if (__CFStrEncodingCanBeStoredInEightBit(systemEncoding)) {
-            __CFDefaultEightBitStringEncoding = systemEncoding;
-        } else {
-            __CFDefaultEightBitStringEncoding = kCFStringEncodingASCII;
+    // This flag prevents recursive entry into __CFStringComputeEightBitStringEncoding
+    static Boolean __CFStringIsBeingInitialized2 = false;
+    if (__CFStringIsBeingInitialized2) return kCFStringEncodingASCII;
+    __CFStringIsBeingInitialized2 = true;
+    
+    Boolean useAscii = true;
+    __CFStringIsBeingInitialized2 = false;
+    if (useAscii) {
+        __CFDefaultEightBitStringEncoding = kCFStringEncodingASCII;
+    } else {
+        if (__CFDefaultEightBitStringEncoding == kCFStringEncodingInvalidId) {
+            CFStringEncoding systemEncoding = CFStringGetSystemEncoding();
+            if (systemEncoding == kCFStringEncodingInvalidId) { // We're right in the middle of querying system encoding from default database. Delaying to set until system encoding is determined.
+              return kCFStringEncodingASCII;
+            } else if (__CFStrEncodingCanBeStoredInEightBit(systemEncoding)) {
+                __CFDefaultEightBitStringEncoding = systemEncoding;
+            } else {
+                __CFDefaultEightBitStringEncoding = kCFStringEncodingASCII;
+            }
         }
     }
-
     return __CFDefaultEightBitStringEncoding;
 }
 
@@ -950,7 +958,7 @@ static void __CFStringDeallocate(CFTypeRef cf) {
                if (__CFStrHasContentsDeallocator(str)) {
                     CFAllocatorRef allocator = __CFStrContentsDeallocator(str);
                    CFAllocatorDeallocate(allocator, contents);
-                   if (!(kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) CFRelease(allocator);
+                   if (!(0 || 0 )) CFRelease(allocator);
                } else {
                    CFAllocatorRef alloc = __CFGetAllocator(str);
                    CFAllocatorDeallocate(alloc, contents);
@@ -959,7 +967,7 @@ static void __CFStringDeallocate(CFTypeRef cf) {
        }
        if (isMutable && __CFStrHasContentsAllocator(str)) {
             CFAllocatorRef allocator = __CFStrContentsAllocator((CFMutableStringRef)str);
-            if (!(kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) CFRelease(allocator);
+            if (!(0 || 0)) CFRelease(allocator);
         }
     }
 }
@@ -1194,7 +1202,7 @@ static const CFRuntimeClass __CFStringClass = {
     __CFStringCopyDescription
 };
 
-__private_extern__ void __CFStringInitialize(void) {
+CF_PRIVATE void __CFStringInitialize(void) {
     __kCFStringTypeID = _CFRuntimeRegisterClass(&__CFStringClass);
 }
 
@@ -1226,7 +1234,7 @@ static Boolean CFStrIsUnicode(CFStringRef str) {
    bytes should not contain BOM characters
    !!! Various flags should be combined to reduce number of arguments, if possible
 */
-__private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
+CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3(
                         CFAllocatorRef alloc, const void *bytes, CFIndex numBytes, CFStringEncoding encoding,
                         Boolean possiblyExternalFormat, Boolean tryToReduceUnicode, Boolean hasLengthByte, Boolean hasNullByte, Boolean noCopy,
                         CFAllocatorRef contentsDeallocator, UInt32 converterFlags) {
@@ -1398,9 +1406,9 @@ __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
     }
 #endif
 
+#if USE_STRING_ROM
     CFStringRef romResult = NULL;
 
-#if USE_STRING_ROM
 
     if (stringSupportsROM) {
         // Disable the string ROM if necessary
@@ -1422,16 +1430,17 @@ __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
        /* set our result to the ROM result which is not really mutable, of course, but that's OK because we don't try to modify it. */
        str = (CFMutableStringRef)romResult;
     }
-#endif
 
     if (! romResult) {
+#else
+    if (1) {
+#endif
        // Now determine the necessary size
 
        if (noCopy) {
 
            size = sizeof(void *);                              // Pointer to the buffer
-            // special GCRefZero allocator usage always needs saving
-           if (_CFAllocatorIsGCRefZero(contentsDeallocator) || (contentsDeallocator != alloc && contentsDeallocator != kCFAllocatorNull)) {
+           if ((0) || (contentsDeallocator != alloc && contentsDeallocator != kCFAllocatorNull)) {
                size += sizeof(void *); // The contentsDeallocator
            }
            if (!hasLengthByte) size += sizeof(CFIndex);        // Explicit length
@@ -1473,7 +1482,7 @@ __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
        if (str) {
            if (__CFOASafe) __CFSetLastAllocationEventName(str, "CFString (immutable)");
 
-            CFOptionFlags allocBits = _CFAllocatorIsGCRefZero(contentsDeallocator) ? __kCFHasContentsDeallocator : (contentsDeallocator == alloc ? __kCFNotInlineContentsDefaultFree : (contentsDeallocator == kCFAllocatorNull ? __kCFNotInlineContentsNoFree : __kCFNotInlineContentsCustomFree));
+            CFOptionFlags allocBits = (0) ? __kCFHasContentsDeallocator : (contentsDeallocator == alloc ? __kCFNotInlineContentsDefaultFree : (contentsDeallocator == kCFAllocatorNull ? __kCFNotInlineContentsNoFree : __kCFNotInlineContentsCustomFree));
            __CFStrSetInfoBits(str,
                                (useInlineData ? __kCFHasInlineContents : allocBits) |
                                ((encoding == kCFStringEncodingUnicode) ? __kCFIsUnicode : 0) |
@@ -1503,6 +1512,19 @@ __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
     }
     if (vBuf.shouldFreeChars) CFAllocatorDeallocate(vBuf.allocator, (void *)bytes);
 
+#if 0
+#warning Debug code
+    const uint8_t *contents = (uint8_t *)__CFStrContents(str);
+    CFIndex len = __CFStrLength2(str, contents);
+
+    if (__CFStrIsEightBit(str)) {
+        contents += __CFStrSkipAnyLengthByte(str);
+        if (!__CFBytesInASCII(contents, len)) {
+         printf("CFString with 8 bit backing store not ASCII: %p, \"%.*s\"\n", str, (int)len, contents);
+        }
+    }
+#endif
+
     return str;
 }
 
@@ -1570,7 +1592,7 @@ CFStringRef  _CFStringCreateWithFormatAndArgumentsAux(CFAllocatorRef alloc, CFSt
     CFStringRef str;
     CFMutableStringRef outputString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); //should use alloc if no copy/release
     __CFStrSetDesiredCapacity(outputString, 120);      // Given this will be tightened later, choosing a larger working string is fine
-    __CFStringAppendFormatCore(outputString, copyDescFunc, formatOptions, format, 0, NULL, 0, arguments);
+    __CFStringAppendFormatCore(outputString, copyDescFunc, formatOptions, NULL, format, 0, NULL, 0, arguments);
     // ??? copy/release should not be necessary here -- just make immutable, compress if possible
     // (However, this does make the string inline, and cause the supplied allocator to be used...)
     str = (CFStringRef)CFStringCreateCopy(alloc, outputString);
@@ -1611,9 +1633,9 @@ CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) {
 
     __CFAssertIsString(str);
     if (!__CFStrIsMutable((CFStringRef)str) &&                                                                 // If the string is not mutable
-        ((alloc ? _CFConvertAllocatorToNonGCRefZeroEquivalent(alloc) : __CFGetDefaultAllocator()) == __CFGetAllocator(str)) &&         //  and it has the same allocator as the one we're using
+        ((alloc ? alloc : __CFGetDefaultAllocator()) == __CFGetAllocator(str)) &&              //  and it has the same allocator as the one we're using
         (__CFStrIsInline((CFStringRef)str) || __CFStrFreeContentsWhenDone((CFStringRef)str) || __CFStrIsConstant((CFStringRef)str))) { //  and the characters are inline, or are owned by the string, or the string is constant
-        if (!(kCFUseCollectableAllocator && _CFAllocatorIsGCRefZero(alloc))) CFRetain(str);                    // Then just retain instead of making a true copy
+        if (!(kCFUseCollectableAllocator && (0))) CFRetain(str);                       // Then just retain instead of making a true copy
        return str;
     }
     if (__CFStrIsEightBit((CFStringRef)str)) {
@@ -1838,7 +1860,7 @@ CF_INLINE void __CFStringReplace(CFMutableStringRef str, CFRange range, CFString
 
 CF_INLINE CFMutableStringRef __CFStringCreateMutableFunnel(CFAllocatorRef alloc, CFIndex maxLength, UInt32 additionalInfoBits) {
     CFMutableStringRef str;
-    if (_CFAllocatorIsGCRefZero(alloc)) additionalInfoBits |= __kCFHasContentsAllocator;
+    if ((0)) additionalInfoBits |= __kCFHasContentsAllocator;
     Boolean hasExternalContentsAllocator = (additionalInfoBits & __kCFHasContentsAllocator) ? true : false;
 
     if (alloc == NULL) alloc = __CFGetDefaultAllocator();
@@ -1870,7 +1892,7 @@ CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocator
        __CFStrSetIsExternalMutable(string);
         if (__CFStrHasContentsAllocator(string)) {
             CFAllocatorRef allocator = __CFStrContentsAllocator((CFMutableStringRef)string);
-            if (!(kCFAllocatorSystemDefaultGCRefZero == allocator || kCFAllocatorDefaultGCRefZero == allocator)) CFRelease(allocator);
+            if (!(0 || 0)) CFRelease(allocator);
             __CFStrSetContentsAllocator(string, externalCharactersAllocator);
         }
         CFStringSetExternalCharactersNoCopy(string, chars, numChars, capacity);
@@ -1896,7 +1918,7 @@ CFMutableStringRef  CFStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxL
 }
 
 
-__private_extern__ void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len) {
+CF_PRIVATE void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len) {
     __CFAssertIsStringAndMutable(str);
     __CFStrSetDesiredCapacity(str, len);
 }
@@ -2033,6 +2055,8 @@ const char * CFStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding) {
     if (encoding != __CFStringGetEightBitStringEncoding() && (kCFStringEncodingASCII != __CFStringGetEightBitStringEncoding() || !__CFStringEncodingIsSupersetOfASCII(encoding))) return NULL;
     // ??? Also check for encoding = SystemEncoding and perhaps bytes are all ASCII?
 
+    if (str == NULL) return NULL;   // Should really just crash, but for compatibility... see <rdar://problem/12340248>
+    
     CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, const char *, (NSString *)str, _fastCStringContents:true);
 
     __CFAssertIsString(str);
@@ -2153,8 +2177,8 @@ Boolean CFStringGetCString(CFStringRef str, char *buffer, CFIndex bufferSize, CF
 extern Boolean __CFLocaleGetNullLocale(struct __CFLocale *locale);
 extern void __CFLocaleSetNullLocale(struct __CFLocale *locale);
 
-static const char *_CFStrGetLanguageIdentifierForLocale(CFLocaleRef locale) {
-    CFStringRef collatorID;
+static const char *_CFStrGetLanguageIdentifierForLocale(CFLocaleRef locale, bool collatorOnly) {
+    CFStringRef localeID;
     const char *langID = NULL;
     static const void *lastLocale = NULL;
     static const char *lastLangID = NULL;
@@ -2169,16 +2193,22 @@ static const char *_CFStrGetLanguageIdentifierForLocale(CFLocaleRef locale) {
     }
     __CFSpinUnlock(&lock);
 
-    collatorID = (CFStringRef)CFLocaleGetValue(locale, __kCFLocaleCollatorID);
+    localeID = (CFStringRef)CFLocaleGetValue(locale, __kCFLocaleCollatorID);
+
+    if (!collatorOnly) {
+        CFIndex length = __CFStrLength(localeID);
+
+        if ((length < 2) || ((4 == length) && CFEqual(localeID, CFSTR("root")))) localeID = (CFStringRef)CFLocaleGetIdentifier(locale);
+    }
 
     // This is somewhat depending on CFLocale implementation always creating CFString for locale identifer ???
-    if (__CFStrLength(collatorID) > 1) {
-        const void *contents = __CFStrContents(collatorID);
+    if (__CFStrLength(localeID) > 1) {
+        const void *contents = __CFStrContents(localeID);
         const char *string;
         char buffer[2];
         
-        if (__CFStrIsEightBit(collatorID)) {
-            string = ((const char *)contents) + __CFStrSkipAnyLengthByte(collatorID);
+        if (__CFStrIsEightBit(localeID)) {
+            string = ((const char *)contents) + __CFStrSkipAnyLengthByte(localeID);
         } else {
             const UTF16Char *characters = (const UTF16Char *)contents;
             
@@ -2200,7 +2230,6 @@ static const char *_CFStrGetLanguageIdentifierForLocale(CFLocaleRef locale) {
         }
     }
 
     if (langID == NULL) __CFLocaleSetNullLocale((struct __CFLocale *)locale);
 
     __CFSpinLock(&lock);
@@ -2493,7 +2522,7 @@ CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef string, CFStr
        freeLocale = true;
     }
 
-    langCode = ((NULL == locale) ? NULL : (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(locale));
+    langCode = ((NULL == locale) ? NULL : (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(locale, true));
 
     if (__CFStringFillCharacterSetInlineBuffer(&csetBuffer, compareOptions)) {
        ignoredChars = &csetBuffer;
@@ -2854,11 +2883,11 @@ Boolean CFStringFindWithOptionsAndLocale(CFStringRef string, CFStringRef stringT
         if (NULL == locale) {
             if (compareOptions & kCFCompareLocalized) {
                 CFLocaleRef currentLocale = CFLocaleCopyCurrent();
-                langCode = (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(currentLocale);
+                langCode = (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(currentLocale, true);
                CFRelease(currentLocale);
             }
         } else {
-            langCode = (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(locale);
+            langCode = (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(locale, true);
         }
 
         CFStringInitInlineBuffer(string, &inlineBuf1, CFRangeMake(0, rangeToSearch.location + rangeToSearch.length));
@@ -3242,7 +3271,7 @@ static void __rangeRelease(CFAllocatorRef allocator, const void *ptr) {
 
 static CFStringRef __rangeCopyDescription(const void *ptr) {
     CFRange range = *(CFRange *)ptr;
-    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("{%d, %d}"), range.location, range.length);
+    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("{%ld, %ld}"), (long)range.location, (long)range.length);
 }
 
 static Boolean __rangeEqual(const void *ptr1, const void *ptr2) {
@@ -3274,8 +3303,7 @@ CFArrayRef CFStringCreateArrayWithFindResults(CFAllocatorRef alloc, CFStringRef
 
        // If necessary, grow the data and squirrel away the found range 
        if (foundCount >= capacity) {
-            // Note that rangeStorage is not allowed to be allocated from one of the GCRefZero allocators
-           if (rangeStorage == NULL) rangeStorage = CFDataCreateMutable(_CFConvertAllocatorToNonGCRefZeroEquivalent(alloc), 0);
+           if (rangeStorage == NULL) rangeStorage = CFDataCreateMutable(alloc, 0);
            capacity = (capacity + 4) * 2;
            CFDataSetLength(rangeStorage, capacity * (sizeof(CFRange) + sizeof(CFDataRef)));
            rangeStorageBytes = (uint8_t *)CFDataGetMutableBytePtr(rangeStorage) + foundCount * (sizeof(CFRange) + sizeof(CFDataRef));
@@ -3925,14 +3953,14 @@ CFArrayRef CFStringCreateArrayBySeparatingStrings(CFAllocatorRef alloc, CFString
             numChars = currentRange->location - startIndex;
             substring = CFStringCreateWithSubstring(alloc, string, CFRangeMake(startIndex, numChars));
             CFArrayAppendValue(array, substring);
-            if (!_CFAllocatorIsGCRefZero(alloc)) CFRelease(substring);
+            CFRelease(substring);
             startIndex = currentRange->location + currentRange->length;
         }
         substring = CFStringCreateWithSubstring(alloc, string, CFRangeMake(startIndex, length - startIndex));
         CFArrayAppendValue(array, substring);
-        if (!_CFAllocatorIsGCRefZero(alloc)) CFRelease(substring);
+        CFRelease(substring);
 
-       if (!_CFAllocatorIsGCRefZero(alloc)) CFRelease(separatorRanges);
+       CFRelease(separatorRanges);
         
         return array;
     }
@@ -4426,7 +4454,7 @@ void CFStringLowercase(CFMutableStringRef string, CFLocaleRef locale) {
 
     length = __CFStrLength(string);
 
-    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale) : NULL);
+    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale, false) : NULL);
 
     if (!langCode && isEightBit) {
         uint8_t *contents = (uint8_t *)__CFStrContents(string) + __CFStrSkipAnyLengthByte(string);
@@ -4517,7 +4545,7 @@ void CFStringUppercase(CFMutableStringRef string, CFLocaleRef locale) {
 
     length = __CFStrLength(string);
 
-    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale) : NULL);
+    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale, false) : NULL);
 
     if (!langCode && isEightBit) {
         uint8_t *contents = (uint8_t *)__CFStrContents(string) + __CFStrSkipAnyLengthByte(string);
@@ -4613,7 +4641,7 @@ void CFStringCapitalize(CFMutableStringRef string, CFLocaleRef locale) {
 
     caseIgnorableForBMP = CFUniCharGetBitmapPtrForPlane(kCFUniCharCaseIgnorableCharacterSet, 0);
 
-    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale) : NULL);
+    langCode = (const uint8_t *)(_CFCanUseLocale(locale) ? _CFStrGetLanguageIdentifierForLocale(locale, false) : NULL);
 
     if (!langCode && isEightBit) {
         uint8_t *contents = (uint8_t *)__CFStrContents(string) + __CFStrSkipAnyLengthByte(string);
@@ -5043,7 +5071,7 @@ void CFStringNormalize(CFMutableStringRef string, CFStringNormalizationForm theF
     }
 }
 
-void CFStringFold(CFMutableStringRef theString, CFOptionFlags theFlags, CFLocaleRef locale) {
+void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, CFLocaleRef locale) {
     CFStringInlineBuffer stringBuffer;
     CFIndex length = CFStringGetLength(theString);
     CFIndex currentIndex = 0;
@@ -5064,7 +5092,7 @@ void CFStringFold(CFMutableStringRef theString, CFOptionFlags theFlags, CFLocale
     
     if ((0 == theFlags) || (0 == length)) goto bail; // nothing to do
 
-    langCode = ((NULL == theLocale) ? NULL : (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(theLocale));
+    langCode = ((NULL == theLocale) ? NULL : (const uint8_t *)_CFStrGetLanguageIdentifierForLocale(theLocale, true));
 
     eightBitEncoding = __CFStringGetEightBitStringEncoding();
     cString = (const uint8_t *)CFStringGetCStringPtr(theString, eightBitEncoding);
@@ -5337,7 +5365,7 @@ static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLoca
         // use significant digits pattern
         CFStringAppendCString(pattern, "@", kCFStringEncodingASCII);
         CFStringPad(pattern, CFSTR("#"), prec, 0);
-        double targetValue = values[spec->mainArgNum].value.doubleValue;;
+        double targetValue = values[spec->mainArgNum].value.doubleValue;
 #if LONG_DOUBLE_SUPPORT
         if (CFFormatSize16 == values[spec->mainArgNum].size) {
             targetValue = values[spec->mainArgNum].value.longDoubleValue; // losing precision
@@ -5355,19 +5383,20 @@ static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLoca
         CFRelease(pattern);
     }
     
-    CFNumberRef tmp;
+    // clear the padding, we will add it later if we need it
+    const SInt32 z = 0;
+    CFNumberRef zero = CFNumberCreate(NULL, kCFNumberSInt32Type, &z);
+    CFNumberFormatterSetProperty(formatter, kCFNumberFormatterFormatWidthKey, zero);
     
-    tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &prec); 
+    CFNumberRef tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &prec);
     CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMaxFractionDigitsKey, tmp);
     if (spec->type == CFFormatDoubleType) {
         CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinFractionDigitsKey, tmp);
     } else {
-        CFRelease(tmp);
-        SInt32 zero = 0;
-        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &zero);
-        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinFractionDigitsKey, tmp);
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinFractionDigitsKey, zero);
     }
     CFRelease(tmp);
+    CFRelease(zero);
 
 
     // ??? use the right zero here for Arabic
@@ -5389,8 +5418,22 @@ static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLoca
     CFNumberFormatterSetProperty(formatter, kCFNumberFormatterPaddingPositionKey, tmp);
     CFRelease(tmp);
 
+    Boolean isNegative = false;
+    switch (values[spec->mainArgNum].type) {
+        case CFFormatLongType:
+            if (values[spec->mainArgNum].value.int64Value < 0) isNegative = true;
+            break;
+        case CFFormatDoubleType:
+#if LONG_DOUBLE_SUPPORT
+            if ((CFFormatSize16 == values[spec->mainArgNum].size) && (values[spec->mainArgNum].value.longDoubleValue < 0)) isNegative = true;
+            else
+#endif
+            if (values[spec->mainArgNum].value.doubleValue < 0) isNegative = true;
+            break;
+    }
+
     CFStringRef pattern = CFNumberFormatterGetFormat(formatter);
-    if (spec->flags & kCFStringFormatPlusFlag) {
+    if ((spec->flags & kCFStringFormatPlusFlag) && !isNegative) {
         if (CFStringGetCharacterAtIndex(pattern, 0) != '+') {
             CFMutableStringRef newPattern = CFStringCreateMutableCopy(NULL, 0, CFSTR("+"));
             CFStringAppend(newPattern, pattern);
@@ -5664,7 +5707,7 @@ reswtch:switch (ch) {
 /* ??? %s depends on handling of encodings by __CFStringAppendBytes
 */
 void CFStringAppendFormatAndArguments(CFMutableStringRef outputString, CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) {
-    __CFStringAppendFormatCore(outputString, NULL, formatOptions, formatString, 0, NULL, 0, args);
+    __CFStringAppendFormatCore(outputString, NULL, formatOptions, NULL, formatString, 0, NULL, 0, args);
 }
         
 // Length of the buffer to call sprintf() with
@@ -5704,9 +5747,9 @@ void CFStringAppendFormatAndArguments(CFMutableStringRef outputString, CFDiction
     }}
 #endif
 
-void _CFStringAppendFormatAndArgumentsAux(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) { __CFStringAppendFormatCore(outputString, copyDescFunc, formatOptions, formatString, 0, NULL, 0, args); }
+void _CFStringAppendFormatAndArgumentsAux(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) { __CFStringAppendFormatCore(outputString, copyDescFunc, formatOptions, NULL, formatString, 0, NULL, 0, args); }
 
-static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args) {
+static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args) {
     SInt32 numSpecs, sizeSpecs, sizeArgNum, formatIdx, curSpec, argNum;
     CFIndex formatLen;
 #define FORMAT_BUFFER_LEN 400
index 3ce34cb4995fff58b49b2d01015407eb43893043..8fe267d98c24c542dff1d148c582a73583f5e05f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFString.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRING__)
@@ -704,7 +704,7 @@ CF_EXPORT void CFStringNormalize(CFMutableStringRef theString, CFStringNormaliza
 */
 
 CF_EXPORT
-void CFStringFold(CFMutableStringRef theString, CFOptionFlags theFlags, CFLocaleRef theLocale) CF_AVAILABLE(10_5, 2_0);
+void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, CFLocaleRef theLocale) CF_AVAILABLE(10_5, 2_0);
 
 /* Perform string transliteration.  The transformation represented by transform is applied to the given range of string, modifying it in place. Only the specified range will be modified, but the transform may look at portions of the string outside that range for context. NULL range pointer causes the whole string to be transformed. On return, range is modified to reflect the new range corresponding to the original range. reverse indicates that the inverse transform should be used instead, if it exists. If the transform is successful, true is returned; if unsuccessful, false. Reasons for the transform being unsuccessful include an invalid transform identifier, or attempting to reverse an irreversible transform.
 
@@ -796,7 +796,8 @@ CFStringEncoding CFStringGetMostCompatibleMacStringEncoding(CFStringEncoding enc
 typedef struct {
     UniChar buffer[__kCFStringInlineBufferLength];
     CFStringRef theString;
-    const UniChar *directBuffer;
+    const UniChar *directUniCharBuffer;
+    const char *directCStringBuffer;
     CFRange rangeToBuffer;             /* Range in string to buffer */
     CFIndex bufferedRangeStart;                /* Start of range currently buffered (relative to rangeToBuffer.location) */
     CFIndex bufferedRangeEnd;          /* bufferedRangeStart + number of chars actually buffered */
@@ -806,17 +807,15 @@ typedef struct {
 CF_INLINE void CFStringInitInlineBuffer(CFStringRef str, CFStringInlineBuffer *buf, CFRange range) {
     buf->theString = str;
     buf->rangeToBuffer = range;
-    buf->directBuffer = CFStringGetCharactersPtr(str);
+    buf->directCStringBuffer = (buf->directUniCharBuffer = CFStringGetCharactersPtr(str)) ? NULL : CFStringGetCStringPtr(str, kCFStringEncodingASCII);
     buf->bufferedRangeStart = buf->bufferedRangeEnd = 0;
 }
 
 CF_INLINE UniChar CFStringGetCharacterFromInlineBuffer(CFStringInlineBuffer *buf, CFIndex idx) {
-    if (buf->directBuffer) {
-       if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0;
-        return buf->directBuffer[idx + buf->rangeToBuffer.location];
-    }
+    if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0;
+    if (buf->directUniCharBuffer) return buf->directUniCharBuffer[idx + buf->rangeToBuffer.location];
+    if (buf->directCStringBuffer) return (UniChar)(buf->directCStringBuffer[idx + buf->rangeToBuffer.location]);
     if (idx >= buf->bufferedRangeEnd || idx < buf->bufferedRangeStart) {
-       if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0;
        if ((buf->bufferedRangeStart = idx - 4) < 0) buf->bufferedRangeStart = 0;
        buf->bufferedRangeEnd = buf->bufferedRangeStart + __kCFStringInlineBufferLength;
        if (buf->bufferedRangeEnd > buf->rangeToBuffer.length) buf->bufferedRangeEnd = buf->rangeToBuffer.length;
@@ -829,10 +828,10 @@ CF_INLINE UniChar CFStringGetCharacterFromInlineBuffer(CFStringInlineBuffer *buf
 /* If INLINE functions are not available, we do somewhat less powerful macros that work similarly (except be aware that the buf argument is evaluated multiple times).
 */
 #define CFStringInitInlineBuffer(str, buf, range) \
-    do {(buf)->theString = str; (buf)->rangeToBuffer = range; (buf)->directBuffer = CFStringGetCharactersPtr(str);} while (0)
+    do {(buf)->theString = str; (buf)->rangeToBuffer = range; (buf)->directCStringBuffer = ((buf)->directUniCharBuffer = CFStringGetCharactersPtr(str)) ? NULL : CFStringGetCStringPtr(str, kCFStringEncodingASCII);} while (0)
 
 #define CFStringGetCharacterFromInlineBuffer(buf, idx) \
-    (((idx) < 0 || (idx) >= (buf)->rangeToBuffer.length) ? 0 : ((buf)->directBuffer ? (buf)->directBuffer[(idx) + (buf)->rangeToBuffer.location] : CFStringGetCharacterAtIndex((buf)->theString, (idx) + (buf)->rangeToBuffer.location)))
+    (((idx) < 0 || (idx) >= (buf)->rangeToBuffer.length) ? 0 : ((buf)->directUniCharBuffer ? (buf)->directUniCharBuffer[(idx) + (buf)->rangeToBuffer.location] : ((buf)->directCStringBuffer ? (UniChar)((buf)->directCStringBuffer[(idx) + (buf)->rangeToBuffer.location]) : CFStringGetCharacterAtIndex((buf)->theString, (idx) + (buf)->rangeToBuffer.location))))
 
 #endif /* CF_INLINE */
 
@@ -881,7 +880,7 @@ void CFShowStr(CFStringRef str);
 
 /* This function is private and should not be used directly */
 CF_EXPORT
-CFStringRef  __CFStringMakeConstantString(const char *cStr);   /* Private; do not use */
+CFStringRef  __CFStringMakeConstantString(const char *cStr) CF_FORMAT_ARGUMENT(1);     /* Private; do not use */
 
 CF_EXTERN_C_END
 CF_IMPLICIT_BRIDGING_DISABLED
index f209328642101724d111cd63b657a6ba6d33a3aa..e7c21eb6ed37fb24f65b9af07f3a61cde79320c4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringDefaultEncoding.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGDEFAULTENCODING__)
index 5ce9c40656d2709d8ac6c8ace7e30c9891df3e70..62a116caad16da327385e4d0ec455314b5906aa6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverter.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -853,11 +853,11 @@ uint32_t CFStringEncodingBytesToUnicode(uint32_t encoding, uint32_t flags, const
     return theResult;
 }
 
-__private_extern__ bool CFStringEncodingIsValidEncoding(uint32_t encoding) {
+CF_PRIVATE bool CFStringEncodingIsValidEncoding(uint32_t encoding) {
     return (CFStringEncodingGetConverter(encoding) ? true : false);
 }
 
-__private_extern__ CFIndex CFStringEncodingCharLengthForBytes(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
+CF_PRIVATE CFIndex CFStringEncodingCharLengthForBytes(uint32_t encoding, uint32_t flags, const uint8_t *bytes, CFIndex numBytes) {
     const _CFEncodingConverter *converter = __CFGetConverter(encoding);
 
     if (converter) {
@@ -901,7 +901,7 @@ __private_extern__ CFIndex CFStringEncodingCharLengthForBytes(uint32_t encoding,
     return 0;
 }
 
-__private_extern__ CFIndex CFStringEncodingByteLengthForCharacters(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars) {
+CF_PRIVATE CFIndex CFStringEncodingByteLengthForCharacters(uint32_t encoding, uint32_t flags, const UniChar *characters, CFIndex numChars) {
     const _CFEncodingConverter *converter = __CFGetConverter(encoding);
 
     if (converter) {
@@ -925,7 +925,7 @@ __private_extern__ CFIndex CFStringEncodingByteLengthForCharacters(uint32_t enco
     return 0;
 }
 
-__private_extern__ void CFStringEncodingRegisterFallbackProcedures(uint32_t encoding, CFStringEncodingToBytesFallbackProc toBytes, CFStringEncodingToUnicodeFallbackProc toUnicode) {
+void CFStringEncodingRegisterFallbackProcedures(uint32_t encoding, CFStringEncodingToBytesFallbackProc toBytes, CFStringEncodingToUnicodeFallbackProc toUnicode) {
     _CFEncodingConverter *converter = (_CFEncodingConverter *)__CFGetConverter(encoding);
 
     if (NULL != converter) {
@@ -936,7 +936,7 @@ __private_extern__ void CFStringEncodingRegisterFallbackProcedures(uint32_t enco
     }
 }
 
-__private_extern__ const CFStringEncodingConverter *CFStringEncodingGetConverter(uint32_t encoding) {
+CF_PRIVATE const CFStringEncodingConverter *CFStringEncodingGetConverter(uint32_t encoding) {
     const _CFEncodingConverter *converter = __CFGetConverter(encoding);
 
     return ((NULL == converter) ? NULL : converter->definition);
@@ -984,7 +984,7 @@ static void __CFStringEncodingFliterDupes(CFStringEncoding *encodings, CFIndex n
     }
 }
 
-__private_extern__ const CFStringEncoding *CFStringEncodingListOfAvailableEncodings(void) {
+CF_PRIVATE const CFStringEncoding *CFStringEncodingListOfAvailableEncodings(void) {
     static const CFStringEncoding *encodings = NULL;
 
     if (NULL == encodings) {
index ea1f9eca7d86e614f41f7c284c1b531c415ac296..2357ac23fcf18f4ad7f7f249725cc8ce6b7d0d8e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverter.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERTER__)
index 9c1328ff3333f9d28c9ea7c4ee4b82f602d99e40..2415c6ab027239b87b84fa2ec5d48988c794a3e3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverterExt.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERETEREXT__)
index 91a5ed11c9f2ac80394c6453904a853499f4374a..faab37cda5461363b27b241939665e0509d4ddbf 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverterPriv.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERTERPRIV__)
index 50116da51a6b97a5763813100ab8c8367f2c382e..2e1845b3871bcaf517776a9169f5a29ccf3b70a9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingDatabase.c
-       Copyright (c) 2005-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2005-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -393,7 +393,7 @@ static inline CFIndex __CFGetEncodingIndex(CFStringEncoding encoding) {
     return kCFNotFound;
 }
 
-__private_extern__ uint16_t __CFStringEncodingGetWindowsCodePage(CFStringEncoding encoding) {
+CF_PRIVATE uint16_t __CFStringEncodingGetWindowsCodePage(CFStringEncoding encoding) {
     CFStringEncoding encodingBase = encoding & 0x0F00;
 
     if (0x0100 == encodingBase) { // UTF
@@ -416,7 +416,7 @@ __private_extern__ uint16_t __CFStringEncodingGetWindowsCodePage(CFStringEncodin
     return 0;
 }
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromWindowsCodePage(uint16_t codepage) {
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromWindowsCodePage(uint16_t codepage) {
     switch (codepage) {
         case 65001: return kCFStringEncodingUTF8;
         case 1200: return kCFStringEncodingUTF16;
@@ -453,7 +453,7 @@ __private_extern__ CFStringEncoding __CFStringEncodingGetFromWindowsCodePage(uin
     return kCFStringEncodingInvalidId;
 }
 
-__private_extern__ bool __CFStringEncodingGetCanonicalName(CFStringEncoding encoding, char *buffer, CFIndex bufferSize) {
+CF_PRIVATE bool __CFStringEncodingGetCanonicalName(CFStringEncoding encoding, char *buffer, CFIndex bufferSize) {
     const char *format = "%s";
     const char *name = NULL;
     uint32_t value = 0;
@@ -523,7 +523,7 @@ static CFHashCode __CFCanonicalNameHash(const void *value) {
     return code * (name - (const char *)value);
 }
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromCanonicalName(const char *canonicalName) {
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromCanonicalName(const char *canonicalName) {
     CFStringEncoding encoding;
     CFIndex prefixLength;
     static CFMutableDictionaryRef mappingTable = NULL;
@@ -797,7 +797,7 @@ static const char *__CFOtherNameList[] = {
 };
 #endif /* DEPLOYMENT_TARGET_MACOSX */
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetMostCompatibleMacScript(CFStringEncoding encoding) {
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetMostCompatibleMacScript(CFStringEncoding encoding) {
 #if DEPLOYMENT_TARGET_MACOSX
     switch (encoding & 0x0F00) {
         case 0: return encoding & 0xFF; break; // Mac scripts
@@ -822,7 +822,7 @@ __private_extern__ CFStringEncoding __CFStringEncodingGetMostCompatibleMacScript
     return kCFStringEncodingInvalidId;
 }
 
-__private_extern__ const char *__CFStringEncodingGetName(CFStringEncoding encoding) {
+CF_PRIVATE const char *__CFStringEncodingGetName(CFStringEncoding encoding) {
     switch (encoding) {
         case kCFStringEncodingUTF8: return "Unicode (UTF-8)"; break;
         case kCFStringEncodingUTF16: return "Unicode (UTF-16)"; break;
index c8f334eb7aaeeb9ef0f750b72cd2aa5d427236b2..f908e14443622d8876e8f83688b3158906cda134 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *  CoreFoundation
  *
  *  Created by Aki Inoue on 07/12/05.
- *  Copyright (c) 2007-2012, Apple Inc. All rights reserved.
+ *  Copyright (c) 2007-2013, Apple Inc. All rights reserved.
  *
  */
 
 #include <CoreFoundation/CFString.h>
 
-__private_extern__ uint16_t __CFStringEncodingGetWindowsCodePage(CFStringEncoding encoding);
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromWindowsCodePage(uint16_t codepage);
+CF_PRIVATE uint16_t __CFStringEncodingGetWindowsCodePage(CFStringEncoding encoding);
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromWindowsCodePage(uint16_t codepage);
 
-__private_extern__ bool __CFStringEncodingGetCanonicalName(CFStringEncoding encoding, char *buffer, CFIndex bufferSize);
-__private_extern__ CFStringEncoding __CFStringEncodingGetFromCanonicalName(const char *canonicalName);
+CF_PRIVATE bool __CFStringEncodingGetCanonicalName(CFStringEncoding encoding, char *buffer, CFIndex bufferSize);
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetFromCanonicalName(const char *canonicalName);
 
-__private_extern__ CFStringEncoding __CFStringEncodingGetMostCompatibleMacScript(CFStringEncoding encoding);
+CF_PRIVATE CFStringEncoding __CFStringEncodingGetMostCompatibleMacScript(CFStringEncoding encoding);
 
-__private_extern__ const char *__CFStringEncodingGetName(CFStringEncoding encoding); // Returns simple non-localizd name
+CF_PRIVATE const char *__CFStringEncodingGetName(CFStringEncoding encoding); // Returns simple non-localizd name
index 77fd9164a8c1c2a610ab94303d0545a9cbd94154..8dc4164de665fa9609c4f5cde7071b942f0dec86 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingExt.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGEXT__)
index f0f9db064a39fb074aa195eb563fb45e42d5afdc..2dc9e9454b24b8a4642b1ca5c9cb20293777174d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodings.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -57,7 +57,7 @@ Boolean (*__CFCharToUniCharFunc)(UInt32 flags, uint8_t ch, UniChar *unicodeChar)
 
 // To avoid early initialization issues, we just initialize this here
 // This should not be const as it is changed
-__private_extern__ UniChar __CFCharToUniCharTable[256] = {
+CF_PRIVATE UniChar __CFCharToUniCharTable[256] = {
   0,   1,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,  15,
  16,  17,  18,  19,  20,  21,  22,  23,  24,  25,  26,  27,  28,  29,  30,  31,
  32,  33,  34,  35,  36,  37,  38,  39,  40,  41,  42,  43,  44,  45,  46,  47,
@@ -76,7 +76,7 @@ __private_extern__ UniChar __CFCharToUniCharTable[256] = {
 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
 };    
 
-__private_extern__ void __CFSetCharToUniCharFunc(Boolean (*func)(UInt32 flags, UInt8 ch, UniChar *unicodeChar)) {
+CF_PRIVATE void __CFSetCharToUniCharFunc(Boolean (*func)(UInt32 flags, UInt8 ch, UniChar *unicodeChar)) {
     if (__CFCharToUniCharFunc != func) {
         int ch;
         __CFCharToUniCharFunc = func;
@@ -91,7 +91,7 @@ __private_extern__ void __CFSetCharToUniCharFunc(Boolean (*func)(UInt32 flags, U
     }
 }
 
-__private_extern__ void __CFStrConvertBytesToUnicode(const uint8_t *bytes, UniChar *buffer, CFIndex numChars) {
+CF_PRIVATE void __CFStrConvertBytesToUnicode(const uint8_t *bytes, UniChar *buffer, CFIndex numChars) {
     CFIndex idx;
     for (idx = 0; idx < numChars; idx++) buffer[idx] = __CFCharToUniCharTable[bytes[idx]];
 }
index a5f16278eb7fa88d61dcd2f7e211be9da882936a..980e1425b17d5c9175d590285345e72b5f8b477c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringScanner.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
@@ -63,7 +63,7 @@ CF_INLINE UniChar __CFStringGetFirstNonSpaceCharacterFromInlineBuffer(CFStringIn
 
 /* result is int64_t or int, depending on doLonglong
 */
-__private_extern__ Boolean __CFStringScanInteger(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, Boolean doLonglong, void *result) {
+CF_PRIVATE Boolean __CFStringScanInteger(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, Boolean doLonglong, void *result) {
     Boolean doingLonglong = false;     /* Set to true if doLonglong, and we overflow an int... */
     Boolean neg = false;
     int intResult = 0;
@@ -121,7 +121,7 @@ __private_extern__ Boolean __CFStringScanInteger(CFStringInlineBuffer *buf, CFTy
     return true;
 }
 
-__private_extern__ Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, unsigned *result) {
+CF_PRIVATE Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, unsigned *result) {
     UInt32 value = 0;
     SInt32 curDigit;
     UniChar ch;
@@ -175,7 +175,7 @@ static const unsigned char __CFNumberSet[16] = {
     0X00, // 0, 0, 0, 0, 0, 0, 0, 0  //  x   y   z   {   |   }   ~  del
 };
 
-__private_extern__ Boolean __CFStringScanDouble(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, double *resultPtr) {
+CF_PRIVATE Boolean __CFStringScanDouble(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, double *resultPtr) {
     #define STACK_BUFFER_SIZE 256
     #define ALLOC_CHUNK_SIZE 256 // first and subsequent malloc size.  Should be greater than STACK_BUFFER_SIZE
     char localCharBuffer[STACK_BUFFER_SIZE];
index 637326a5efa0c32ec5a8026975f877dc94bb9205..507b37de53df8906075f1a70cf74cbe9b5469d9a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringUtilities.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -111,6 +111,11 @@ CFStringEncoding CFStringConvertIANACharSetNameToEncoding(CFStringRef charsetNam
 #endif
     
 
+    // handling Java name variant for MS codepages
+    if ((kCFStringEncodingInvalidId == encoding) && !strncasecmp(name, "ms950", strlen("ms950"))) { // <rdar://problem/12903398> “MS950” is not recognized
+        encoding = __CFStringEncodingGetFromCanonicalName("cp950");
+    }
+    
     return encoding;
 }
 
@@ -556,7 +561,7 @@ static inline CFIndex __extendLocationForward(CFIndex location, CFStringInlineBu
     return location;
 }
 
-__private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale) {
+CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale) {
     const UniChar *characters1;
     const UniChar *characters2;
     CFComparisonResult compResult = kCFCompareEqualTo;
index 6efe1a2da537de65f909c1eae9961dc73681476e..51a2da7aeacc75b1609f34cfa30af45ca3c72d09 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFSystemDirectories.c
-       Copyright (c) 1997-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1997-2013, Apple Inc. All rights reserved.
        Responsibility: Kevin Perry
 */
 
@@ -43,6 +43,7 @@
 #include <libc.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <pwd.h>
 #include <NSSystemDirectories.h>
 
 CFSearchPathEnumerationState __CFStartSearchPathEnumeration(CFSearchPathDirectory dir, CFSearchPathDomainMask domainMask) {
@@ -104,6 +105,7 @@ CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directo
 
 #endif
 
+
 #undef numDirs
 #undef numApplicationDirs
 #undef numLibraryDirs
index 5e40803a231d944992bd6dc7205baabef6178f58..62460e2b866e89b0c0c006e218478dc9979f6237 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFTimeZone.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -479,7 +479,7 @@ static const CFRuntimeClass __CFTimeZoneClass = {
     __CFTimeZoneCopyDescription
 };
 
-__private_extern__ void __CFTimeZoneInitialize(void) {
+CF_PRIVATE void __CFTimeZoneInitialize(void) {
     __kCFTimeZoneTypeID = _CFRuntimeRegisterClass(&__CFTimeZoneClass);
 }
 
index c30f7c79f8689d5cbfd25862a0519ae17c9056d1..427272947b75e7a3400f60c4c291fa8531235dac 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFTimeZone.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFTIMEZONE__)
index dd08b99edcafe0ce40bbd1d86afbff0d6c13c653..1fe4f0ef2950980cb5c9bc10ede38cc4d38542d9 100644 (file)
--- a/CFTree.c
+++ b/CFTree.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFTree.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -97,7 +97,7 @@ static CFStringRef __CFTreeCopyDescription(CFTypeRef cf) {
     if (NULL == contextDesc) {
        contextDesc = CFStringCreateWithFormat(allocator, NULL, CFSTR("<CFTree context %p>"), tree->_info);
     }
-    CFStringAppendFormat(result, NULL, CFSTR("<CFTree %p [%p]>{children = %u, context = %@}"), cf, allocator, CFTreeGetChildCount(tree), contextDesc);
+    CFStringAppendFormat(result, NULL, CFSTR("<CFTree %p [%p]>{children = %lu, context = %@}"), cf, allocator, (unsigned long)CFTreeGetChildCount(tree), contextDesc);
     if (contextDesc) CFRelease(contextDesc);
     return result;
 }
@@ -136,7 +136,7 @@ static const CFRuntimeClass __CFTreeClass = {
     __CFTreeCopyDescription
 };
 
-__private_extern__ void __CFTreeInitialize(void) {
+CF_PRIVATE void __CFTreeInitialize(void) {
     __kCFTreeTypeID = _CFRuntimeRegisterClass(&__CFTreeClass);
 }
 
index 277eb1f97e64a9c066c3d73e51b40d11af3e6f03..41a21a6d6083da51a4c4a47f5e6cbef1c42106f8 100644 (file)
--- a/CFTree.h
+++ b/CFTree.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFTree.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 /*!
         @header CFTree
diff --git a/CFURL.c b/CFURL.c
index b15658c85552f6fe0d1b4fab705f8aea4c8abb5a..4407e3b0c1e23d2258c0da487e1d8a90e35b66c8 100644 (file)
--- a/CFURL.c
+++ b/CFURL.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFURL.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
 #include <unistd.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/syslog.h>
 #include <CoreFoundation/CFURLPriv.h>
 #endif
 
+#ifndef DEBUG_URL_MEMORY_USAGE
+// enables various statistical counters which can be displayed with __CFURLDumpMemRecord().
+#define DEBUG_URL_MEMORY_USAGE 0
+#endif
+
+#ifndef DEBUG_URL_INITIALIZER_LOGGING
+// enables logging in URL initializer. You get to see the inputs and output for each URL created.
+#define DEBUG_URL_INITIALIZER_LOGGING 0
+#endif
+
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 static CFArrayRef HFSPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir);
-static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir);
+static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute);
 #endif
-static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir);
-static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir);
-static CFStringRef POSIXPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDirectory);
+static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute);
+static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute);
+static CFStringRef POSIXPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDirectory, Boolean isAbsolute, Boolean *posixAndUrlPathsMatch);
+static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscapes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, Boolean isDirectory, Boolean isAbsolute, Boolean windowsPath, Boolean *addedPercentEncoding);
 CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLRef anURL, CFURLPathStyle fsType, Boolean resolveAgainstBase);
 CF_EXPORT CFURLRef _CFURLCreateCurrentDirectoryURL(CFAllocatorRef allocator);
 #if DEPLOYMENT_TARGET_MACOSX
@@ -62,18 +74,31 @@ static Boolean _CFURLHasFileURLScheme(CFURLRef url, Boolean *hasScheme);
 
 
 
-
-#ifndef DEBUG_URL_MEMORY_USAGE
-#define DEBUG_URL_MEMORY_USAGE 0
+// When __CONSTANT_CFSTRINGS__ is not defined, we have separate macros for static and exported constant strings, but
+// when it is defined, we must prefix with static to prevent the string from being exported
+#ifdef __CONSTANT_CFSTRINGS__
+static CONST_STRING_DECL(kCFURLHTTPScheme, "http")
+static CONST_STRING_DECL(kCFURLHTTPSScheme, "https")
+static CONST_STRING_DECL(kCFURLFileScheme, "file")
+static CONST_STRING_DECL(kCFURLDataScheme, "data")
+static CONST_STRING_DECL(kCFURLFTPScheme, "ftp")
+static CONST_STRING_DECL(kCFURLLocalhost, "localhost")
+#else
+CONST_STRING_DECL(kCFURLHTTPScheme, "http")
+CONST_STRING_DECL(kCFURLHTTPSScheme, "https")
+CONST_STRING_DECL(kCFURLFileScheme, "file")
+CONST_STRING_DECL(kCFURLDataScheme, "data")
+CONST_STRING_DECL(kCFURLFTPScheme, "ftp")
+CONST_STRING_DECL(kCFURLLocalhost, "localhost")
 #endif
 
 #if DEBUG_URL_MEMORY_USAGE
-static UInt32 numURLs = 0;
-static UInt32 numDealloced = 0;
-static UInt32 numFileURLsCreated = 0;
-static UInt32 numExtraDataAllocated = 0;
-static UInt32 numURLsWithBaseURL = 0;
-static UInt32 numNonUTF8EncodedURLs = 0;
+static uint numURLs = 0;                    // number of URLs allocated
+static uint numDealloced = 0;               // number of URLs deallocated
+static uint numFileURLsParsed = 0;          // number of URLs created from a string which had to be parsed
+static uint numExtraDataAllocated = 0;      // number of URLs with additional data -- either because URLHandle was used, or because a sanitizedString was needed
+static uint numURLsWithBaseURL = 0;         // number of URLs with a baseURL
+static uint numNonUTF8EncodedURLs = 0;      // number of URLs that don't have UTF8 encoding
 #endif
 
 /* The bit flags in myURL->_flags */
@@ -90,13 +115,11 @@ static UInt32 numNonUTF8EncodedURLs = 0;
 // various boolean flags
 #define IS_IPV6_ENCODED                 (0x00000400)
 #define IS_DIRECTORY                    (0x00000800)
-#define IS_CANONICAL_FILE_URL           (0x00001000)
+#define IS_CANONICAL_FILE_URL           (0x00001000) // if set, the URL is a file URL in the form "file://<absolute_percent_encoded_path>" (it was created from a file system path or representation)
 #define PATH_HAS_FILE_ID                (0x00002000)
-#define IS_ABSOLUTE                     (0x00004000)
-#define IS_DECOMPOSABLE                 (0x00008000)
-#define POSIX_AND_URL_PATHS_MATCH       (0x00010000) // POSIX_AND_URL_PATHS_MATCH will only be true if the URL path and the POSIX path are identical, character for character, except for the presence/absence of a trailing slash on directories
-#define ORIGINAL_AND_URL_STRINGS_MATCH  (0x00020000)
-#define USES_EIGHTBITSTRINGENCODING     (0x00040000)
+#define IS_DECOMPOSABLE                 (0x00004000)
+#define POSIX_AND_URL_PATHS_MATCH       (0x00008000) // POSIX_AND_URL_PATHS_MATCH will only be true if the URL path and the POSIX path are identical, character for character, except for the presence/absence of a trailing slash on directories
+#define ORIGINAL_AND_URL_STRINGS_MATCH  (0x00010000)
 // scheme bits and amount to shift it to translate to the kXXXXScheme enums
 #define SCHEME_TYPE_MASK                (0xE0000000)
 #define SCHEME_SHIFT                    29
@@ -117,10 +140,10 @@ CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType);
 #define NET_LOCATION_MASK (HAS_HOST | HAS_USER | HAS_PASSWORD | HAS_PORT)
 #define RESOURCE_SPECIFIER_MASK  (HAS_PARAMETERS | HAS_QUERY | HAS_FRAGMENT)
 // These flags can be compared for equality since these are all set once when the CFURL is created.
-// IS_CANONICAL_FILE_URL cannot be compared since we don't create the URL string.
+// IS_CANONICAL_FILE_URL cannot be compared since we don't always create the URL string.
 // POSIX_AND_URL_PATHS_MATCH cannot be compared because it may not be set
 // ORIGINAL_AND_URL_STRINGS_MATCH cannot be compared because it gets set on demand later.
-#define EQUAL_FLAGS_MASK (HAS_SCHEME | HAS_USER | HAS_PASSWORD | HAS_HOST | HAS_PORT | HAS_PATH | HAS_PARAMETERS | HAS_QUERY | HAS_FRAGMENT | IS_IPV6_ENCODED | IS_DIRECTORY | PATH_HAS_FILE_ID | IS_ABSOLUTE | IS_DECOMPOSABLE | SCHEME_TYPE_MASK )
+#define EQUAL_FLAGS_MASK (HAS_SCHEME | HAS_USER | HAS_PASSWORD | HAS_HOST | HAS_PORT | HAS_PATH | HAS_PARAMETERS | HAS_QUERY | HAS_FRAGMENT | IS_IPV6_ENCODED | IS_DIRECTORY | PATH_HAS_FILE_ID | IS_DECOMPOSABLE | SCHEME_TYPE_MASK )
 
 // The value of FULL_URL_REPRESENTATION must not be in the CFURLPathStyle enums. Also, its value is exposed via _CFURLCopyPropertyListRepresentation to the Finder so don't change it.  
 #define FULL_URL_REPRESENTATION (0xF)
@@ -143,9 +166,18 @@ CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType);
 #define FILE_ID_PREAMBLE_LENGTH 10
 
 #define FILE_PREFIX "file://"
+static const UInt8 fileURLPrefix[] = FILE_PREFIX;
+
+// FILE_PREFIX_WITH_AUTHORITY and fileURLPrefixWithAuthority are only needed because some code incorrectly expects file URLs to have a host of "localhost", so if the application is linked on or before OS X 10.9 or iOS 7.0, we add "localhost" to file path URLs we create.
 #define FILE_PREFIX_WITH_AUTHORITY "file://localhost"
 static const UInt8 fileURLPrefixWithAuthority[] = FILE_PREFIX_WITH_AUTHORITY;
 
+static Boolean AddAuthorityToFileURL(void)
+{
+    static Boolean result = false;
+    return ( result );
+}
+
 //     In order to reduce the sizeof ( __CFURL ), move these items into a seperate structure which is
 //     only allocated when necessary.  In my tests, it's almost never needed -- very rarely does a CFURL have
 //     either a sanitized string or a reserved pointer for URLHandle.
@@ -163,7 +195,7 @@ struct __CFURL {
     CFURLRef _base;
     CFRange *_ranges;
     struct _CFURLAdditionalData* _extra;
-    void *_resourceInfo;    // For use by CarbonCore to cache property values. Retained and released by CFURL.
+    void *_resourceInfo;    // For use by CoreServicesInternal to cache property values. Retained and released by CFURL.
 };
 
 
@@ -291,61 +323,7 @@ CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType)
     *flags = (*flags & ~SCHEME_TYPE_MASK) + (schemeType << SCHEME_SHIFT);
 }
 
-/* Returns whether the provided bytes can be stored in ASCII
- */
-static Boolean __CFBytesInASCII(const uint8_t *bytes, CFIndex len) {
-#if __LP64__
-    /* A bit of unrolling; go by 32s, 16s, and 8s first */
-    while (len >= 32) {
-        uint64_t val = *(const uint64_t *)bytes;
-        uint64_t hiBits = (val & 0x8080808080808080ULL);    // More efficient to collect this rather than do a conditional at every step
-        bytes += 8;
-        val = *(const uint64_t *)bytes;
-        hiBits |= (val & 0x8080808080808080ULL);
-        bytes += 8;
-        val = *(const uint64_t *)bytes;
-        hiBits |= (val & 0x8080808080808080ULL);
-        bytes += 8;
-        val = *(const uint64_t *)bytes;
-        if (hiBits | (val & 0x8080808080808080ULL)) return false;
-        bytes += 8;
-        len -= 32;
-    }
-    
-    while (len >= 16) {
-        uint64_t val = *(const uint64_t *)bytes;
-        uint64_t hiBits = (val & 0x8080808080808080ULL);
-        bytes += 8;
-        val = *(const uint64_t *)bytes;
-        if (hiBits | (val & 0x8080808080808080ULL)) return false;
-        bytes += 8;
-        len -= 16;
-    }
-    
-    while (len >= 8) {
-        uint64_t val = *(const uint64_t *)bytes;
-        if (val & 0x8080808080808080ULL) return false;
-        bytes += 8;
-        len -= 8;
-    }
-#endif
-    /* Go by 4s */
-    while (len >= 4) {
-        uint32_t val = *(const uint32_t *)bytes;
-        if (val & 0x80808080U) return false;
-        bytes += 4;
-        len -= 4;
-    }
-    /* Handle the rest one byte at a time */
-    while (len--) {
-        if (*bytes++ & 0x80) return false;
-    }
-    
-    return true;
-}
-
 static Boolean _pathHasFileIDPrefix(CFStringRef path);
-static void _convertToURLRepresentation(struct __CFURL *url, UInt32 fsType);
 static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef basePath, Boolean baseIsDir, CFURLPathStyle fsType, CFAllocatorRef alloc);
 static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef base, UInt32 *flags, CFRange **range);
 static CFRange _rangeForComponent(UInt32 flags, CFRange *ranges, UInt32 compFlag);
@@ -363,7 +341,7 @@ CF_INLINE void _parseComponentsOfURL(CFURLRef url) {
 
 enum {
        VALID = 1,
-       UNRESERVED = 2,
+       ALPHA = 2,
        PATHVALID = 4,
        SCHEME = 8,
        HEXDIGIT = 16
@@ -403,31 +381,31 @@ static const unsigned char sURLValidCharacters[128] = {
     /* rs   30 */   0,
     /* us   31 */   0,
     /* sp   32 */   0,
-    /* '!'  33 */   VALID | UNRESERVED | PATHVALID ,
+    /* '!'  33 */   VALID | PATHVALID ,
     /* '"'  34 */   0,
     /* '#'  35 */   0,
     /* '$'  36 */   VALID | PATHVALID ,
     /* '%'  37 */   0,
     /* '&'  38 */   VALID | PATHVALID ,
-    /* '''  39 */   VALID | UNRESERVED | PATHVALID ,
-    /* '('  40 */   VALID | UNRESERVED | PATHVALID ,
-    /* ')'  41 */   VALID | UNRESERVED | PATHVALID ,
-    /* '*'  42 */   VALID | UNRESERVED | PATHVALID ,
+    /* '''  39 */   VALID | PATHVALID ,
+    /* '('  40 */   VALID | PATHVALID ,
+    /* ')'  41 */   VALID | PATHVALID ,
+    /* '*'  42 */   VALID | PATHVALID ,
     /* '+'  43 */   VALID | SCHEME | PATHVALID ,
     /* ','  44 */   VALID | PATHVALID ,
-    /* '-'  45 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* '.'  46 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
+    /* '-'  45 */   VALID | SCHEME | PATHVALID ,
+    /* '.'  46 */   VALID | SCHEME | PATHVALID ,
     /* '/'  47 */   VALID | PATHVALID ,
-    /* '0'  48 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '1'  49 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '2'  50 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '3'  51 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '4'  52 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '5'  53 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '6'  54 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '7'  55 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '8'  56 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* '9'  57 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '0'  48 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '1'  49 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '2'  50 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '3'  51 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '4'  52 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '5'  53 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '6'  54 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '7'  55 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '8'  56 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
+    /* '9'  57 */   VALID | SCHEME | PATHVALID | HEXDIGIT ,
     /* ':'  58 */   VALID ,
     /* ';'  59 */   VALID ,
     /* '<'  60 */   0,
@@ -435,90 +413,89 @@ static const unsigned char sURLValidCharacters[128] = {
     /* '>'  62 */   0,
     /* '?'  63 */   VALID ,
     /* '@'  64 */   VALID ,
-    /* 'A'  65 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'B'  66 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'C'  67 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'D'  68 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'E'  69 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'F'  70 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'G'  71 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'H'  72 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'I'  73 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'J'  74 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'K'  75 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'L'  76 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'M'  77 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'N'  78 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'O'  79 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'P'  80 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'Q'  81 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'R'  82 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'S'  83 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'T'  84 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'U'  85 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'V'  86 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'W'  87 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'X'  88 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'Y'  89 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'Z'  90 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
+    /* 'A'  65 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'B'  66 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'C'  67 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'D'  68 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'E'  69 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'F'  70 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'G'  71 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'H'  72 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'I'  73 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'J'  74 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'K'  75 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'L'  76 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'M'  77 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'N'  78 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'O'  79 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'P'  80 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'Q'  81 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'R'  82 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'S'  83 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'T'  84 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'U'  85 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'V'  86 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'W'  87 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'X'  88 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'Y'  89 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'Z'  90 */   VALID | ALPHA | SCHEME | PATHVALID ,
     /* '['  91 */   0,
     /* '\'  92 */   0,
     /* ']'  93 */   0,
     /* '^'  94 */   0,
-    /* '_'  95 */   VALID | UNRESERVED | PATHVALID ,
+    /* '_'  95 */   VALID | PATHVALID ,
     /* '`'  96 */   0,
-    /* 'a'  97 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'b'  98 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'c'  99 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'd' 100 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'e' 101 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'f' 102 */   VALID | UNRESERVED | SCHEME | PATHVALID | HEXDIGIT ,
-    /* 'g' 103 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'h' 104 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'i' 105 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'j' 106 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'k' 107 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'l' 108 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'm' 109 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'n' 110 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'o' 111 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'p' 112 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'q' 113 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'r' 114 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 's' 115 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 't' 116 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'u' 117 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'v' 118 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'w' 119 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'x' 120 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'y' 121 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-    /* 'z' 122 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
+    /* 'a'  97 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'b'  98 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'c'  99 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'd' 100 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'e' 101 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'f' 102 */   VALID | ALPHA | SCHEME | PATHVALID | HEXDIGIT ,
+    /* 'g' 103 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'h' 104 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'i' 105 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'j' 106 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'k' 107 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'l' 108 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'm' 109 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'n' 110 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'o' 111 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'p' 112 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'q' 113 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'r' 114 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 's' 115 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 't' 116 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'u' 117 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'v' 118 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'w' 119 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'x' 120 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'y' 121 */   VALID | ALPHA | SCHEME | PATHVALID ,
+    /* 'z' 122 */   VALID | ALPHA | SCHEME | PATHVALID ,
     /* '{' 123 */   0,
     /* '|' 124 */   0,
     /* '}' 125 */   0,
-    /* '~' 126 */   VALID | UNRESERVED | PATHVALID ,
+    /* '~' 126 */   VALID | PATHVALID ,
     /* del 127 */   0,
 };
 
 CF_INLINE Boolean isURLLegalCharacter(UniChar ch) {
-    return (ch <= 127) ? (sURLValidCharacters[ch] & VALID) : false;
+    return (ch <= 127) ? ((sURLValidCharacters[ch] & VALID) != 0) : false;
 }
 
 CF_INLINE Boolean scheme_valid(UniChar ch) {
-    return (ch <= 127) ? (sURLValidCharacters[ch] & SCHEME) : false;
+    return (ch <= 127) ? ((sURLValidCharacters[ch] & SCHEME) != 0) : false;
 }
 
-// "Unreserved" as defined by RFC 2396
-CF_INLINE Boolean isUnreservedCharacter(UniChar ch) {
-    return (ch <= 127) ? (sURLValidCharacters[ch] & UNRESERVED) : false;
+CF_INLINE Boolean isALPHA(UniChar ch) {
+    return (ch <= 127) ? ((sURLValidCharacters[ch] & ALPHA) != 0) : false;
 }
 
 CF_INLINE Boolean isPathLegalCharacter(UniChar ch) {
-    return (ch <= 127) ? (sURLValidCharacters[ch] & PATHVALID) : false;
+    return (ch <= 127) ? ((sURLValidCharacters[ch] & PATHVALID) != 0) : false;
 }
 
 CF_INLINE Boolean isHexDigit(UniChar ch) {
-    return (ch <= 127) ? (sURLValidCharacters[ch] & HEXDIGIT) : false;
+    return (ch <= 127) ? ((sURLValidCharacters[ch] & HEXDIGIT) != 0) : false;
 }
 
 // Returns false if ch1 or ch2 isn't properly formatted
@@ -542,9 +519,278 @@ CF_INLINE Boolean _haveTestedOriginalString(CFURLRef url) {
     return ((url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) != 0) || (_getSanitizedString(url) != NULL);
 }
 
+enum {
+    IS_PCHAR = 0x01,
+};
+
+static const unsigned char sURLValidBytes[256] = {
+    /* nul   0 */   0,
+    /* soh   1 */   0,
+    /* stx   2 */   0,
+    /* etx   3 */   0,
+    /* eot   4 */   0,
+    /* enq   5 */   0,
+    /* ack   6 */   0,
+    /* bel   7 */   0,
+    /* bs    8 */   0,
+    /* ht    9 */   0,
+    /* nl   10 */   0,
+    /* vt   11 */   0,
+    /* np   12 */   0,
+    /* cr   13 */   0,
+    /* so   14 */   0,
+    /* si   15 */   0,
+    /* dle  16 */   0,
+    /* dc1  17 */   0,
+    /* dc2  18 */   0,
+    /* dc3  19 */   0,
+    /* dc4  20 */   0,
+    /* nak  21 */   0,
+    /* syn  22 */   0,
+    /* etb  23 */   0,
+    /* can  24 */   0,
+    /* em   25 */   0,
+    /* sub  26 */   0,
+    /* esc  27 */   0,
+    /* fs   28 */   0,
+    /* gs   29 */   0,
+    /* rs   30 */   0,
+    /* us   31 */   0,
+    /* sp   32 */   0,
+    /* '!'  33 */   IS_PCHAR,
+    /* '"'  34 */   0,
+    /* '#'  35 */   0,
+    /* '$'  36 */   IS_PCHAR,
+    /* '%'  37 */   0,
+    /* '&'  38 */   IS_PCHAR,
+    /* '''  39 */   IS_PCHAR,
+    /* '('  40 */   IS_PCHAR,
+    /* ')'  41 */   IS_PCHAR,
+    /* '*'  42 */   IS_PCHAR,
+    /* '+'  43 */   IS_PCHAR,
+    /* ','  44 */   IS_PCHAR,
+    /* '-'  45 */   IS_PCHAR,
+    /* '.'  46 */   IS_PCHAR,
+    /* '/'  47 */   IS_PCHAR,   // not really a pchar -- it's the segment delimiter
+    /* '0'  48 */   IS_PCHAR,
+    /* '1'  49 */   IS_PCHAR,
+    /* '2'  50 */   IS_PCHAR,
+    /* '3'  51 */   IS_PCHAR,
+    /* '4'  52 */   IS_PCHAR,
+    /* '5'  53 */   IS_PCHAR,
+    /* '6'  54 */   IS_PCHAR,
+    /* '7'  55 */   IS_PCHAR,
+    /* '8'  56 */   IS_PCHAR,
+    /* '9'  57 */   IS_PCHAR,
+    /* ':'  58 */   IS_PCHAR,
+    /* ';'  59 */   0,          // we need to percent-escape ';' in file system paths so it won't be mistaken for the start of the obsolete param rule (rfc2396) that CFURL still supports
+    /* '<'  60 */   0,
+    /* '='  61 */   IS_PCHAR,
+    /* '>'  62 */   0,
+    /* '?'  63 */   0,
+    /* '@'  64 */   IS_PCHAR,
+    /* 'A'  65 */   IS_PCHAR,
+    /* 'B'  66 */   IS_PCHAR,
+    /* 'C'  67 */   IS_PCHAR,
+    /* 'D'  68 */   IS_PCHAR,
+    /* 'E'  69 */   IS_PCHAR,
+    /* 'F'  70 */   IS_PCHAR,
+    /* 'G'  71 */   IS_PCHAR,
+    /* 'H'  72 */   IS_PCHAR,
+    /* 'I'  73 */   IS_PCHAR,
+    /* 'J'  74 */   IS_PCHAR,
+    /* 'K'  75 */   IS_PCHAR,
+    /* 'L'  76 */   IS_PCHAR,
+    /* 'M'  77 */   IS_PCHAR,
+    /* 'N'  78 */   IS_PCHAR,
+    /* 'O'  79 */   IS_PCHAR,
+    /* 'P'  80 */   IS_PCHAR,
+    /* 'Q'  81 */   IS_PCHAR,
+    /* 'R'  82 */   IS_PCHAR,
+    /* 'S'  83 */   IS_PCHAR,
+    /* 'T'  84 */   IS_PCHAR,
+    /* 'U'  85 */   IS_PCHAR,
+    /* 'V'  86 */   IS_PCHAR,
+    /* 'W'  87 */   IS_PCHAR,
+    /* 'X'  88 */   IS_PCHAR,
+    /* 'Y'  89 */   IS_PCHAR,
+    /* 'Z'  90 */   IS_PCHAR,
+    /* '['  91 */   0,
+    /* '\'  92 */   0,
+    /* ']'  93 */   0,
+    /* '^'  94 */   0,
+    /* '_'  95 */   IS_PCHAR,
+    /* '`'  96 */   0,
+    /* 'a'  97 */   IS_PCHAR,
+    /* 'b'  98 */   IS_PCHAR,
+    /* 'c'  99 */   IS_PCHAR,
+    /* 'd' 100 */   IS_PCHAR,
+    /* 'e' 101 */   IS_PCHAR,
+    /* 'f' 102 */   IS_PCHAR,
+    /* 'g' 103 */   IS_PCHAR,
+    /* 'h' 104 */   IS_PCHAR,
+    /* 'i' 105 */   IS_PCHAR,
+    /* 'j' 106 */   IS_PCHAR,
+    /* 'k' 107 */   IS_PCHAR,
+    /* 'l' 108 */   IS_PCHAR,
+    /* 'm' 109 */   IS_PCHAR,
+    /* 'n' 110 */   IS_PCHAR,
+    /* 'o' 111 */   IS_PCHAR,
+    /* 'p' 112 */   IS_PCHAR,
+    /* 'q' 113 */   IS_PCHAR,
+    /* 'r' 114 */   IS_PCHAR,
+    /* 's' 115 */   IS_PCHAR,
+    /* 't' 116 */   IS_PCHAR,
+    /* 'u' 117 */   IS_PCHAR,
+    /* 'v' 118 */   IS_PCHAR,
+    /* 'w' 119 */   IS_PCHAR,
+    /* 'x' 120 */   IS_PCHAR,
+    /* 'y' 121 */   IS_PCHAR,
+    /* 'z' 122 */   IS_PCHAR,
+    /* '{' 123 */   0,
+    /* '|' 124 */   0,
+    /* '}' 125 */   0,
+    /* '~' 126 */   IS_PCHAR,
+    /* del 127 */   0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+                    0,
+};
+
+CF_INLINE Boolean is_pchar(unsigned char ch) {
+    return ( (sURLValidBytes[ch] & IS_PCHAR) != 0 );
+}
+
+
 /*
  CreateStringFromFileSystemRepresentationByAddingPercentEscapes creates a CFString
  for the path-absolute form of a URI path component from the native file system representation.
+ Note: this code uses '/' path separators
  
  The rules for path-absolute from rfc3986 are:
  path-absolute = "/" [ segment-nz *( "/" segment ) ]
@@ -555,85 +801,105 @@ CF_INLINE Boolean _haveTestedOriginalString(CFURLRef url) {
  unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
  sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
  */
-static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscapes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, Boolean windowsPath)
+static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscapes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, Boolean isDirectory, Boolean isAbsolute, Boolean windowsPath, Boolean *addedPercentEncoding)
 {
     static const UInt8 hexchars[] = "0123456789ABCDEF";
-    STACK_BUFFER_DECL(UInt8, stackBuf, PATH_MAX * 3);   // worst case is every byte needs to be percent-escaped
+    const UInt8 *fileURLPrefixPtr;
+    size_t fileURLPrefixLength;
+    if ( AddAuthorityToFileURL() ) {
+        fileURLPrefixPtr = fileURLPrefixWithAuthority;
+        fileURLPrefixLength = sizeof(fileURLPrefixWithAuthority);
+    }
+    else {
+        fileURLPrefixPtr = fileURLPrefix;
+        fileURLPrefixLength = sizeof(fileURLPrefix);
+    }
+    STACK_BUFFER_DECL(UInt8, stackBuf, (PATH_MAX * 3) + (isAbsolute ? fileURLPrefixLength : 0) + (isDirectory ? 1 : 0)); // worst case is every byte needs to be percent-escaped
     UInt8 *bufStartPtr;
     UInt8 *bufBytePtr;
     const UInt8 *bytePtr = bytes;
     CFIndex idx;
     CFStringRef result;
+    Boolean addedPercent = FALSE;
    
     // choose a buffer to percent-escape into.
     if ( numBytes <= PATH_MAX ) {
         bufStartPtr = &stackBuf[0];
     }
     else {
-        // worst case is every byte needs to be percent-escaped (numBytes * 3)
-        bufStartPtr = (UInt8 *)malloc(numBytes * 3);
+        // worst case is every byte needs to be percent-escaped
+        bufStartPtr = (UInt8 *)malloc((numBytes * 3) + (isAbsolute ? fileURLPrefixLength : 0) + (isDirectory ? 1 : 0));
     }
     
     if ( bufStartPtr != NULL ) {
-        bufBytePtr = bufStartPtr;
-        for ( idx = 0; (idx < numBytes) && (*bytePtr != 0); ++idx ) {
-            switch ( *bytePtr ) {
-                    // these are the visible 7-bit ascii characters that are not legal pchar octets
-                case '"':
-                case '#':
-                case '%':
-                case ';':      // we need to percent-escape ';' in file system paths so it won't be mistaken for the start of the obsolete param rule (rfc2396) that CFURL still supports
-                case '<':
-                case '>':
-                case '?':      // we need to percent-escape '?' in file system paths so it won't be mistaken for the start of a query
-                case '[':
-                case '\\':
-                case ']':
-                case '^':
-                case '`':
-                case '{':
-                case '|':
-                case '}':
-                    // percent-escape non-pchar octets spread throughout the visible 7-bit ascii range
+        if ( isAbsolute ) {
+            // start with the fileURLPrefix
+            strcpy((char *)bufStartPtr, (char *)fileURLPrefixPtr);
+            bufBytePtr = bufStartPtr + fileURLPrefixLength - 1;
+        }
+        else {
+            bufBytePtr = bufStartPtr;
+        }
+        
+        if ( !windowsPath ) {
+            for ( idx = 0; (idx < numBytes) && (*bytePtr != 0); ++idx ) {
+                if ( is_pchar(*bytePtr) ) {
+                    *bufBytePtr++ = *bytePtr;
+                }
+                else {
                     *bufBytePtr++ = '%';
                     *bufBytePtr++ = hexchars[*bytePtr >> 4];
                     *bufBytePtr++ = hexchars[*bytePtr & 0x0f];
-                    break;
-                default:
-                    if ( (*bytePtr <= ' ') ||  // percent-escape non-pchar octets that are space or less (control characters)
-                        (*bytePtr >= 0x7f) ||  // percent-escape non-pchar octets that del and 8-bit ascii with the high bit set
-                        (windowsPath && (*bytePtr == '/')) ) { // percent-escape the forward slash if this is a windowsPath
-                        *bufBytePtr++ = '%';
-                        *bufBytePtr++ = hexchars[*bytePtr >> 4];
-                        *bufBytePtr++ = hexchars[*bytePtr & 0x0f];
-                    }
-                    else {
-                        // copy everything else
-                        *bufBytePtr++ = *bytePtr;
-                    }
-                    break;
+                    addedPercent = TRUE;
+                }
+                ++bytePtr;
+            }
+        }
+        else {
+            for ( idx = 0; (idx < numBytes) && (*bytePtr != 0); ++idx ) {
+                if ( is_pchar(*bytePtr) && (*bytePtr != '/') ) {    // percent-escape the forward slash if this is a windowsPath
+                    *bufBytePtr++ = *bytePtr;
+                }
+                else {
+                    *bufBytePtr++ = '%';
+                    *bufBytePtr++ = hexchars[*bytePtr >> 4];
+                    *bufBytePtr++ = hexchars[*bytePtr & 0x0f];
+                    addedPercent = TRUE;
+                }
+                ++bytePtr;
             }
-            ++bytePtr;
         }
         
         // did we convert numBytes?
-        if ( idx == numBytes ) {
-            // create the result
-            result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), kCFStringEncodingUTF8, FALSE);
-        }
-        else {
+        if ( idx != numBytes ) {
             // no, but it's OK if the remaining bytes are all nul (embedded nul bytes are not allowed)
-            for ( /* start where we left off */; (idx < numBytes) && (bufStartPtr[idx] == 0); ++idx ) {
+            const UInt8 *nullBytePtr = bytePtr;
+            for ( /* start where we left off */; (idx < numBytes) && (*nullBytePtr == '\0'); ++idx, ++nullBytePtr ) {
                 // do nothing
             }
-            if ( idx == numBytes ) {
-                // create the result
-                result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), kCFStringEncodingUTF8, FALSE);
+        }
+        
+        if ( idx == numBytes ) {
+            if ( isDirectory ) {
+                // if it is a directory and it doesn't end with PATH_SEP, append a PATH_SEP.
+                if ( bytes[numBytes-1] != '/' ) {
+                    *bufBytePtr++ = '/';
+                }
             }
             else {
-                // the remaining bytes were not all nul
-                result = NULL;
+                // it is not a directory: remove any pathDelim characters at end (leaving at least one character)
+                while ( (numBytes > 1) && (bytes[numBytes-1] == '/') ) {
+                    --bufBytePtr;
+                    --numBytes;
+                }
             }
+            
+            // create the result
+            result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), kCFStringEncodingUTF8, FALSE);
+        }
+        else {
+            // the remaining bytes were not all nul
+            result = NULL;
         }
         
         // free the buffer if we malloc'd it
@@ -644,6 +910,11 @@ static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscape
     else {
         result = NULL;
     }
+
+    if ( addedPercentEncoding ) {
+        *addedPercentEncoding = addedPercent;
+    }
+    
     return ( result );
 }
 
@@ -652,34 +923,11 @@ CF_INLINE CFStringRef _replacePathIllegalCharacters(CFStringRef str, CFAllocator
     CFStringRef result = NULL;
     STACK_BUFFER_DECL(char, buffer, PATH_MAX);
     if ( CFStringGetCString(str, buffer, PATH_MAX, kCFStringEncodingUTF8) ) {
-        result = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)buffer, strlen(buffer), !preserveSlashes);
+        result = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)buffer, strlen(buffer), FALSE, FALSE, !preserveSlashes, NULL);
     }
     return result;
 }
 
-// We have 2 UniChars of a surrogate; we must convert to the correct percent-encoded UTF8 string and append to str.  Added so that file system URLs can always be converted from POSIX to full URL representation.  -- REW, 8/20/2001
-static Boolean _hackToConvertSurrogates(UniChar highChar, UniChar lowChar, CFMutableStringRef str) {
-    UniChar surrogate[2];
-    uint8_t bytes[6]; // Aki sez it should never take more than 6 bytes
-    CFIndex len; 
-    uint8_t *currByte;
-    surrogate[0] = highChar;
-    surrogate[1] = lowChar;
-    if (CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8, 0, surrogate, 2, NULL, bytes, 6, &len) != kCFStringEncodingConversionSuccess) {
-        return false;
-    }
-    for (currByte = bytes; currByte < bytes + len; currByte ++) {
-        UniChar escapeSequence[3] = {'%', '\0', '\0'};
-        unsigned char high, low;
-        high = ((*currByte) & 0xf0) >> 4;
-        low = (*currByte) & 0x0f;
-        escapeSequence[1] = (high < 10) ? '0' + high : 'A' + high - 10;
-        escapeSequence[2] = (low < 10) ? '0' + low : 'A' + low - 10;
-        CFStringAppendCharacters(str, escapeSequence, 3);
-    }
-    return true;
-}
-
 static Boolean _appendPercentEscapesForCharacter(UniChar ch, CFStringEncoding encoding, CFMutableStringRef str) {
     uint8_t bytes[6]; // 6 bytes is the maximum a single character could require in UTF8 (most common case); other encodings could require more
     uint8_t *bytePtr = bytes, *currByte;
@@ -713,6 +961,116 @@ static Boolean _appendPercentEscapesForCharacter(UniChar ch, CFStringEncoding en
     return true;
 }
 
+static CFStringRef UnescapeAllWithUTF8(CFAllocatorRef alloc, CFStringRef originalString)
+{
+    CFStringRef result = NULL;
+    CFIndex strLength = CFStringGetLength(originalString);
+    CFIndex maxBufferSize = CFStringGetMaximumSizeForEncoding(strLength, kCFStringEncodingUTF8);
+    CFIndex stackBufferSize = 2096;
+    STACK_BUFFER_DECL(UInt8, escapedStackBuf, stackBufferSize *2);
+    UInt8 *escapedBuf;
+    UInt8 *unescapedBuf;
+    // choose a buffer to percent-escape into.
+    if ( maxBufferSize <= stackBufferSize ) {
+        escapedBuf = &escapedStackBuf[0];
+    }
+    else {
+        escapedBuf = (UInt8 *)malloc(maxBufferSize * 2);
+    }
+    if ( escapedBuf ) {
+        CFIndex charsConverted;
+        CFIndex usedBufLen;
+        unescapedBuf = &escapedBuf[maxBufferSize];
+        charsConverted = CFStringGetBytes(originalString, CFRangeMake(0, strLength), kCFStringEncodingUTF8, 0, false, escapedBuf, maxBufferSize, &usedBufLen);
+        if ( charsConverted ) {
+            // 0x80 marks invalid hex digits so this table can validate the digits while getting the values
+            static const UInt8 hexvalues[] = {
+               /* 00 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 08 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 10 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 18 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 20 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 28 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 30 */  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+               /* 38 */  0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 40 */  0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80,
+               /* 48 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 50 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 58 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 60 */  0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80,
+               /* 68 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 70 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 78 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               
+               /* 80 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 88 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 90 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* 98 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* A0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* A8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* B0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* B8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* C0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* C8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* D0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* D8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* E0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* E8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* F0 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+               /* F8 */  0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+            };
+            UInt8 *bufStartPtr;
+            UInt8 *bufPtr;
+            const UInt8 *bytePtr = escapedBuf;
+            CFIndex idx;
+            
+            bufPtr = bufStartPtr = unescapedBuf;
+            Boolean conversionOK = TRUE;
+            
+            for ( idx = 0; (idx < usedBufLen) && conversionOK; ++idx ) {
+                switch ( *bytePtr ) {
+                    case '%':
+                        idx += 2;
+                        if ( idx < usedBufLen ) {
+                            UInt8 hex1, hex2;
+                            // skip over %
+                            bytePtr++;
+                            // get the hex digits
+                            hex1 = hexvalues[*bytePtr++];
+                            hex2 = hexvalues[*bytePtr++];
+                            // validate them
+                            if ( ((hex1 | hex2) & 0x80) == 0 ) {
+                                // convert hex digits
+                                *bufPtr = (hex1 << 4) + hex2;
+                            }
+                            else {
+                                conversionOK = FALSE;
+                            }
+                        }
+                        else {
+                            conversionOK = FALSE;
+                        }
+                        break;
+                    default:
+                        // copy everything else
+                        *bufPtr = *bytePtr++;
+                        break;
+                }
+                ++bufPtr;
+            }
+            if ( conversionOK ) {
+                result = CFStringCreateWithBytes(alloc, unescapedBuf, bufPtr - bufStartPtr, kCFStringEncodingUTF8, false);
+            }
+        }
+        
+        // free the buffer if we malloc'd it
+        if ( escapedBuf != &escapedStackBuf[0] ) {
+            free(escapedBuf);
+        }
+    }
+    return ( result );
+}
+
 // Uses UTF-8 to translate all percent escape sequences; returns NULL if it encounters a format failure.  May return the original string.
 CFStringRef  CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef alloc, CFStringRef  originalString, CFStringRef  charactersToLeaveEscaped) {
     CFMutableStringRef newStr = NULL;
@@ -726,12 +1084,17 @@ CFStringRef  CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef alloc, CF
     Boolean failed = false;
     
     if (!originalString) return NULL;
-
-    if (charactersToLeaveEscaped == NULL) {
+    
+    length = CFStringGetLength(originalString);
+    
+    if ((length == 0) || (charactersToLeaveEscaped == NULL)) {
         return (CFStringRef)CFStringCreateCopy(alloc, originalString);
     }
-
-    length = CFStringGetLength(originalString);
+    
+    if ( escapeAll ) {
+        return ( UnescapeAllWithUTF8(alloc, originalString) );
+    }
+       
     searchRange = CFRangeMake(0, length);
 
     while (!failed && CFStringFindWithOptions(originalString, CFSTR("%"), searchRange, 0, &percentRange)) {
@@ -775,6 +1138,7 @@ CFStringRef  CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef alloc, CF
                 if (!_translateBytes(ch1, ch2, bytes+j)) { failed = true; break; }
             }
 
+            // FIXME: This uses about 1/3 of the time spent in CFURLCreateStringByReplacingPercentEscapes
             // !!! We should do the low-level bit-twiddling ourselves; this is expensive!  REW, 6/10/99
             escapedStr = CFStringCreateWithBytes(alloc, bytes, numBytesExpected, kCFStringEncodingUTF8, false);
             if (!escapedStr) {
@@ -809,7 +1173,7 @@ CFStringRef  CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef alloc, CF
             newStr = CFStringCreateMutable(alloc, length);
         }
         if (percentRange.location - mark > 0) {
-            // The creation of this temporary string is unfortunate. 
+            // FIXME: The creation of this temporary string is unfortunate.
             CFStringRef substring = CFStringCreateWithSubstring(alloc, originalString, CFRangeMake(mark, percentRange.location - mark));
             CFStringAppend(newStr, substring);
             CFRelease(substring);
@@ -910,7 +1274,7 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorR
                 newStr = CFStringCreateMutable(alloc, length);
             }
             if (percentRange.location - mark > 0) {
-                // The creation of this temporary string is unfortunate. 
+                // FIXME: The creation of this temporary string is unfortunate.
                 CFStringRef substring = CFStringCreateWithSubstring(alloc, originalString, CFRangeMake(mark, percentRange.location - mark));
                 CFStringAppend(newStr, substring);
                 CFRelease(substring);
@@ -956,11 +1320,24 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorR
     }
 }
     
+static Boolean _stringContainsCharacter(CFStringRef string, UniChar ch) {
+    CFIndex i, c = CFStringGetLength(string);
+    CFStringInlineBuffer buf;
+    CFStringInitInlineBuffer(string, &buf, CFRangeMake(0, c));
+    for (i = 0; i < c; i ++) if (__CFStringGetCharacterFromInlineBufferQuick(&buf, i) == ch) return true;
+    return false;
+}
 
-static CFStringRef _addPercentEscapesToString(CFAllocatorRef allocator, CFStringRef originalString, Boolean (*shouldReplaceChar)(UniChar, void*), CFIndex (*handlePercentChar)(CFIndex, CFStringRef, CFStringRef *, void *), CFStringEncoding encoding, void *context) {
+// Note: charactersToLeaveUnescaped and legalURLCharactersToBeEscaped only work for characters which can be represented as a single UTF16 codepoint.
+CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) {
     CFMutableStringRef newString = NULL;
     CFIndex idx, length;
     CFStringInlineBuffer buf;
+    enum {
+        kCharBufferMax = 4096,
+    };
+    STACK_BUFFER_DECL(UniChar, charBuffer, kCharBufferMax);
+    CFIndex charBufferIndex = 0;
 
     if (!originalString) return NULL;
     length = CFStringGetLength(originalString);
@@ -968,99 +1345,100 @@ static CFStringRef _addPercentEscapesToString(CFAllocatorRef allocator, CFString
     CFStringInitInlineBuffer(originalString, &buf, CFRangeMake(0, length));
 
     for (idx = 0; idx < length; idx ++) {
-        UniChar ch = CFStringGetCharacterFromInlineBuffer(&buf, idx);
-        Boolean shouldReplace = shouldReplaceChar(ch, context);
+        UniChar ch = __CFStringGetCharacterFromInlineBufferQuick(&buf, idx);
+        Boolean shouldReplace = (isURLLegalCharacter(ch) == false);
+        if (shouldReplace) {
+            if (charactersToLeaveUnescaped && _stringContainsCharacter(charactersToLeaveUnescaped, ch)) {
+                shouldReplace = false;
+            }
+        } else if (legalURLCharactersToBeEscaped && _stringContainsCharacter(legalURLCharactersToBeEscaped, ch)) {
+            shouldReplace = true;
+        }
+        
         if (shouldReplace) {
+            enum {
+                kMaxBytesPerUniChar = 8,    // 8 bytes is the maximum a single UniChar can require in any current encodings; future encodings could require more
+                kMaxPercentEncodedUniChars = kMaxBytesPerUniChar * 3
+            };
+            
+            static const UInt8 hexchars[] = "0123456789ABCDEF";
+            uint8_t bytes[kMaxBytesPerUniChar];
+            uint8_t *bytePtr = bytes;
+            uint8_t *currByte;
+            uint8_t *endPtr;
+            CFIndex byteLength;
+
             // Perform the replacement
-            if (!newString) {
+            if ( !newString ) {
                 newString = CFStringCreateMutableCopy(CFGetAllocator(originalString), 0, originalString);
                 CFStringDelete(newString, CFRangeMake(idx, length-idx));
             }
-            if (!_appendPercentEscapesForCharacter(ch, encoding, newString)) {
-//#warning FIXME - once CFString supports finding glyph boundaries walk by glyph boundaries instead of by unichars
-                if (encoding == kCFStringEncodingUTF8 && CFCharacterSetIsSurrogateHighCharacter(ch) && idx + 1 < length && CFCharacterSetIsSurrogateLowCharacter(CFStringGetCharacterFromInlineBuffer(&buf, idx+1))) {
-                    // Hack to guarantee we always safely convert file URLs between POSIX & full URL representation
-                    if (_hackToConvertSurrogates(ch, CFStringGetCharacterFromInlineBuffer(&buf, idx+1), newString)) {
-                        idx ++; // We consumed 2 characters, not 1
-                    } else {
+            // make sure charBuffer has enough room
+            if ( charBufferIndex >= (kCharBufferMax - kMaxPercentEncodedUniChars) ) {
+                // make room
+                CFStringAppendCharacters(newString, charBuffer, charBufferIndex);
+                charBufferIndex = 0;
+            }
+            
+            // convert the UniChar to bytes
+            if ( CFStringEncodingUnicodeToBytes(encoding, 0, &ch, 1, NULL, bytePtr, 8, &byteLength) == kCFStringEncodingConversionSuccess ) {
+                // percent-encode the bytes
+                endPtr = bytePtr + byteLength;
+                for ( currByte = bytePtr; currByte < endPtr; currByte++ ) {
+                    charBuffer[charBufferIndex++] = '%';
+                    charBuffer[charBufferIndex++] = hexchars[*currByte >> 4];
+                    charBuffer[charBufferIndex++] = hexchars[*currByte & 0x0f];
+                }
+            }
+            else {
+                // FIXME: once CFString supports finding glyph boundaries walk by glyph boundaries instead of by unichars
+                if ( encoding == kCFStringEncodingUTF8 && CFCharacterSetIsSurrogateHighCharacter(ch) && idx + 1 < length && CFCharacterSetIsSurrogateLowCharacter(__CFStringGetCharacterFromInlineBufferQuick(&buf, idx+1)) ) {
+                    UniChar surrogate[2];
+                    uint8_t *currByte;
+                    
+                    surrogate[0] = ch;
+                    surrogate[1] = __CFStringGetCharacterFromInlineBufferQuick(&buf, idx+1);
+                    // Aki sez it should never take more than 6 bytes
+                    if (CFStringEncodingUnicodeToBytes(kCFStringEncodingUTF8, 0, surrogate, 2, NULL, bytes, 6, &byteLength) == kCFStringEncodingConversionSuccess) {
+                        endPtr = bytePtr + byteLength;
+                        for ( currByte = bytes; currByte < endPtr; currByte++ ) {
+                            charBuffer[charBufferIndex++] = '%';
+                            charBuffer[charBufferIndex++] = hexchars[*currByte >> 4];
+                            charBuffer[charBufferIndex++] = hexchars[*currByte & 0x0f];
+                        }
+                        idx++; // We consumed 2 characters, not 1
+                    }
+                    else {
+                        // surrogate pair conversion failed
                         break;
                     }
                 } else {
+                    // not a surrogate pair
                     break;
                 }
             }
-        } else if (ch == '%' && handlePercentChar) {
-            CFStringRef replacementString = NULL;
-            CFIndex newIndex = handlePercentChar(idx, originalString, &replacementString, context);
-            if (newIndex < 0) {
-                break;
-            } else if (replacementString) {
-                if (!newString) {
-                    newString = CFStringCreateMutableCopy(CFGetAllocator(originalString), 0, originalString);
-                    CFStringDelete(newString, CFRangeMake(idx, length-idx));
-                }
-                CFStringAppend(newString, replacementString);
-                CFRelease(replacementString);
-            }
-            if (newIndex == idx) {
-                if (newString) {
-                    CFStringAppendCharacters(newString, &ch, 1);
-                }
-            } else {
-                if (!replacementString && newString) {
-                    CFIndex tmpIndex;
-                    for (tmpIndex = idx; tmpIndex < newIndex; tmpIndex ++) {
-                        ch = CFStringGetCharacterAtIndex(originalString, idx);
-                        CFStringAppendCharacters(newString, &ch, 1);
-                    }                        
-                }
-                idx = newIndex - 1;
-            }
         } else if (newString) {
-            CFStringAppendCharacters(newString, &ch, 1);
+            charBuffer[charBufferIndex++] = ch;
+            if ( charBufferIndex == kCharBufferMax ) {
+                CFStringAppendCharacters(newString, charBuffer, charBufferIndex);
+                charBufferIndex = 0;
+            }
         }
     }
     if (idx < length) {
-        // Ran in to an encoding failure
+        // Ran into an encoding failure
         if (newString) CFRelease(newString);
         return NULL;
     } else if (newString) {
+        if ( charBufferIndex != 0 ) {
+            CFStringAppendCharacters(newString, charBuffer, charBufferIndex);
+        }
         return newString;
     } else {
         return (CFStringRef)CFStringCreateCopy(CFGetAllocator(originalString), originalString);
     }
 }
 
-
-static Boolean _stringContainsCharacter(CFStringRef string, UniChar ch) {
-    CFIndex i, c = CFStringGetLength(string);
-    CFStringInlineBuffer buf;
-    CFStringInitInlineBuffer(string, &buf, CFRangeMake(0, c));
-    for (i = 0; i < c; i ++) if (__CFStringGetCharacterFromInlineBufferQuick(&buf, i) == ch) return true;
-    return false;
-}
-
-static Boolean _shouldPercentReplaceChar(UniChar ch, void *context) {
-    CFStringRef unescape = ((CFStringRef *)context)[0];
-    CFStringRef escape = ((CFStringRef *)context)[1];
-    Boolean shouldReplace = (isURLLegalCharacter(ch) == false);
-    if (shouldReplace) {
-        if (unescape && _stringContainsCharacter(unescape, ch)) {
-            shouldReplace = false;
-        }
-    } else if (escape && _stringContainsCharacter(escape, ch)) {
-        shouldReplace = true;
-    }
-    return shouldReplace;
-}
-
-CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) {
-    CFStringRef strings[2];
-    strings[0] = charactersToLeaveUnescaped;
-    strings[1] = legalURLCharactersToBeEscaped;
-    return _addPercentEscapesToString(allocator, originalString, _shouldPercentReplaceChar, NULL, encoding, strings);
-}
-
 static Boolean __CFURLEqual(CFTypeRef  cf1, CFTypeRef  cf2) {
     Boolean result;
     CFURLRef  url1 = (CFURLRef)cf1;
@@ -1108,39 +1486,111 @@ static CFHashCode __CFURLHash(CFTypeRef cf)
     return ( result );
 }
 
-static CFStringRef  __CFURLCopyFormattingDescription(CFTypeRef  cf, CFDictionaryRef formatOptions) {
-    CFURLRef  url = (CFURLRef)cf;
-    __CFGenericValidateType(cf, CFURLGetTypeID());
-    if (! url->_base) {
-        CFRetain(url->_string);
-        return url->_string;
-    } else {
-        // Do not dereference url->_base; it may be an ObjC object
-        return CFStringCreateWithFormat(CFGetAllocator(url), NULL, CFSTR("%@ -- %@"), url->_string, url->_base);
+static CFStringRef CreateTruncatedURLString(CFAllocatorRef alloc, CFStringRef urlString, CFIndex maxLength, CFIndex suffixLength)
+{
+    CFStringRef result;
+    
+    CFIndex len = CFStringGetLength(urlString);
+    if ( len <= maxLength ) {
+        // return the retained urlString
+        result = CFStringCreateCopy(alloc, urlString);
     }
-}
-
+    else {
+        CFStringRef start = CFStringCreateWithSubstring(alloc, urlString, CFRangeMake(0, maxLength - suffixLength));
+        CFStringRef end = CFStringCreateWithSubstring(alloc, urlString, CFRangeMake(len - suffixLength, suffixLength));
+        result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@ ... %@"), start, end);
+        if ( start ) {
+            CFRelease(start);
+        }
+        if ( (end) ) {
+            CFRelease(end);
+        }
+    }
+    return ( result );
+}
+
+static CFStringRef  __CFURLCopyFormattingDescription(CFTypeRef  cf, CFDictionaryRef formatOptions) {
+    CFStringRef result;
+    CFURLRef  url = (CFURLRef)cf;
+    __CFGenericValidateType(cf, CFURLGetTypeID());
+    CFAllocatorRef alloc = CFGetAllocator(url);
+
+    Boolean isDataURL = false;
+    CFStringRef scheme = CFURLCopyScheme(url);
+    if ( scheme ) {
+        isDataURL = CFStringCompare(scheme, kCFURLDataScheme, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
+        CFRelease(scheme);
+    }
+    
+    if ( !isDataURL ) {
+        if (!url->_base) {
+            {
+                result = CFStringCreateCopy(alloc, url->_string);
+            }
+        } else {
+            // Do not dereference url->_base; it may be an ObjC object
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@ -- %@"), url->_string, url->_base);
+        }
+    }
+    else {
+        if ( !url->_base ) {
+            result = CreateTruncatedURLString(alloc, url->_string, 128, 8);
+        }
+        else {
+            CFStringRef urlString = CreateTruncatedURLString(alloc, url->_string, 128, 8);
+            CFStringRef baseString = CreateTruncatedURLString(alloc, CFURLGetString(url->_base), 128, 8);
+            // Do not dereference url->_base; it may be an ObjC object
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@ -- %@"), urlString, baseString);
+            if ( urlString ) {
+                CFRelease(urlString);
+            }
+            if ( baseString ) {
+                CFRelease(baseString);
+            }
+        }
+    }
+    return ( result );
+}
+
 
 static CFStringRef __CFURLCopyDescription(CFTypeRef cf) {
     CFURLRef url = (CFURLRef)cf;
     CFStringRef result;
     CFAllocatorRef alloc = CFGetAllocator(url);
-    if ( url->_base) {
-        CFStringRef baseString = CFCopyDescription(url->_base);
-        result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %d\n\tbase = %@}"), cf, alloc, url->_string, url->_encoding, baseString);
-        CFRelease(baseString);
-    } else {
-        result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %d, base = (null)}"), cf, alloc, url->_string, url->_encoding);
+    Boolean isDataURL = false;
+    CFStringRef scheme = CFURLCopyScheme(url);
+    
+    if ( scheme ) {
+        isDataURL = CFStringCompare(scheme, kCFURLDataScheme, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
+        CFRelease(scheme);
+    }
+    
+    if ( !isDataURL ) {
+        if ( url->_base) {
+            CFStringRef baseString = CFCopyDescription(url->_base);
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %u\n\tbase = %@}"), cf, alloc, url->_string, (unsigned int)(url->_encoding), baseString);
+            CFRelease(baseString);
+        } else {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %u, base = (null)}"), cf, alloc, url->_string, (unsigned int)(url->_encoding));
+        }
+    }
+    else {
+        CFStringRef urlString = CreateTruncatedURLString(alloc, url->_string, 128, 8);
+        if ( url->_base) {
+            CFStringRef baseString = CFCopyDescription(url->_base);
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %u\n\tbase = %@}"), cf, alloc, urlString, (unsigned int)(url->_encoding), baseString);
+            CFRelease(baseString);
+        } else {
+            result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %u, base = (null)}"), cf, alloc, urlString, (unsigned int)(url->_encoding));
+        }
+        CFRelease(urlString);
     }
     return result;
 }
 
 #if DEBUG_URL_MEMORY_USAGE
-
 extern __attribute((used)) void __CFURLDumpMemRecord(void) {
-    CFStringRef str = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%d URLs created; %d destroyed\n%d file URLs created; %d urls had 'extra' data allocated, %d had base urls, %d were not UTF8 encoded\n"), numURLs, numDealloced, numFileURLsCreated, numExtraDataAllocated, numURLsWithBaseURL, numNonUTF8EncodedURLs );
-    CFShow(str);
-    CFRelease(str);
+    syslog(LOG_ERR, "%d URLs created; %d destroyed; %d URLs parsed; %d urls had 'extra' data allocated; %d had base urls; %d were not UTF8 encoded", numURLs, numDealloced, numFileURLsParsed, numExtraDataAllocated, numURLsWithBaseURL, numNonUTF8EncodedURLs);
 }
 #endif
 
@@ -1177,24 +1627,7 @@ static const CFRuntimeClass __CFURLClass = {
     NULL,                               // refcount
 };
 
-// When __CONSTANT_CFSTRINGS__ is not defined, we have separate macros for static and exported constant strings, but
-// when it is defined, we must prefix with static to prevent the string from being exported 
-#ifdef __CONSTANT_CFSTRINGS__
-static CONST_STRING_DECL(kCFURLHTTPScheme, "http")
-static CONST_STRING_DECL(kCFURLHTTPSScheme, "https")
-static CONST_STRING_DECL(kCFURLFileScheme, "file")
-static CONST_STRING_DECL(kCFURLDataScheme, "data")
-static CONST_STRING_DECL(kCFURLFTPScheme, "ftp")
-static CONST_STRING_DECL(kCFURLLocalhost, "localhost")
-#else
-CONST_STRING_DECL(kCFURLHTTPScheme, "http")
-CONST_STRING_DECL(kCFURLHTTPSScheme, "https")
-CONST_STRING_DECL(kCFURLFileScheme, "file")
-CONST_STRING_DECL(kCFURLDataScheme, "data")
-CONST_STRING_DECL(kCFURLFTPScheme, "ftp")
-CONST_STRING_DECL(kCFURLLocalhost, "localhost")
-#endif
-__private_extern__ void __CFURLInitialize(void) {
+CF_PRIVATE void __CFURLInitialize(void) {
     __kCFURLTypeID = _CFRuntimeRegisterClass(&__CFURLClass);
 }
 
@@ -1208,7 +1641,7 @@ CFTypeID CFURLGetTypeID(void) {
     return __kCFURLTypeID;
 }
 
-__private_extern__ void CFShowURL(CFURLRef url) {
+CF_PRIVATE void CFShowURL(CFURLRef url) {
     if (!url) {
         fprintf(stdout, "(null)\n");
         return;
@@ -1234,12 +1667,12 @@ __private_extern__ void CFShowURL(CFURLRef url) {
 /***************************************************/
 /* URL creation and String/Data creation from URLS */
 /***************************************************/
-static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, Boolean useEightBitStringEncoding, UInt8 *inBuffer, CFIndex inBufferSize, const char **cstring, const UniChar **ustring, Boolean *useCString, Boolean *freeCharacters) {
+static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, UInt8 *inBuffer, CFIndex inBufferSize, const char **cstring, const UniChar **ustring, Boolean *useCString, Boolean *freeCharacters) {
     CFIndex neededLength;
     CFIndex length;
     CFRange rg;
 
-    *cstring = CFStringGetCStringPtr(string, (useEightBitStringEncoding ? __CFStringGetEightBitStringEncoding() : kCFStringEncodingISOLatin1));
+    *cstring = CFStringGetCStringPtr(string, kCFStringEncodingISOLatin1);
     if (*cstring) {
         *ustring = NULL;
         *useCString = true;
@@ -1286,315 +1719,56 @@ static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, Boolean u
     }
 }
 
-#define STRING_CHAR(x) (useCString ? cstring[(x)] : ustring[(x)])
+static void _parseComponentsCString(CFAllocatorRef alloc, CFURLRef baseURL, UInt32 *theFlags, CFRange **range, CFIndex cfStringLength, const char *characterArray)
+#define CFURL_INCLUDE_PARSE_COMPONENTS
+#include "CFURL.inc.h"
+#undef CFURL_INCLUDE_PARSE_COMPONENTS
+
+static void _parseComponentsUString(CFAllocatorRef alloc, CFURLRef baseURL, UInt32 *theFlags, CFRange **range, CFIndex cfStringLength, const UniChar *characterArray)
+#define CFURL_INCLUDE_PARSE_COMPONENTS
+#include "CFURL.inc.h"
+#undef CFURL_INCLUDE_PARSE_COMPONENTS
+
 static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef baseURL, UInt32 *theFlags, CFRange **range) {
-    CFRange ranges[9];
-    /* index gives the URL part involved; to calculate the correct range index, use the number of the bit of the equivalent flag (i.e. the host flag is HAS_HOST, which is 0x8.  so the range index for the host is 3.)  Note that this is true in this function ONLY, since the ranges stored in (*range) are actually packed, skipping those URL components that don't exist.  This is why the indices are hard-coded in this function. */
-
-    CFIndex idx, base_idx = 0;
-    CFIndex string_length;
-    UInt32 flags = *theFlags;
-    Boolean useEightBitStringEncoding = (flags & USES_EIGHTBITSTRINGENCODING) != 0;
-    Boolean useCString, freeCharacters, isCompliant;
-    uint8_t numRanges = 0;
+    CFIndex cfStringLength = CFStringGetLength(string);
+    Boolean useCString, freeCharacters;
     const char *cstring = NULL;
     const UniChar *ustring = NULL;
     CFIndex stackBufferSize = 4096;
     STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize);
     
-    string_length = CFStringGetLength(string);
-    constructBuffers(alloc, string, useEightBitStringEncoding, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
+    constructBuffers(alloc, string, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
     
-    // Algorithm is as described in RFC 1808
-    // 1: parse the fragment; remainder after left-most "#" is fragment
-    for (idx = base_idx; idx < string_length; idx++) {
-        if ('#' == STRING_CHAR(idx)) {
-            flags |= HAS_FRAGMENT;
-            ranges[8].location = idx + 1;
-            ranges[8].length = string_length - (idx + 1);
-            numRanges ++;
-            string_length = idx;       // remove fragment from parse string
-            break;
-        }
+    if (useCString) {
+        _parseComponentsCString(alloc, baseURL, theFlags, range, cfStringLength, cstring);
     }
-    // 2: parse the scheme
-    for (idx = base_idx; idx < string_length; idx++) {
-        UniChar ch = STRING_CHAR(idx);
-        if (':' == ch) {
-            flags |= HAS_SCHEME;
-            flags |= IS_ABSOLUTE;
-            ranges[0].location = base_idx;
-            ranges[0].length = idx;
-            numRanges ++;
-            base_idx = idx + 1;
-            // optimization for ftp urls
-            if (idx == 3 && STRING_CHAR(0) == 'f' && STRING_CHAR(1) == 't' && STRING_CHAR(2) == 'p') {
-                _setSchemeTypeInFlags(&flags, kHasFtpScheme);
-            }
-            else if (idx == 4) {
-                // optimization for http urls
-                if (STRING_CHAR(0) == 'h' && STRING_CHAR(1) == 't' && STRING_CHAR(2) == 't' && STRING_CHAR(3) == 'p') {
-                    _setSchemeTypeInFlags(&flags, kHasHttpScheme);
-                }
-                // optimization for file urls
-                if (STRING_CHAR(0) == 'f' && STRING_CHAR(1) == 'i' && STRING_CHAR(2) == 'l' && STRING_CHAR(3) == 'e') {
-                    _setSchemeTypeInFlags(&flags, kHasFileScheme);
-                }
-                // optimization for data urls
-                if (STRING_CHAR(0) == 'd' && STRING_CHAR(1) == 'a' && STRING_CHAR(2) == 't' && STRING_CHAR(3) == 'a') {
-                    _setSchemeTypeInFlags(&flags, kHasDataScheme);
-                }
-            }
-            // optimization for https urls
-            else if (idx == 5 && STRING_CHAR(0) == 'h' && STRING_CHAR(1) == 't' && STRING_CHAR(2) == 't' && STRING_CHAR(3) == 'p' && STRING_CHAR(3) == 's') {
-                _setSchemeTypeInFlags(&flags, kHasHttpsScheme);
-            }
-            break;
-        } else if (!scheme_valid(ch)) {
-            break;     // invalid scheme character -- no scheme
-        }
-    }
-
-    // Make sure we have an RFC-1808 compliant URL - that's either something without a scheme, or scheme:/(stuff) or scheme://(stuff) 
-    // Strictly speaking, RFC 1808 & 2396 bar "scheme:" (with nothing following the colon); however, common usage
-    // expects this to be treated identically to "scheme://" - REW, 12/08/03
-    if (!(flags & HAS_SCHEME)) {
-        isCompliant = true;
-    } else if (base_idx == string_length) {
-        isCompliant = false;
-    } else if (STRING_CHAR(base_idx) != '/') {
-        isCompliant = false;
-    } else {
-        isCompliant = true;
-    }
-    
-    if (!isCompliant) {
-        // Clear the fragment flag if it's been set
-        if (flags & HAS_FRAGMENT) {
-            flags &= (~HAS_FRAGMENT);
-            string_length = CFStringGetLength(string);
-        }
-        (*theFlags) = flags;
-        (*range) = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
-        (*range)->location = ranges[0].location;
-        (*range)->length = ranges[0].length;
-
-        if (freeCharacters) {
-            CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring);
-        }
-        return;
+    else {
+        _parseComponentsUString(alloc, baseURL, theFlags, range, cfStringLength, ustring);
     }
-    // URL is 1808-compliant
-    flags |= IS_DECOMPOSABLE;
     
-    // 3: parse the network location and login
-    if (2 <= (string_length - base_idx) && '/' == STRING_CHAR(base_idx) && '/' == STRING_CHAR(base_idx+1)) {
-        CFIndex base = 2 + base_idx, extent;
-        for (idx = base; idx < string_length; idx++) {
-            if ('/' == STRING_CHAR(idx) || '?' == STRING_CHAR(idx)) break;
-        }
-        extent = idx;
-        
-        // net_loc parts extend from base to extent (but not including), which might be to end of string
-        // net location is "<user>:<password>@<host>:<port>"
-        if (extent != base) {
-            for (idx = base; idx < extent; idx++) {
-                if ('@' == STRING_CHAR(idx)) {   // there is a user
-                    CFIndex idx2;
-                    flags |= HAS_USER;
-                    numRanges ++;
-                    ranges[1].location = base;  // base of the user
-                    for (idx2 = base; idx2 < idx; idx2++) {
-                        if (':' == STRING_CHAR(idx2)) {        // found a password separator
-                            flags |= HAS_PASSWORD;
-                            numRanges ++;
-                            ranges[2].location = idx2+1; // base of the password
-                            ranges[2].length = idx-(idx2+1);  // password extent
-                            ranges[1].length = idx2 - base; // user extent
-                            break;
-                        }
-                    }
-                    if (!(flags & HAS_PASSWORD)) {
-                        // user extends to the '@'
-                        ranges[1].length = idx - base; // user extent
-                    }
-                    base = idx + 1;
-                    break;
-                }
-            }
-            flags |= HAS_HOST;
-            numRanges ++;
-            ranges[3].location = base; // base of host
-
-            // base has been advanced past the user and password if they existed
-            for (idx = base; idx < extent; idx++) {
-                // IPV6 support (RFC 2732) DCJ June/10/2002
-                if ('[' == STRING_CHAR(idx)) { // starting IPV6 explicit address
-                                       //      Find the ']' terminator of the IPv6 address, leave idx pointing to ']' or end
-                                       for ( ; idx < extent; ++ idx ) {
-                                               if ( ']' == STRING_CHAR(idx)) {
-                                                       flags |= IS_IPV6_ENCODED;
-                                                       break;
-                                               }
-                                       }
-                               }
-                // there is a port if we see a colon.  Only the last one is the port, though.
-                else if ( ':' == STRING_CHAR(idx)) {   
-                    flags |= HAS_PORT;
-                    numRanges ++;
-                    ranges[4].location = idx+1; // base of port
-                    ranges[4].length = extent - (idx+1); // port extent
-                    ranges[3].length = idx - base; // host extent
-                    break;
-                }
-            }
-            if (!(flags & HAS_PORT)) {
-                ranges[3].length = extent - base;  // host extent
-            }
-        }
-        base_idx = extent;
-    }
-
-    // 4: parse the query; remainder after left-most "?" is query
-    for (idx = base_idx; idx < string_length; idx++) {
-        if ('?' == STRING_CHAR(idx)) {
-            flags |= HAS_QUERY;
-            numRanges ++;
-            ranges[7].location = idx + 1;
-            ranges[7].length = string_length - (idx+1);
-            string_length = idx;       // remove query from parse string
-            break;
-        }
-    }
-        
-    // 5: parse the parameters; remainder after left-most ";" is parameters
-    for (idx = base_idx; idx < string_length; idx++) {
-        if (';' == STRING_CHAR(idx)) {
-            flags |= HAS_PARAMETERS;
-            numRanges ++;
-            ranges[6].location = idx + 1;
-            ranges[6].length = string_length - (idx+1);
-            string_length = idx;       // remove parameters from parse string
-            break;
-        }
-    }
-        
-    // 6: parse the path; it's whatever's left between string_length & base_idx
-    if (string_length - base_idx != 0 || (flags & NET_LOCATION_MASK))
-    {
-        // If we have a net location, we are 1808-compliant, and an empty path substring implies a path of "/"
-        UniChar ch;
-        Boolean isDir;
-        CFRange pathRg;
-        flags |= HAS_PATH;
-        numRanges ++;
-        pathRg.location = base_idx;
-        pathRg.length = string_length - base_idx;
-        ranges[5] = pathRg;
-
-        if (pathRg.length > 0) {
-            Boolean sawPercent = FALSE;
-            for (idx = pathRg.location; idx < string_length; idx++) {
-                if ('%' == STRING_CHAR(idx)) {
-                    sawPercent = TRUE;
-                    break;
-                }
-            }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-           if (pathRg.length > 6 && STRING_CHAR(pathRg.location) == '/' && STRING_CHAR(pathRg.location + 1) == '.' && STRING_CHAR(pathRg.location + 2) == 'f' && STRING_CHAR(pathRg.location + 3) == 'i' && STRING_CHAR(pathRg.location + 4) == 'l' && STRING_CHAR(pathRg.location + 5) == 'e' && STRING_CHAR(pathRg.location + 6) == '/') {
-               flags |= PATH_HAS_FILE_ID;
-           } else if (!sawPercent) {
-                flags |= POSIX_AND_URL_PATHS_MATCH;
-            }
-#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
-            if (!sawPercent) {
-                flags |= POSIX_AND_URL_PATHS_MATCH;
-            }
-#endif
-
-            ch = STRING_CHAR(pathRg.location + pathRg.length - 1);
-            if (ch == '/') {
-                isDir = true;
-            } else if (ch == '.') {
-                if (pathRg.length == 1) {
-                    isDir = true;
-                } else {
-                    ch = STRING_CHAR(pathRg.location + pathRg.length - 2);
-                    if (ch == '/') {
-                        isDir = true;
-                    } else if (ch != '.') {
-                        isDir = false;
-                    } else if (pathRg.length == 2) {
-                        isDir = true;
-                    } else {
-                        isDir = (STRING_CHAR(pathRg.location + pathRg.length - 3) == '/');
-                    }
-                }
-            } else {
-                isDir = false;
-            }
-        } else {
-            isDir = (baseURL != NULL) ? CFURLHasDirectoryPath(baseURL) : false;
-        }
-        if (isDir) {
-            flags |= IS_DIRECTORY;
-        }
-    }
-
     if (freeCharacters) {
         CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring);
     }
-    (*theFlags) = flags;
-    (*range) = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange)*numRanges, 0);
-    numRanges = 0;
-    for (idx = 0, flags = 1; flags != (1<<9); flags = (flags<<1), idx ++) {
-        if ((*theFlags) & flags) {
-            (*range)[numRanges] = ranges[idx];
-            numRanges ++;
-        }
-    }
 }
 
+static Boolean scanCharactersCString(CFAllocatorRef alloc, CFMutableStringRef *escapedString, UInt32 *flags, const char *characterArray, Boolean useCString, CFIndex base, CFIndex end, CFIndex *mark, UInt32 componentFlag, CFStringEncoding encoding)
+#define CFURL_INCLUDE_SCAN_CHARACTERS
+#include "CFURL.inc.h"
+#undef CFURL_INCLUDE_SCAN_CHARACTERS
+
+static Boolean scanCharactersUString(CFAllocatorRef alloc, CFMutableStringRef *escapedString, UInt32 *flags, const UniChar *characterArray, Boolean useCString, CFIndex base, CFIndex end, CFIndex *mark, UInt32 componentFlag, CFStringEncoding encoding)
+#define CFURL_INCLUDE_SCAN_CHARACTERS
+#include "CFURL.inc.h"
+#undef CFURL_INCLUDE_SCAN_CHARACTERS
+
 static Boolean scanCharacters(CFAllocatorRef alloc, CFMutableStringRef *escapedString, UInt32 *flags, const char *cstring, const UniChar *ustring, Boolean useCString, CFIndex base, CFIndex end, CFIndex *mark, UInt32 componentFlag, CFStringEncoding encoding) {
-    CFIndex idx;
-    Boolean sawIllegalChar = false;
-    for (idx = base; idx < end; idx ++) {
-        Boolean shouldEscape;
-        UniChar ch = STRING_CHAR(idx);
-        if (isURLLegalCharacter(ch)) {
-            if ((componentFlag == HAS_USER || componentFlag == HAS_PASSWORD) && (ch == '/' || ch == '?' || ch == '@')) {
-                shouldEscape = true;
-            } else {
-                shouldEscape = false;
-            }
-        } else if (ch == '%' && idx + 2 < end && isHexDigit(STRING_CHAR(idx + 1)) && isHexDigit(STRING_CHAR(idx+2))) {
-            shouldEscape = false;
-        } else if (componentFlag == HAS_HOST && ((idx == base && ch == '[') || (idx == end-1 && ch == ']'))) {
-            shouldEscape = false;
-        } else {
-            shouldEscape = true;
-        }
-        if (shouldEscape) {
-            sawIllegalChar = true;
-            if (componentFlag && flags) {
-                *flags |= componentFlag;
-            }
-            if (!*escapedString) {
-                *escapedString = CFStringCreateMutable(alloc, 0);
-            }
-            if (useCString) {
-                CFStringRef tempString = CFStringCreateWithBytes(alloc, (uint8_t *)&(cstring[*mark]), idx - *mark, kCFStringEncodingISOLatin1, false);
-                CFStringAppend(*escapedString, tempString);
-                CFRelease(tempString);
-            } else {
-                CFStringAppendCharacters(*escapedString, &(ustring[*mark]), idx - *mark);
-            }
-            *mark = idx + 1;
-            _appendPercentEscapesForCharacter(ch, encoding, *escapedString); // This can never fail because anURL->_string was constructed from the encoding passed in
-        }
+    if ( useCString ) {
+        return ( scanCharactersCString(alloc, escapedString, flags, cstring, useCString, base, end, mark, componentFlag, encoding));
+    }
+    else {
+        return ( scanCharactersUString(alloc, escapedString, flags, ustring, useCString, base, end, mark, componentFlag, encoding));
     }
-    return sawIllegalChar;
-} 
+}
 
 static void computeSanitizedString(CFURLRef url) {
     CFAllocatorRef alloc = CFGetAllocator(url);
@@ -1608,9 +1782,8 @@ static void computeSanitizedString(CFURLRef url) {
     STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize);
     CFMutableStringRef sanitizedString = NULL;
     UInt32 additionalDataFlags = 0;
-    Boolean useEightBitStringEncoding = (url->_flags & USES_EIGHTBITSTRINGENCODING) != 0;
 
-    constructBuffers(alloc, url->_string, useEightBitStringEncoding, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
+    constructBuffers(alloc, url->_string, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
     if (!(url->_flags & IS_DECOMPOSABLE)) {
         // Impossible to have a problem character in the scheme
         base = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME).length + 1;
@@ -1628,7 +1801,7 @@ static void computeSanitizedString(CFURLRef url) {
         while (currentComponent < (HAS_FRAGMENT << 1)) {
             CFRange componentRange = _rangeForComponent(url->_flags, url->_ranges, currentComponent);
             if (componentRange.location != kCFNotFound) {
-                scanCharacters(alloc, & sanitizedString, &additionalDataFlags, cstring, ustring, useCString, componentRange.location, componentRange.location + componentRange.length, &mark, currentComponent, url->_encoding);
+                scanCharacters(alloc, &sanitizedString, &additionalDataFlags, cstring, ustring, useCString, componentRange.location, componentRange.location + componentRange.length, &mark, currentComponent, url->_encoding);
             }
             currentComponent = currentComponent << 1;
         }
@@ -1640,9 +1813,7 @@ static void computeSanitizedString(CFURLRef url) {
     }
     if (sanitizedString && mark != string_length) {
         if (useCString) {
-            CFStringRef tempString = CFStringCreateWithBytes(alloc, (uint8_t *)&(cstring[mark]), string_length - mark, kCFStringEncodingISOLatin1, false);
-            CFStringAppend(sanitizedString, tempString);
-            CFRelease(tempString);
+            __CFStringAppendBytes(sanitizedString, (char *)&(cstring[mark]), string_length - mark, kCFStringEncodingISOLatin1);
         } else {
             CFStringAppendCharacters(sanitizedString, &(ustring[mark]), string_length - mark);
         }
@@ -1668,14 +1839,12 @@ static CFStringRef correctedComponent(CFStringRef comp, UInt32 compFlag, CFStrin
     CFIndex stackBufferSize = 1024;
     STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize);
 
-    constructBuffers(alloc, comp, false, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
+    constructBuffers(alloc, comp, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
     scanCharacters(alloc, &result, NULL, cstring, ustring, useCString, 0, string_length, &mark, compFlag, enc);
     if (result) {
         if (mark < string_length) {
             if (useCString) {
-                CFStringRef tempString = CFStringCreateWithBytes(alloc, (uint8_t *)&(cstring[mark]), string_length - mark, kCFStringEncodingISOLatin1, false);
-                CFStringAppend(result, tempString);
-                CFRelease(tempString);
+                __CFStringAppendBytes(result, (char *)&(cstring[mark]), string_length - mark, kCFStringEncodingISOLatin1);
             } else {
                 CFStringAppendCharacters(result, &(ustring[mark]), string_length - mark);
             }
@@ -1691,11 +1860,14 @@ static CFStringRef correctedComponent(CFStringRef comp, UInt32 compFlag, CFStrin
     return result;
 }
 
-#undef STRING_CHAR
+
 CF_EXPORT CFURLRef _CFURLAlloc(CFAllocatorRef allocator) {
     struct __CFURL *url;
 #if DEBUG_URL_MEMORY_USAGE
     numURLs ++;
+//    if ( numURLs % 1000 == 0 ) {
+//        __CFURLDumpMemRecord();
+//    }
 #endif
     url = (struct __CFURL *)_CFRuntimeCreateInstance(allocator, __kCFURLTypeID, sizeof(struct __CFURL) - sizeof(CFRuntimeBase), NULL);
     if (url) {
@@ -1710,196 +1882,433 @@ CF_EXPORT CFURLRef _CFURLAlloc(CFAllocatorRef allocator) {
     return url;
 }
 
-// It is the caller's responsibility to guarantee that if URLString is absolute, base is NULL.  This is necessary to avoid duplicate processing for file system URLs, which had to decide whether to compute the cwd for the base; we don't want to duplicate that work.  This ALSO means it's the caller's responsibility to set the IS_ABSOLUTE bit, since we may have a degenerate URL whose string is relative, but lacks a base.
-static void _CFURLInit(struct __CFURL *url, CFStringRef URLString, UInt32 fsType, CFURLRef base) {
-    CFAssert2((fsType == FULL_URL_REPRESENTATION) || (fsType == kCFURLPOSIXPathStyle) || (fsType == kCFURLWindowsPathStyle) || (fsType == kCFURLHFSPathStyle), __kCFLogAssertion, "%s(): Received bad fsType %d", __PRETTY_FUNCTION__, fsType);
+// It is the caller's responsibility to guarantee that if URLString is absolute, base is NULL.  This is necessary to avoid duplicate processing for file system URLs, which had to decide whether to compute the cwd for the base; we don't want to duplicate that work. If parseURL is false, the caller is responsible for parsing the URL. 
+static void _CFURLInit(struct __CFURL *url, CFStringRef URLString, CFURLRef base, Boolean parseURL) {
     
     // Coming in, the url has its allocator flag properly set, and its base initialized, and nothing else.    
-    url->_string = CFStringCreateCopy(CFGetAllocator(url), URLString);    
+    url->_string = CFStringCreateCopy(CFGetAllocator(url), URLString);
     url->_base = base ? CFURLCopyAbsoluteURL(base) : NULL;
     
 #if DEBUG_URL_MEMORY_USAGE
-    if ( (fsType == kCFURLPOSIXPathStyle) || (fsType == kCFURLHFSPathStyle) || (fsType == kCFURLWindowsPathStyle) ) {
-        numFileURLsCreated ++;
-    }
     if ( url->_base ) {
         numURLsWithBaseURL ++;
     }
 #endif
-    if (fsType != FULL_URL_REPRESENTATION) {
-        // _convertToURLRepresentation parses the URL
-        _convertToURLRepresentation((struct __CFURL *)url, fsType);
-    }
-    else {
+    if ( parseURL ) {
+#if DEBUG_URL_MEMORY_USAGE
+        numFileURLsParsed++;
+#endif
         _parseComponentsOfURL(url);
     }
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
-CF_EXPORT void _CFURLInitFSPath(CFURLRef url, CFStringRef path) {
-    CFIndex len = CFStringGetLength(path);
-    if (len && CFStringGetCharacterAtIndex(path, 0) == '/') {
-        _CFURLInit((struct __CFURL *)url, path, kCFURLPOSIXPathStyle, NULL);
-        ((struct __CFURL *)url)->_flags |= IS_ABSOLUTE;
-    } else {
-        CFURLRef cwdURL = _CFURLCreateCurrentDirectoryURL(CFGetAllocator(url));
-        _CFURLInit((struct __CFURL *)url, path, kCFURLPOSIXPathStyle, cwdURL);
-        if ( cwdURL )
-            CFRelease(cwdURL);
+static Boolean _CFStringIsLegalURLString(CFStringRef string) {
+    Boolean result = true;
+    if ( string ) {
+        CFStringInlineBuffer stringBuffer;
+        Boolean sawHash = false;
+        CFIndex idx = 0;
+        CFIndex checkHexDigit = 0;
+        CFIndex length;
+        
+        length = CFStringGetLength(string);
+        {
+            CFStringInitInlineBuffer(string, &stringBuffer, CFRangeMake(0, length));
+            
+            while ( idx < length ) {
+                CFIndex rangeLength;
+                const UniChar *chPtr;
+                
+                rangeLength = (idx + __kCFStringInlineBufferLength <= length) ? __kCFStringInlineBufferLength : length - idx;
+                chPtr = CFStringGetCharactersPtrFromInlineBuffer(&stringBuffer, CFRangeMake(idx, rangeLength));
+                for ( CFIndex rangeIdx = 0; rangeIdx < rangeLength; ++rangeIdx, ++chPtr ) {
+                    if ( !checkHexDigit ) {
+                        if ( *chPtr == '%' ) {
+                            // percent encoded? make sure there at least 2 characters left to check
+                            if ( (idx + rangeIdx + 2) < length ) {
+                                // the next 2 characters must be HEXDIG
+                                checkHexDigit = 2;
+                                continue;
+                            }
+                            else {
+                                result = false;
+                                break;
+                            }
+                        }
+                        if ( *chPtr == '[' || *chPtr == ']' ) {
+                            continue; // IPV6 support (RFC 2732) DCJ June/10/2002
+                        }
+                        if ( *chPtr == '#' ) {
+                            // only allow one # character
+                            if ( !sawHash ) {
+                                sawHash = true;
+                                continue;
+                            }
+                            else {
+                                result = false;
+                                break;
+                            }
+                        }
+#if DEPLOYMENT_TARGET_WINDOWS
+                        // <rdar://problem/7134119> CF on Windows: CFURLCreateWithString should work with | in path on Windows
+                        if ( isURLLegalCharacter(*chPtr) || *chPtr == '|' ) {
+                            continue;
+                        }
+#else
+                        if ( isURLLegalCharacter(*chPtr) ) {
+                            continue;
+                        }
+#endif
+                        else {
+                            result = false;
+                            break;
+                        }
+                    }
+                    else {
+                        if ( isHexDigit(*chPtr) ) {
+                            --checkHexDigit;
+                            continue;
+                        }
+                        else {
+                            result = false;
+                            break;
+                        }
+                    }
+                }
+                
+                if ( !result ) {
+                    break; // out of main while loop
+                }
+                
+                idx += rangeLength;
+            }
+        }
     }
-    if (!len || '/' == CFStringGetCharacterAtIndex(path, len - 1))
-        ((struct __CFURL *)url)->_flags |= IS_DIRECTORY;
-}
-#elif DEPLOYMENT_TARGET_WINDOWS
-CF_EXPORT void _CFURLInitFSPath(CFURLRef url, CFStringRef path) {
-    CFIndex len = CFStringGetLength(path);
-       // be sure to use the windows path separator when checking the path to see if it's a directory here
-        if (!len || '\\' == CFStringGetCharacterAtIndex(path, len - 1))
-            ((struct __CFURL *)url)->_flags |= IS_DIRECTORY;
-    UniChar firstChar = 0 < len ? CFStringGetCharacterAtIndex(path, 0) : 0;
-    UniChar secondChar = 1 < len ? CFStringGetCharacterAtIndex(path, 1) : 0;
-    Boolean isDrive = ('A' <= firstChar && firstChar <= 'Z') || ('a' <= firstChar && firstChar <= 'z');
-        if (!len || '/' == CFStringGetCharacterAtIndex(path, len - 1))
-            ((struct __CFURL *)url)->_flags |= IS_DIRECTORY;
-    isDrive = isDrive && (secondChar == ':' || secondChar == '|');
-    if (isDrive || (firstChar == '\\' && secondChar == '\\')) {
-        _CFURLInit((struct __CFURL *)url, path, kCFURLWindowsPathStyle, NULL);
-        ((struct __CFURL *)url)->_flags |= IS_ABSOLUTE;
-    } else if (firstChar == '/') {
-        if (!len || '/' == CFStringGetCharacterAtIndex(path, len - 1))
-            ((struct __CFURL *)url)->_flags |= IS_DIRECTORY;
-        _CFURLInit((struct __CFURL *)url, path, kCFURLPOSIXPathStyle, NULL);
-        ((struct __CFURL *)url)->_flags |= IS_ABSOLUTE;
-    } else {
-        CFURLRef cwdURL = _CFURLCreateCurrentDirectoryURL(CFGetAllocator(url));
-        _CFURLInit((struct __CFURL *)url, path, kCFURLPOSIXPathStyle, cwdURL);
-        if ( cwdURL )
-            CFRelease(cwdURL);
+    else {
+        CFAssert(false, __kCFLogAssertion, "Cannot create an CFURL from a NULL string");
+        result = false;
     }
+    
+    return ( result );
 }
-#endif
 
-// Exported for Foundation's use
-CF_EXPORT Boolean _CFStringIsLegalURLString(CFStringRef string) {
-    // Check each character to make sure it is a legal URL char.  The valid characters are 'A'-'Z', 'a' - 'z', '0' - '9', plus the characters in "-_.!~*'()", and the set of reserved characters (these characters have special meanings in the URL syntax), which are ";/?:@&=+$,".  In addition, percent escape sequences '%' hex-digit hex-digit are permitted.
-    // Plus the hash character '#' which denotes the beginning of a fragment, and can appear exactly once in the entire URL string. -- REW, 12/13/2000
-    CFStringInlineBuffer stringBuffer;
-    CFIndex idx = 0, length;
-    Boolean sawHash = false;
-    if (!string) {
-        CFAssert(false, __kCFLogAssertion, "Cannot create an CFURL from a NULL string");
-        return false;
+/* initializes a URL object with a URL string */
+CF_EXPORT Boolean _CFURLInitWithURLString(CFURLRef uninitializedURL, CFStringRef string, Boolean checkForLegalCharacters, CFURLRef baseURL)
+{
+#if DEBUG_URL_INITIALIZER_LOGGING
+    CFStringRef input_string = string ? CFRetain(string) : NULL;
+    Boolean input_checkForLegalCharacters = checkForLegalCharacters;
+    CFURLRef input_baseURL = baseURL ? CFRetain(baseURL) : NULL;
+#endif
+    Boolean result = checkForLegalCharacters ? _CFStringIsLegalURLString(string) : true;
+    
+    if ( result ) {
+        // determine if URL is absolute (i.e. it has a scheme and the scheme characters are valid
+        CFStringInlineBuffer stringBuffer;
+        CFIndex length = CFStringGetLength(string);
+        CFIndex idx = 0;
+        Boolean isAbsolute = false;
+        Boolean schemeCharsValid = true;
+
+        CFStringInitInlineBuffer(string, &stringBuffer, CFRangeMake(0, length));
+        // the first character of the scheme must be ALPHA
+        if ( (length > 0) && isALPHA(__CFStringGetCharacterFromInlineBufferQuick(&stringBuffer, 0)) ) {
+            // stop looking if we hit the end of the string, find a colon (isAbsolute), or find a non-scheme character (schemeCharsValid)
+            while (idx < length && schemeCharsValid && !isAbsolute) {
+                CFIndex rangeLength = (idx + __kCFStringInlineBufferLength <= length) ? __kCFStringInlineBufferLength : length - idx;
+                const UniChar *chPtr = CFStringGetCharactersPtrFromInlineBuffer(&stringBuffer, CFRangeMake(idx, rangeLength));
+                for (CFIndex i = 0; i < rangeLength; ++i, ++chPtr) {
+                    if ( *chPtr == ':' ) {
+                        isAbsolute = true;
+                        break;
+                    }
+                    if ( !scheme_valid(*chPtr) ) {
+                        schemeCharsValid = false;
+                        break;
+                    }
+                }
+                if ( isAbsolute ) {
+                    break;
+                }
+                idx += rangeLength;
+            }
+        }
+        
+        _CFURLInit((struct __CFURL *)uninitializedURL, string, isAbsolute ? NULL : baseURL, TRUE);
     }
-    length = CFStringGetLength(string);
-    CFStringInitInlineBuffer(string, &stringBuffer, CFRangeMake(0, length));
-    while (idx < length) {
-        UniChar ch = CFStringGetCharacterFromInlineBuffer(&stringBuffer, idx);
-        idx ++;
-               
-               //      Make sure that two valid hex digits follow a '%' character
-               if ( ch == '%' ) {
-                       if ( idx + 2 > length )
-                       {
-                               //CFAssert1(false, __kCFLogAssertion, "Detected illegal percent escape sequence at character %d when trying to create a CFURL", idx-1);
-                               idx = -1;  // To guarantee index < length, and our failure case is triggered
-                               break;
-                       }
-                       
-                       ch = CFStringGetCharacterFromInlineBuffer(&stringBuffer, idx);
-                       idx ++;
-                       if (! isHexDigit(ch) ) {
-                               //CFAssert1(false, __kCFLogAssertion, "Detected illegal percent escape sequence at character %d when trying to create a CFURL", idx-2);
-                               idx = -1;
-                               break;
-                       }
-                       ch = CFStringGetCharacterFromInlineBuffer(&stringBuffer, idx);
-                       idx ++;
-                       if (! isHexDigit(ch) ) {
-                               //CFAssert1(false, __kCFLogAssertion, "Detected illegal percent escape sequence at character %d when trying to create a CFURL", idx-3);
-                               idx = -1;
-                               break;
-                       }
+#if DEBUG_URL_INITIALIZER_LOGGING
+    CFLog(kCFLogLevelError, CFSTR("_CFURLInitWithURLString (in) string '%@', checkForLegalCharacters %@, baseURL %@\n\t_CFURLInitWithURLString (out) result %@, url %@"), input_string, input_checkForLegalCharacters ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFSTR("YES") : CFSTR("NO"), uninitializedURL);
+    if ( input_string ) {
+        CFRelease(input_string);
+    }
+    if ( input_baseURL ) {
+        CFRelease(input_baseURL);
+    }
+#endif   
+    return ( result );
+}
 
-                       continue;
+/* initializes a URL object with a file system path */
+CF_EXPORT Boolean _CFURLInitWithFileSystemPath(CFURLRef uninitializedURL, CFStringRef fileSystemPath, CFURLPathStyle pathStyle, Boolean isDirectory, CFURLRef baseURL)
+{
+#if DEBUG_URL_INITIALIZER_LOGGING
+    CFStringRef input_fileSystemPath = fileSystemPath ? CFRetain(fileSystemPath) : NULL;
+    CFURLPathStyle input_pathStyle = pathStyle;
+    Boolean input_isDirectory = isDirectory;
+    CFURLRef input_baseURL = baseURL ? CFRetain(baseURL) : NULL;
+#endif
+    Boolean result = false;
+    CFAssert1(fileSystemPath != NULL, __kCFLogAssertion, "%s(): NULL path string not permitted", __PRETTY_FUNCTION__);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+    CFAssert2(pathStyle == kCFURLPOSIXPathStyle || pathStyle == kCFURLHFSPathStyle || pathStyle == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, pathStyle);
+#pragma GCC diagnostic pop
+    
+    struct __CFURL *url = (struct __CFURL *)uninitializedURL;
+    CFAllocatorRef alloc = CFGetAllocator(uninitializedURL);
+    CFStringRef urlString = NULL;
+    Boolean isAbsolute;
+    Boolean isFileReferencePath = false;
+    Boolean posixAndUrlPathsMatch = false;
+    UniChar pathDelim = '\0';
+    Boolean releaseBaseURL = false;
+    CFIndex len = CFStringGetLength(fileSystemPath);
+    
+    if (len > 0) {
+        // determine if fileSystemPath is an absolute path and what pathDelim we're using
+        switch (pathStyle) {
+            case kCFURLPOSIXPathStyle:
+                pathDelim = '/';
+                isAbsolute = (len > 0 && CFStringGetCharacterAtIndex(fileSystemPath, 0) == pathDelim);
+                break;
+                
+                
+            case kCFURLWindowsPathStyle:
+            {
+                // this is what _CFURLInitFSPath() did (with a small change to handle absolute paths that begin with a single backslash)
+                UniChar firstChar = 0 < len ? CFStringGetCharacterAtIndex(fileSystemPath, 0) : 0;
+                UniChar secondChar = 1 < len ? CFStringGetCharacterAtIndex(fileSystemPath, 1) : 0;
+                Boolean isDrive = isALPHA(firstChar) && (secondChar == ':' || secondChar == '|');
+                
+                if ( isDrive) {
+                    // A disk designator
+                    pathDelim = '\\';
+                    isAbsolute = true;
+                }
+                else if ( firstChar == '\\' ) {
+                    // Either a UNC name of any format (which always start with two backslash characters), or an absolute path which starts with a single backslash.
+                    pathDelim = '\\';
+                    isAbsolute = true;
+                }
+                else if (firstChar == '/') {
+                    // We switch to kCFURLPOSIXPathStyle here because there's probably code that passes POSIX paths in but wrongly specifies kCFURLWindowsPathStyle.
+                    pathStyle = kCFURLPOSIXPathStyle;
+                    pathDelim = '/';
+                    isAbsolute = true;
+                }
+                else {
+                    // We switch to kCFURLPOSIXPathStyle here because this is not an absolute path and we're going to set baseURL to the current working directory below, and so we assume the relative path will have  to be combined with the base path at some point.
+                    pathStyle = kCFURLPOSIXPathStyle;
+                    pathDelim = '/';
+                    isAbsolute = false;
+                }
+            }
+                break;
         }
-               if (ch == '[' || ch == ']') continue; // IPV6 support (RFC 2732) DCJ June/10/2002
-        if (ch == '#') {
-            if (sawHash) break;
-            sawHash = true;
-            continue;
+        
+        // Convert the fileSystemPath to a urlString and determine if it is a file reference path.
+        // The urlString returned will have a pathDelim at the end if isDirectory was true and no pathDelim if isDirectory was false (unless the urlPath is "/")
+        // If isAbsolute, "file://" will be prepended to the urlString.
+        switch (pathStyle) {
+            case kCFURLPOSIXPathStyle:
+                isFileReferencePath = _pathHasFileIDPrefix(fileSystemPath);
+                urlString = POSIXPathToURLPath(fileSystemPath, alloc, isDirectory, isAbsolute, &posixAndUrlPathsMatch);
+                break;
+                
+                
+            case kCFURLWindowsPathStyle:
+                urlString = WindowsPathToURLPath(fileSystemPath, alloc, isDirectory, isAbsolute);
+                break;
+        }
+        
+        CFAssert2(urlString != NULL, __kCFLogAssertion, "%s(): Encountered malformed file system URL %@", __PRETTY_FUNCTION__, urlString);
+        
+        if ( urlString ) {
+            if ( isAbsolute ) {
+                // if fileSystemPath is an absolute path, ignore baseURL (if provided)
+                baseURL = NULL;
+            }
+            else if ( baseURL == NULL ) {
+                // if fileSystemPath is a relative path and no baseURL is provided, use the current working directory
+                baseURL = _CFURLCreateCurrentDirectoryURL(CFGetAllocator(uninitializedURL));
+                releaseBaseURL = true;
+            }
+            
+            // override isDirectory if the path is to root
+            if ( !isDirectory && (len == 1) && (CFStringGetCharacterAtIndex(urlString, 0) == pathDelim) ) {
+                // Override isDirectory
+                isDirectory = true;
+            }
+            
+            _CFURLInit(url, urlString, baseURL, FALSE);
+            
+            // hard coded parse
+            if ( isAbsolute ) {
+                UInt32 flags = IS_DECOMPOSABLE | HAS_SCHEME | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH;
+                flags |= (isDirectory ? IS_DIRECTORY : 0);
+                if ( isFileReferencePath ) {
+                    // if the URL is a file reference URL, don't set IS_CANONICAL_FILE_URL or POSIX_AND_URL_PATHS_MATCH
+                    flags |= PATH_HAS_FILE_ID;
+                }
+                else {
+                    // only posix style paths can be canonical because POSIXPathToURLPath() converts the string to file system representation
+                    flags |= ((pathStyle == kCFURLPOSIXPathStyle) ? IS_CANONICAL_FILE_URL : 0);
+                    flags |= (posixAndUrlPathsMatch ? POSIX_AND_URL_PATHS_MATCH : 0);
+                }
+                _setSchemeTypeInFlags(&flags, kHasFileScheme);
+                
+                if ( AddAuthorityToFileURL() ) {
+                    url->_flags = flags | HAS_HOST;
+                    url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 3, 0);
+                    url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
+                    url->_ranges[1] = CFRangeMake(7, 9); // host "localhost"
+                    url->_ranges[2] = CFRangeMake(16, CFStringGetLength(urlString)- 16);
+                }
+                else {
+                    url->_flags = flags;
+                    url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 2, 0);
+                    url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
+                    url->_ranges[1] = CFRangeMake(7, CFStringGetLength(urlString)- 7);
+                }
+            } else {
+                url->_flags = (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH;
+                url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
+                *(url->_ranges) = CFRangeMake(0, CFStringGetLength(url->_string));
+            }
+            
+            if ( releaseBaseURL && baseURL ) {
+                CFRelease(baseURL);
+            }
+            
+            CFRelease(urlString);
+            result = true;
         }
-#if DEPLOYMENT_TARGET_WINDOWS
-       // <rdar://problem/7134119> CF on Windows: CFURLCreateWithString should work with | in path on Windows
-       if (isURLLegalCharacter(ch) || ch == '|')
-#else
-               if ( isURLLegalCharacter( ch ) )
-#endif
-                       continue;
-               break;
     }
-    if (idx < length) {
-        return false;
+#if DEBUG_URL_INITIALIZER_LOGGING
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+    CFLog(kCFLogLevelError, CFSTR("_CFURLInitWithFileSystemPath (in) fileSystemPath '%@', pathStyle %@, isDirectory %@, baseURL %@\n\t_CFURLInitWithFileSystemPath (out) result %@, url %@"), input_fileSystemPath, input_pathStyle == kCFURLPOSIXPathStyle ? CFSTR("POSIX") : input_pathStyle == kCFURLHFSPathStyle ? CFSTR("HFS"): CFSTR("Windows"), input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFSTR("YES") : CFSTR("NO"), uninitializedURL);
+#pragma GCC diagnostic pop
+    if ( input_fileSystemPath ) {
+        CFRelease(input_fileSystemPath);
     }
-    return true;
+    if ( input_baseURL ) {
+        CFRelease(input_baseURL);
+    }
+#endif
+    return ( result );
 }
 
-CF_EXPORT void _CFURLInitWithString(CFURLRef myURL, CFStringRef string, CFURLRef baseURL) {
-    struct __CFURL *url = (struct __CFURL *)myURL; // Supress annoying compile warnings
-    Boolean isAbsolute = false;
-    CFRange colon = CFStringFind(string, CFSTR(":"), 0);
-    if (colon.location != kCFNotFound) {
-        isAbsolute = true;
-        CFIndex i;
-        for (i = 0; i < colon.location; i++) {
-            char ch = (char)CFStringGetCharacterAtIndex(string, i);
-            if (!scheme_valid(ch)) {
-                isAbsolute = false;
-                break;
+/* initializes a URL object with the file system representation */
+CF_EXPORT Boolean _CFURLInitWithFileSystemRepresentation(CFURLRef uninitializedURL, const UInt8 *buffer, CFIndex bufLen, Boolean isDirectory, CFURLRef baseURL)
+{
+#if DEBUG_URL_INITIALIZER_LOGGING
+    STACK_BUFFER_DECL(UInt8, input_buffer, bufLen);
+    CFIndex input_bufLen = bufLen;
+    Boolean input_isDirectory = isDirectory;
+    CFURLRef input_baseURL = baseURL ? CFRetain(baseURL) : NULL;
+    memcpy(input_buffer, buffer, bufLen);
+#endif
+    Boolean result = false;
+    CFAllocatorRef alloc = CFGetAllocator(uninitializedURL);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
+    struct __CFURL *url = (struct __CFURL *)uninitializedURL;
+    Boolean isAbsolute = bufLen && (*buffer == '/');
+    Boolean addedPercentEncoding;
+    Boolean releaseBaseURL = false;
+    
+    if ( isAbsolute ) {
+        // if buffer contains an absolute path, ignore baseURL (if provided)
+        baseURL = NULL;
+    }
+    else if ( baseURL == NULL ) {
+        // if buffer contains a relative path and no baseURL is provided, use the current working directory
+        baseURL = _CFURLCreateCurrentDirectoryURL(CFGetAllocator(uninitializedURL));
+        releaseBaseURL = true;
+    }
+    CFStringRef urlString = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(alloc, buffer, bufLen, isDirectory, isAbsolute, false /*windowsPath*/, &addedPercentEncoding);
+    if ( urlString ) {
+        _CFURLInit(url, urlString, baseURL, FALSE);
+        
+        // hard coded parse
+        if ( isAbsolute ) {
+            if ( AddAuthorityToFileURL() ) {
+                url->_flags = (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH ) | (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_SCHEME | HAS_HOST | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | IS_CANONICAL_FILE_URL;
+                _setSchemeTypeInFlags(&url->_flags, kHasFileScheme);
+                url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 3, 0);
+                url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
+                url->_ranges[1] = CFRangeMake(7, 9); // host "localhost"
+                url->_ranges[2] = CFRangeMake(16, CFStringGetLength(urlString)- 16);
+            }
+            else {
+                url->_flags = (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH ) | (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_SCHEME | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | IS_CANONICAL_FILE_URL;
+                _setSchemeTypeInFlags(&url->_flags, kHasFileScheme);
+                url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 2, 0);
+                url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
+                url->_ranges[1] = CFRangeMake(7, CFStringGetLength(urlString)- 7);
             }
+        } else {
+            url->_flags = (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH ) | (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH;
+            url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
+            *(url->_ranges) = CFRangeMake(0, CFStringGetLength(url->_string));
         }
+        if ( releaseBaseURL && baseURL ) {
+            CFRelease(baseURL);
+        }
+        CFRelease(urlString);
+        result = true;
     }
-    _CFURLInit(url, string, FULL_URL_REPRESENTATION, isAbsolute ? NULL : baseURL);
-    if (isAbsolute) {
-        url->_flags |= IS_ABSOLUTE;
+#elif DEPLOYMENT_TARGET_WINDOWS
+    CFStringRef filePath = CFStringCreateWithBytes(alloc, buffer, bufLen, CFStringFileSystemEncoding(), false);
+    if ( filePath ) {
+        result = _CFURLInitWithFileSystemPath(uninitializedURL, filePath, kCFURLWindowsPathStyle, isDirectory, baseURL);
+        CFRelease(filePath);
     }
+#endif
+#if DEBUG_URL_INITIALIZER_LOGGING
+    CFLog(kCFLogLevelError, CFSTR("_CFURLInitWithFileSystemRepresentation (in) buffer '%*s', isDirectory %@, baseURL %@\n\t_CFURLInitWithFileSystemRepresentation (out) result %@, url %@"), input_bufLen, input_buffer, input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFSTR("YES") : CFSTR("NO"), uninitializedURL);
+    if ( input_baseURL ) {
+        CFRelease(input_baseURL);
+    }
+#endif
+    return ( result );
 }
 
-struct __CFURLEncodingTranslationParameters {
-    CFStringEncoding fromEnc;
-    CFStringEncoding toEnc;
-    const UniChar *addlChars;
-    int count;
-    Boolean escapeHighBit;
-    Boolean escapePercents;
-    Boolean agreesOverASCII;
-    Boolean encodingsMatch;
-} ;
-
 // encoding will be used both to interpret the bytes of URLBytes, and to interpret any percent-escapes within the bytes.
 CFURLRef CFURLCreateWithBytes(CFAllocatorRef allocator, const uint8_t *URLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL) {
-    CFStringRef  urlString;
-    Boolean useEightBitStringEncoding = ( __CFStringEncodingIsSupersetOfASCII(encoding) && __CFBytesInASCII(URLBytes, length) );
-    urlString = CFStringCreateWithBytes(allocator, URLBytes, length, useEightBitStringEncoding ? __CFStringGetEightBitStringEncoding() : encoding, false);
-    CFURLRef  result;
-    if (!urlString || CFStringGetLength(urlString) == 0) {
-        if (urlString) CFRelease(urlString);
-        return NULL;
-    }
-    result = _CFURLAlloc(allocator);
-    if (result) {
-        if ( useEightBitStringEncoding ) {
-            ((struct __CFURL *)result)->_flags |= USES_EIGHTBITSTRINGENCODING;
-        }
-        _CFURLInitWithString(result, urlString, baseURL);
-        if (encoding != kCFStringEncodingUTF8) {
-            ((struct __CFURL *)result)->_encoding = encoding;
+    CFStringRef  urlString = CFStringCreateWithBytes(allocator, URLBytes, length, encoding, false);
+    CFURLRef result = NULL;
+    if ( urlString ) {
+        if ( baseURL || CFStringGetLength(urlString) != 0 ) {
+            result = _CFURLAlloc(allocator);
+            if (result) {
+                if ( !_CFURLInitWithURLString(result, urlString, false /* checkForLegalCharacters */, baseURL) ) {
+                    CFRelease(result);
+                    result = NULL;
+                }
+                else {
+                    if (encoding != kCFStringEncodingUTF8) {
+                        ((struct __CFURL *)result)->_encoding = encoding;
 #if DEBUG_URL_MEMORY_USAGE
-            numNonUTF8EncodedURLs++;
+                        numNonUTF8EncodedURLs++;
 #endif
+                    }
+                }
+            }
         }
+        CFRelease(urlString); // it's retained by result, now.
     }
-    CFRelease(urlString); // it's retained by result, now.
-    return result;
+    return ( result );
 }
 
 CFDataRef CFURLCreateData(CFAllocatorRef allocator, CFURLRef  url, CFStringEncoding encoding, Boolean escapeWhitespace) {
@@ -1915,29 +2324,50 @@ CFDataRef CFURLCreateData(CFAllocatorRef allocator, CFURLRef  url, CFStringEncod
 
 // Any escape sequences in URLString will be interpreted via UTF-8.
 CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef  URLString, CFURLRef  baseURL) {
-    CFURLRef url;
-    if (!URLString || CFStringGetLength(URLString) == 0) return NULL;
-    if (!_CFStringIsLegalURLString(URLString)) return NULL;
-    url = _CFURLAlloc(allocator);
-    if (url) {
-        _CFURLInitWithString(url, URLString, baseURL);
+    CFURLRef url = NULL;
+    if ( URLString && (baseURL || CFStringGetLength(URLString) != 0) ) {
+        url = _CFURLAlloc(allocator);
+        if (url) {
+            if ( !_CFURLInitWithURLString(url, URLString, true /* checkForLegalCharacters */, baseURL) ) {
+                CFRelease(url);
+                url = NULL;
+            }
+        }
     }
-    return url;
+    return ( url );
 }
 
-static CFURLRef _CFURLCreateWithArbitraryString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL) {
-    CFURLRef url;
-    if (!URLString || CFStringGetLength(URLString) == 0) return NULL;
-    url = _CFURLAlloc(allocator);
-    if (url) {
-        _CFURLInitWithString(url, URLString, baseURL);
+static CFURLRef _CFURLCreateWithArbitraryString(CFAllocatorRef allocator, CFStringRef URLString, CFURLRef baseURL) {
+    CFURLRef url = NULL;
+    if ( URLString && (baseURL || CFStringGetLength(URLString) != 0) ) {
+        url = _CFURLAlloc(allocator);
+        if (url) {
+            if ( !_CFURLInitWithURLString(url, URLString, false /* checkForLegalCharacters */, baseURL) ) {
+                CFRelease(url);
+                url = NULL;
+            }
+        }
     }
-    return url;
+    return ( url );
 }
 
 CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *relativeURLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL, Boolean useCompatibilityMode) {
     CFURLRef result = NULL;
     
+    /*
+     CFURLCreateAbsoluteURLWithBytes() and useCompatibilityMode is for:
+         <rdar://problem/2711611> Problem with '|' in url and calling CFURLCreateWithString()
+         <rdar://problem/3085893> CFURL resolves "../" URLs at top level in a way that is not the same as web browsers
+         <rdar://problem/3085920> CFURL API should be more helpful for accepting URLs with technically-bad characters
+         <rdar://problem/3205656> Safari needs CFURL to deal with google.com URLs that end in "%"
+         <rdar://problem/3219233> Safari needs CFURL to not remove path when relative URL is just a query string
+         <rdar://problem/3219240> Safari needs CFURL to support "compatibility" resolution of partial URLs with schemes
+     
+     If useCompatibilityMode is true, the rules historically used on the web are used to resolve relativeString against baseURL - these rules are generally listed in the RFC as optional or alternate interpretations.  Otherwise, the strict rules from the RFC are used.
+     
+     The major differences are that in compatibility mode, we are lenient of the scheme appearing in relative portion, leading "../" components are removed from the final URL's path, and if the relative portion contains only resource specifier pieces (query, parameters, and fragment), then the last path component of the base URL will not be deleted
+     */
+
     // if not useCompatibilityMode, use CFURLCreateWithBytes and then CFURLCopyAbsoluteURL if there's a baseURL
     if ( !useCompatibilityMode ) {
         CFURLRef url = CFURLCreateWithBytes(alloc, relativeURLBytes, length, encoding, baseURL);
@@ -1956,18 +2386,16 @@ CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *rela
         Boolean absStringIsMutable = false;
         CFURLRef absURL;
         CFStringRef relativeString;
-        Boolean useEightBitStringEncoding;
         
-        useEightBitStringEncoding = ( __CFStringEncodingIsSupersetOfASCII(encoding) && __CFBytesInASCII(relativeURLBytes, length) );
-        relativeString = CFStringCreateWithBytes(alloc, relativeURLBytes, length, useEightBitStringEncoding ? __CFStringGetEightBitStringEncoding() : encoding, false);
+        relativeString = CFStringCreateWithBytes(alloc, relativeURLBytes, length, encoding, false);
         if ( relativeString != NULL ) {
             if (!baseURL) {
-                if ( useEightBitStringEncoding ) {
-                    absFlags |= USES_EIGHTBITSTRINGENCODING;
-                }
                 absString = relativeString;
             } else {
-                UniChar ch = CFStringGetCharacterAtIndex(relativeString, 0);
+                UniChar ch = 0;
+                if ( CFStringGetLength(relativeString) > 0 ) {
+                    ch = CFStringGetCharacterAtIndex(relativeString, 0);
+                }
                 if (ch == '?' || ch == ';' || ch == '#') {
                     // Nothing but parameter + query + fragment; append to the baseURL string
                     CFStringRef baseString;
@@ -1995,9 +2423,6 @@ CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *rela
                             _parseComponents(alloc, relString, baseURL, &relFlags, &relRanges);
                         } else {
                             // Discard the base string; the relative string is absolute and we're not in the funky edge case where the schemes match
-                            if ( useEightBitStringEncoding ) {
-                                absFlags |= USES_EIGHTBITSTRINGENCODING;
-                            }
                             CFRetain(relativeString);
                             absString = relativeString;
                         }
@@ -2112,7 +2537,7 @@ static CFStringRef _resolvedPath(UniChar *pathStr, UniChar *end, UniChar pathDel
                             pathStr[0] = '.';
                             pathStr[1] = '/';
                             pathStr[2] = '\0';
-                                                       end = & pathStr[3];
+                            end = &pathStr[3];
                             break;
                         }
                     }
@@ -2135,32 +2560,37 @@ static CFStringRef _resolvedPath(UniChar *pathStr, UniChar *end, UniChar pathDel
     if (stripTrailingDelimiter && end > pathStr && end-1 != pathStr && *(end-1) == pathDelimiter) {
         end --;
     }
-    return CFStringCreateWithCharactersNoCopy(alloc, pathStr, end - pathStr, alloc);
+    // return an zero-length string if end < pathStr
+    return CFStringCreateWithCharactersNoCopy(alloc, pathStr, end >= pathStr ? end - pathStr : 0, alloc);
 }
 
-static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStringRef relString, UInt32 relFlags, CFRange *relRanges, CFStringRef baseString, UInt32 baseFlags, CFRange *baseRanges) {
-    CFMutableStringRef newString = CFStringCreateMutable(alloc, 0);
-    CFIndex bufLen = CFStringGetLength(baseString) + CFStringGetLength(relString); // Overkill, but guarantees we never allocate again
-    UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, bufLen * sizeof(UniChar), 0);
+static CFMutableStringRef resolveAbsoluteURLStringBuffer(CFAllocatorRef alloc, CFStringRef relString, UInt32 relFlags, CFRange *relRanges, CFStringRef baseString, UInt32 baseFlags, CFRange *baseRanges, UniChar *buf)
+{
+    CFStringAppendBuffer appendBuffer;
+    UniChar chars[2];
+    CFStringInitAppendBuffer(alloc, &appendBuffer);
     CFRange rg;
     
     rg = _rangeForComponent(baseFlags, baseRanges, HAS_SCHEME);
     if (rg.location != kCFNotFound) {
         CFStringGetCharacters(baseString, rg, buf);
-        CFStringAppendCharacters(newString, buf, rg.length);
-        CFStringAppendCString(newString, ":", kCFStringEncodingASCII);
+        CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
+        chars[0] = ':';
+        CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
     }
-
+    
     if (relFlags & NET_LOCATION_MASK) {
-        CFStringAppend(newString, relString);
+        CFStringAppendStringToAppendBuffer(&appendBuffer, relString);
     } else {
-        CFStringAppendCString(newString, "//", kCFStringEncodingASCII);
+        chars[0] = '/';
+        chars[1] = '/';
+        CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 2);
         rg = _netLocationRange(baseFlags, baseRanges);
         if (rg.location != kCFNotFound) {
             CFStringGetCharacters(baseString, rg, buf);
-            CFStringAppendCharacters(newString, buf, rg.length);
+            CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
         }
-
+        
         if (relFlags & HAS_PATH) {
             CFRange relPathRg = _rangeForComponent(relFlags, relRanges, HAS_PATH);
             CFRange basePathRg = _rangeForComponent(baseFlags, baseRanges, HAS_PATH);
@@ -2181,7 +2611,7 @@ static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStrin
             } else if (useBasePath) {
                 newPath = CFStringCreateWithSubstring(alloc, baseString, basePathRg);
             } else {
-                // #warning FIXME - Get rid of this allocation
+                // FIXME: Get rid of this allocation
                 UniChar *newPathBuf = (UniChar *)CFAllocatorAllocate(alloc, sizeof(UniChar) * (relPathRg.length + basePathRg.length + 1), 0);
                 UniChar *idx, *end;
                 CFStringGetCharacters(baseString, basePathRg, newPathBuf);
@@ -2197,33 +2627,34 @@ static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStrin
              * so we have to add one '/' to the newString
              * (Sergey Zubarev)
              */
-             // No - the input strings here are URL path strings, not Win32 paths.  
-             // Absolute paths should have had a '/' prepended before this point. 
-             // I have removed Sergey Zubarev's change and left his comment (and
-             // this one) as a record. - REW, 1/5/2004
+            // No - the input strings here are URL path strings, not Win32 paths.
+            // Absolute paths should have had a '/' prepended before this point.
+            // I have removed Sergey Zubarev's change and left his comment (and
+            // this one) as a record. - REW, 1/5/2004
             
             // if the relative URL does not begin with a slash and
             // the base does not end with a slash, add a slash
             if ((basePathRg.location == kCFNotFound || basePathRg.length == 0) && CFStringGetCharacterAtIndex(newPath, 0) != '/') {
-                CFStringAppendCString(newString, "/", kCFStringEncodingASCII);
+                chars[0] = '/';
+                CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
             }
             
-            CFStringAppend(newString, newPath);
+            CFStringAppendStringToAppendBuffer(&appendBuffer, newPath);
             CFRelease(newPath);
             rg.location = relPathRg.location + relPathRg.length;
             rg.length = CFStringGetLength(relString);
             if (rg.length > rg.location) {
-                rg.length -= rg.location; 
+                rg.length -= rg.location;
                 CFStringGetCharacters(relString, rg, buf);
-                CFStringAppendCharacters(newString, buf, rg.length);
+                CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
             }
         } else {
             rg = _rangeForComponent(baseFlags, baseRanges, HAS_PATH);
             if (rg.location != kCFNotFound) {
                 CFStringGetCharacters(baseString, rg, buf);
-                CFStringAppendCharacters(newString, buf, rg.length);
+                CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
             }
-
+            
             if (!(relFlags & RESOURCE_SPECIFIER_MASK)) {
                 // ???  Can this ever happen?
                 UInt32 rsrcFlag = _firstResourceSpecifierFlag(baseFlags);
@@ -2233,47 +2664,66 @@ static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStrin
                     rg.location --; // To pick up the separator
                     rg.length ++;
                     CFStringGetCharacters(baseString, rg, buf);
-                    CFStringAppendCharacters(newString, buf, rg.length);
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
                 }
             } else if (relFlags & HAS_PARAMETERS) {
                 rg = _rangeForComponent(relFlags, relRanges, HAS_PARAMETERS);
                 rg.location --; // To get the semicolon that starts the parameters
                 rg.length = CFStringGetLength(relString) - rg.location;
                 CFStringGetCharacters(relString, rg, buf);
-                CFStringAppendCharacters(newString, buf, rg.length);
+                CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
             } else {
                 // Sigh; we have to resolve these against one another
                 rg = _rangeForComponent(baseFlags, baseRanges, HAS_PARAMETERS);
                 if (rg.location != kCFNotFound) {
-                    CFStringAppendCString(newString, ";", kCFStringEncodingASCII);
+                    chars[0] = ';';
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
                     CFStringGetCharacters(baseString, rg, buf);
-                    CFStringAppendCharacters(newString, buf, rg.length);
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
                 }
                 rg = _rangeForComponent(relFlags, relRanges, HAS_QUERY);
                 if (rg.location != kCFNotFound) {
-                    CFStringAppendCString(newString, "?", kCFStringEncodingASCII);
+                    chars[0] = '?';
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
                     CFStringGetCharacters(relString, rg, buf);
-                    CFStringAppendCharacters(newString, buf, rg.length);
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
                 } else {
                     rg = _rangeForComponent(baseFlags, baseRanges, HAS_QUERY);
                     if (rg.location != kCFNotFound) {
-                        CFStringAppendCString(newString, "?", kCFStringEncodingASCII);
+                        chars[0] = '?';
+                        CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
                         CFStringGetCharacters(baseString, rg, buf);
-                        CFStringAppendCharacters(newString, buf, rg.length);
+                        CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
                     }
                 }
                 // Only the relative portion of the URL can supply the fragment; otherwise, what would be in the relativeURL?
                 rg = _rangeForComponent(relFlags, relRanges, HAS_FRAGMENT);
                 if (rg.location != kCFNotFound) {
-                    CFStringAppendCString(newString, "#", kCFStringEncodingASCII);
+                    chars[0] = '#';
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, chars, 1);
                     CFStringGetCharacters(relString, rg, buf);
-                    CFStringAppendCharacters(newString, buf, rg.length);
+                    CFStringAppendCharactersToAppendBuffer(&appendBuffer, buf, rg.length);
                 }
             }
         }
     }
-    CFAllocatorDeallocate(alloc, buf);
-    return newString;
+    return CFStringCreateMutableWithAppendBuffer(&appendBuffer);
+}
+
+static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStringRef relString, UInt32 relFlags, CFRange *relRanges, CFStringRef baseString, UInt32 baseFlags, CFRange *baseRanges) {
+    CFMutableStringRef result;
+    CFIndex bufLen = CFStringGetLength(baseString) + CFStringGetLength(relString); // Overkill, but guarantees we never allocate again
+    if ( bufLen <= 1024 ) {
+        STACK_BUFFER_DECL(UniChar, buf, bufLen);
+        result = resolveAbsoluteURLStringBuffer(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges, buf);
+        return ( result );
+    }
+    else {
+        UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, bufLen * sizeof(UniChar), 0);
+        result = resolveAbsoluteURLStringBuffer(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges, buf);
+        CFAllocatorDeallocate(alloc, buf);
+        return ( result );
+    }
 }
 
 CFURLRef CFURLCopyAbsoluteURL(CFURLRef  relativeURL) {
@@ -2432,7 +2882,7 @@ static CFStringRef _retainedComponentString(CFURLRef url, UInt32 compFlag, Boole
             comp = CFStringCreateWithSubstring(alloc, url->_string, rg);
         }
         
-        if (!fromOriginalString) {
+        if (comp && !fromOriginalString) {
             if (!_haveTestedOriginalString(url)) {
                 computeSanitizedString(url);
             }
@@ -2442,7 +2892,7 @@ static CFStringRef _retainedComponentString(CFURLRef url, UInt32 compFlag, Boole
                 comp = newComp;
             }
         }
-        if (removePercentEscapes) {
+        if (comp && removePercentEscapes) {
             CFStringRef tmp;
             if (url->_encoding == kCFStringEncodingUTF8) {
                 tmp = CFURLCreateStringByReplacingPercentEscapes(alloc, comp, CFSTR(""));
@@ -3174,7 +3624,7 @@ static CFURLRef composeFromRFC1808(CFAllocatorRef alloc, const CFURLComponentsRF
         hadPrePathComponent = true;
     }
     if (comp->port != kCFNotFound) {
-        CFStringAppendFormat(urlString, NULL, CFSTR(":%d"), comp->port);
+        CFStringAppendFormat(urlString, NULL, CFSTR(":%ld"), (long)comp->port);
         hadPrePathComponent = true;
     }
 
@@ -3260,7 +3710,7 @@ static CFURLRef composeFromRFC2396(CFAllocatorRef alloc, const CFURLComponentsRF
     if (comp->host) {
         CFStringAppend(urlString, comp->host);
         if (comp->port != kCFNotFound) {
-            CFStringAppendFormat(urlString, NULL, CFSTR(":%d"), comp->port);
+            CFStringAppendFormat(urlString, NULL, CFSTR(":%ld"), (long)comp->port);
         }
         hadPrePathComponent = true;
     }
@@ -3336,7 +3786,7 @@ CF_EXPORT void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) {
 /* File system stuff */
 
 /* HFSPath<->URLPath functions at the bottom of the file */
-static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir) {
+static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute) {
     CFArrayRef tmp;
     CFMutableArrayRef urlComponents = NULL;
     CFIndex i=0;
@@ -3346,9 +3796,8 @@ static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef al
     CFRelease(tmp);
 
     CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(urlComponents, 0);
-    if (CFStringGetLength(str) == 2 && CFStringGetCharacterAtIndex(str, 1) == ':') {
-        CFArrayInsertValueAtIndex(urlComponents, 0, CFSTR("")); // So we get a leading '/' below
-        i = 2; // Skip over the drive letter and the empty string we just inserted
+    if (isAbsolute && CFStringGetLength(str) == 2 && CFStringGetCharacterAtIndex(str, 1) == ':') {
+        i = 1; // Skip over the drive letter 
     }
     CFIndex c;
     for (c = CFArrayGetCount(urlComponents); i < c; i ++) {
@@ -3369,15 +3818,23 @@ static CFArrayRef WindowsPathToURLComponents(CFStringRef path, CFAllocatorRef al
         if (CFStringGetLength((CFStringRef)CFArrayGetValueAtIndex(urlComponents, CFArrayGetCount(urlComponents) - 1)) != 0)
             CFArrayAppendValue(urlComponents, CFSTR(""));
     }
+    if (isAbsolute) {
+        if ( AddAuthorityToFileURL() ) {
+            CFArrayInsertValueAtIndex(urlComponents, 0, CFSTR(FILE_PREFIX_WITH_AUTHORITY));
+        }
+        else {
+            CFArrayInsertValueAtIndex(urlComponents, 0, CFSTR(FILE_PREFIX));
+        }
+    }
     return urlComponents;
 }
 
-static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir) {
+static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute) {
     CFArrayRef urlComponents;
     CFStringRef str;
 
     if (CFStringGetLength(path) == 0) return CFStringCreateWithCString(alloc, "", kCFStringEncodingASCII);
-    urlComponents = WindowsPathToURLComponents(path, alloc, isDir);
+    urlComponents = WindowsPathToURLComponents(path, alloc, isDir, isAbsolute);
     if (!urlComponents) return CFStringCreateWithCString(alloc, "", kCFStringEncodingASCII);
 
     // WindowsPathToURLComponents already added percent escapes for us; no need to add them again here.
@@ -3386,12 +3843,16 @@ static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc,
     return str;
 }
 
-static CFStringRef POSIXPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDirectory) {
-    CFStringRef pathString = _replacePathIllegalCharacters(path, alloc, true);
-    if (isDirectory && CFStringGetCharacterAtIndex(path, CFStringGetLength(path)-1) != '/') {
-        CFStringRef tmp = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@/"), pathString);
-        CFRelease(pathString);
-        pathString = tmp;
+static CFStringRef POSIXPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDirectory, Boolean isAbsolute, Boolean *posixAndUrlPathsMatch) {
+    Boolean addedPercentEncoding;
+    CFStringRef pathString = NULL;
+    STACK_BUFFER_DECL(char, buffer, PATH_MAX);
+    if ( CFStringGetFileSystemRepresentation(path, buffer, PATH_MAX) ) {
+        pathString = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)buffer, strlen(buffer), isDirectory, isAbsolute, false /* windowsPath */, &addedPercentEncoding);
+    }
+    
+    if ( posixAndUrlPathsMatch ) {
+        *posixAndUrlPathsMatch = !addedPercentEncoding;
     }
     return pathString;
 }
@@ -3406,18 +3867,25 @@ static CFStringRef URLPathToPOSIXPath(CFStringRef path, CFAllocatorRef allocator
             CFRelease(result);
             result = tmp;
         }
-        }
+    }
     return result;
-                }
+}
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
-static Boolean CanonicalFileURLStringToFileSystemRepresentation(CFStringRef str, CFAllocatorRef alloc, UInt8 *inBuffer, CFIndex inBufferLen)
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
+static Boolean CanonicalFileURLStringToFileSystemRepresentation(CFStringRef str, UInt8 *inBuffer, CFIndex inBufferLen)
 {
+    size_t fileURLPrefixLength;
+    if ( AddAuthorityToFileURL() ) {
+        fileURLPrefixLength = sizeof(fileURLPrefixWithAuthority);
+    }
+    else {
+        fileURLPrefixLength = sizeof(fileURLPrefix);
+    }
     Boolean result;
     if ( inBuffer && inBufferLen ) {
         STACK_BUFFER_DECL(UInt8, stackEscapedBuf, PATH_MAX * 3);    // worst case size is every unicode code point could be a 3-byte UTF8 sequence
         UInt8 *escapedBuf;
-        CFIndex strLength = CFStringGetLength(str) - (sizeof(fileURLPrefixWithAuthority) - 1);
+        CFIndex strLength = CFStringGetLength(str) - (fileURLPrefixLength - 1);
         if ( strLength != 0 ) {
             CFIndex maxBufLength = strLength * 3;
             CFIndex usedBufLen;
@@ -3430,7 +3898,7 @@ static Boolean CanonicalFileURLStringToFileSystemRepresentation(CFStringRef str,
                 escapedBuf = (UInt8 *)malloc(maxBufLength);
             }
             if ( escapedBuf != NULL ) {
-                charsConverted = CFStringGetBytes(str, CFRangeMake(sizeof(fileURLPrefixWithAuthority) - 1, strLength), kCFStringEncodingUTF8, 0, false, escapedBuf, maxBufLength, &usedBufLen);
+                charsConverted = CFStringGetBytes(str, CFRangeMake(fileURLPrefixLength - 1, strLength), kCFStringEncodingUTF8, 0, false, escapedBuf, maxBufLength, &usedBufLen);
                 if ( charsConverted ) {
                     static const UInt8 hexvalues[] = {
                         /* 00 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
@@ -3621,61 +4089,6 @@ static CFStringRef URLPathToWindowsPath(CFStringRef path, CFAllocatorRef allocat
 
 
 
-// converts url from a file system path representation to a standard representation
-static void _convertToURLRepresentation(struct __CFURL *url, UInt32 fsType) {
-    CFStringRef path = NULL;
-    Boolean isDir = ((url->_flags & IS_DIRECTORY) != 0);
-    Boolean isFileReferencePath = false;
-    CFAllocatorRef alloc = CFGetAllocator(url);
-    
-    switch (fsType) {
-        case kCFURLPOSIXPathStyle:
-            isFileReferencePath = _pathHasFileIDPrefix(url->_string);
-            if (url->_flags & POSIX_AND_URL_PATHS_MATCH) {
-                path = (CFStringRef)CFRetain(url->_string);
-            } else {
-                path = POSIXPathToURLPath(url->_string, alloc, isDir);
-            }
-            break;
-        case kCFURLWindowsPathStyle:
-            path = WindowsPathToURLPath(url->_string, alloc, isDir);
-            break;
-    }
-    CFAssert2(path != NULL, __kCFLogAssertion, "%s(): Encountered malformed file system URL %@", __PRETTY_FUNCTION__, url);
-    if ( path )
-    {
-        if (!url->_base) {
-            CFMutableStringRef str = CFStringCreateMutable(alloc, 0);
-            CFStringAppend(str, isFileReferencePath ? CFSTR(FILE_PREFIX) : CFSTR(FILE_PREFIX_WITH_AUTHORITY));
-            CFStringAppend(str, path);
-            url->_flags = (url->_flags & (IS_DIRECTORY)) | IS_DECOMPOSABLE | IS_ABSOLUTE | HAS_SCHEME | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | ( isFileReferencePath ? PATH_HAS_FILE_ID : HAS_HOST );
-            _setSchemeTypeInFlags(&url->_flags, kHasFileScheme);
-            CFRelease(url->_string);
-            url->_string = CFStringCreateCopy(alloc, str);
-            CFRelease(str);
-            if (isFileReferencePath) {
-                url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 2, 0);
-                url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
-                url->_ranges[1] = CFRangeMake(7, CFStringGetLength(path)); // path
-            }
-            else {
-                url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 3, 0);
-                url->_ranges[0] = CFRangeMake(0, 4); // scheme "file"
-                url->_ranges[1] = CFRangeMake(7, 9); // host "localhost"
-                url->_ranges[2] = CFRangeMake(16, CFStringGetLength(path)); // path
-            }
-            CFRelease(path);
-        } else {
-            CFRelease(url->_string);
-            url->_flags = (url->_flags & (IS_DIRECTORY)) | IS_DECOMPOSABLE | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH;
-            url->_string = CFStringCreateCopy(alloc, path);
-            CFRelease(path);
-            url->_ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
-            *(url->_ranges) = CFRangeMake(0, CFStringGetLength(url->_string));
-        }
-    }
-}
-
 // Caller must release the returned string
 static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef basePath, Boolean baseIsDir, CFURLPathStyle fsType, CFAllocatorRef alloc) {
     CFIndex baseLen = CFStringGetLength(basePath);
@@ -3695,7 +4108,10 @@ static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef
         }
         baseLen = ptr - buf + 1;
     }
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
     if (fsType == kCFURLHFSPathStyle) {
+#pragma GCC diagnostic pop
         // HFS relative paths will begin with a colon, so we must remove the trailing colon from the base path first.
         baseLen --;
     }
@@ -3714,185 +4130,31 @@ CFURLRef _CFURLCreateCurrentDirectoryURL(CFAllocatorRef allocator) {
 }
 
 CFURLRef CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle fsType, Boolean isDirectory) {
-    Boolean isAbsolute = true;
-    CFIndex len;
-    CFURLRef baseURL, result;
-
-    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
+    CFURLRef result;
     
-    CFAssert1(filePath != NULL, __kCFLogAssertion, "%s(): NULL filePath argument not permitted", __PRETTY_FUNCTION__);
-
-       len = CFStringGetLength(filePath);
-       
-    switch(fsType) {
-        case kCFURLPOSIXPathStyle:
-            isAbsolute = (len > 0 && CFStringGetCharacterAtIndex(filePath, 0) == '/');
-            break;
-        case kCFURLWindowsPathStyle:
-            isAbsolute = (len >= 3 && CFStringGetCharacterAtIndex(filePath, 1) == ':' && CFStringGetCharacterAtIndex(filePath, 2) == '\\');
-           /* Absolute path under Win32 can begin with "\\"
-            * (Sergey Zubarev)
-            */
-            if (!isAbsolute) isAbsolute = (len > 2 && CFStringGetCharacterAtIndex(filePath, 0) == '\\' && CFStringGetCharacterAtIndex(filePath, 1) == '\\');
-            break;
-        case kCFURLHFSPathStyle:
-            isAbsolute = (len > 0 && CFStringGetCharacterAtIndex(filePath, 0) != ':');
-            break;
-    }
-    if (isAbsolute) {
-        baseURL = NULL;
-    } else {
-        baseURL = _CFURLCreateCurrentDirectoryURL(allocator);
+    result = _CFURLAlloc(allocator);
+    if ( result ) {
+        if ( !_CFURLInitWithFileSystemPath(result, filePath, fsType, isDirectory, NULL) ) {
+            CFRelease(result);
+            result = NULL;
+        }
     }
-    result = CFURLCreateWithFileSystemPathRelativeToBase(allocator, filePath, fsType, isDirectory, baseURL);
-    if (baseURL) CFRelease(baseURL);
-    return result;
+    
+    return ( result );
 }
 
 CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef allocator, CFStringRef filePath, CFURLPathStyle fsType, Boolean isDirectory, CFURLRef baseURL) {
-    CFURLRef url;
-    Boolean isAbsolute = true, releaseFilePath = false, releaseBaseURL = false;
-    UniChar pathDelim = '\0';
-    CFIndex len;
-
-    CFAssert1(filePath != NULL, __kCFLogAssertion, "%s(): NULL path string not permitted", __PRETTY_FUNCTION__);
-    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
+    CFURLRef result;
     
-       len = CFStringGetLength(filePath);
-
-    switch(fsType) {
-        case kCFURLPOSIXPathStyle:
-            isAbsolute = (len > 0 && CFStringGetCharacterAtIndex(filePath, 0) == '/');
-                       
-            pathDelim = '/';
-            break;
-        case kCFURLWindowsPathStyle: 
-            isAbsolute = (len >= 3 && CFStringGetCharacterAtIndex(filePath, 1) == ':' && CFStringGetCharacterAtIndex(filePath, 2) == '\\');
-           /* Absolute path under Win32 can begin with "\\"
-            * (Sergey Zubarev)
-            */
-            if (!isAbsolute)
-                isAbsolute = (len > 2 && CFStringGetCharacterAtIndex(filePath, 0) == '\\' && CFStringGetCharacterAtIndex(filePath, 1) == '\\');
-             pathDelim = '\\';
-            break;
-        case kCFURLHFSPathStyle: 
-               {       CFRange fullStrRange = CFRangeMake( 0, CFStringGetLength( filePath ) );
-               
-            isAbsolute = (len > 0 && CFStringGetCharacterAtIndex(filePath, 0) != ':');
-            pathDelim = ':';
-                       
-                       if ( filePath && CFStringFindWithOptions( filePath, CFSTR("::"), fullStrRange, 0, NULL ) ) {
-                               UniChar *       chars = (UniChar *) malloc( fullStrRange.length * sizeof( UniChar ) );
-                               CFIndex index, writeIndex, firstColonOffset = -1;
-                                                               
-                               CFStringGetCharacters( filePath, fullStrRange, chars );
-
-                               for ( index = 0, writeIndex = 0 ; index < fullStrRange.length; index ++ ) {
-                                       if ( chars[ index ] == ':' ) {
-                                               if ( index + 1 < fullStrRange.length && chars[ index + 1 ] == ':' ) {
-
-                                                       // Don't let :: go off the 'top' of the path -- which means that there always has to be at
-                                                       //      least one ':' to the left of the current write position to go back to.
-                                                       if ( writeIndex > 0 && firstColonOffset >= 0 )
-                                                       {
-                                                               writeIndex --;
-                                                               while ( writeIndex > 0 && writeIndex >= firstColonOffset && chars[ writeIndex ] != ':' )
-                                                                       writeIndex --;
-                                                       }
-                                                       index ++;       // skip over the first ':', so we replace the ':' which is there with a new one
-                                               }
-                                               
-                                               if ( firstColonOffset == -1 )
-                                                       firstColonOffset = writeIndex;
-                                       }
-                                       
-                                       chars[ writeIndex ++ ] = chars[ index ];
-                               }
-                                                               
-                               if ( releaseFilePath && filePath )
-                                       CFRelease( filePath );
-
-                               filePath = CFStringCreateWithCharacters( allocator, chars, writeIndex );
-                               // reset len because a canonical HFS path can be a different length than the original CFString
-                               len = CFStringGetLength(filePath);
-                               releaseFilePath = true;
-                               
-                               free( chars );
-                       }
-                       
-            break;
-               }
-    }
-    if (isAbsolute) {
-        baseURL = NULL;
-    }
-    else if ( baseURL == NULL ) {
-        baseURL = _CFURLCreateCurrentDirectoryURL(allocator);
-        releaseBaseURL = true;
-    }
-
-       
-    if (isDirectory && len > 0 && CFStringGetCharacterAtIndex(filePath, len-1) != pathDelim) {
-        CFMutableStringRef tempRef = CFStringCreateMutable(allocator, 0);
-       CFStringAppend(tempRef, filePath);
-       CFStringAppendCharacters(tempRef, &pathDelim, 1);
-       if ( releaseFilePath && filePath ) CFRelease( filePath );
-       filePath = tempRef;
-        releaseFilePath = true;
-    } else if (!isDirectory && len > 0 && CFStringGetCharacterAtIndex(filePath, len-1) == pathDelim) {
-        if (len == 1 || CFStringGetCharacterAtIndex(filePath, len-2) == pathDelim) {
-            // Override isDirectory
-            isDirectory = true;
-        } else {
-            CFStringRef tempRef = CFStringCreateWithSubstring(allocator, filePath, CFRangeMake(0, len-1));
-                       if ( releaseFilePath && filePath )
-                               CFRelease( filePath );
-                       filePath = tempRef;
-            releaseFilePath = true;
-        }
-    }
-    if (!filePath || CFStringGetLength(filePath) == 0) {
-        if (releaseFilePath && filePath) CFRelease(filePath);
-        if (releaseBaseURL && baseURL) CFRelease(baseURL);
-        return NULL;
-    }
-    url = _CFURLAlloc(allocator);
-    _CFURLInit((struct __CFURL *)url, filePath, fsType, baseURL);
-    if (releaseFilePath) CFRelease(filePath);
-    if (releaseBaseURL && baseURL) CFRelease(baseURL);
-    if (isDirectory) ((struct __CFURL *)url)->_flags |= IS_DIRECTORY;
-    if (fsType == kCFURLPOSIXPathStyle) {
-        // Check if relative path is equivalent to URL representation; this will be true if url->_string contains only characters from the unreserved character set, plus '/' to delimit the path, plus ';', '@', '&', '=', '+', '$', ',' (according to RFC 2396) -- REW, 12/1/2000
-        // Per Section 5 of RFC 2396, there's a special problem if a colon apears in the first path segment - in this position, it can be mistaken for the scheme name.  Otherwise, it's o.k., and can be safely identified as part of the path.  In this one case, we need to prepend "./" to make it clear what's going on.... -- REW, 8/24/2001
-        CFStringInlineBuffer buf;
-        Boolean sawSlash = FALSE;
-        Boolean mustPrependDotSlash = FALSE;
-        CFIndex idx, length = CFStringGetLength(url->_string);
-        CFStringInitInlineBuffer(url->_string, &buf, CFRangeMake(0, length));
-        for (idx = 0; idx < length; idx ++) {
-            UniChar ch = CFStringGetCharacterFromInlineBuffer(&buf, idx);
-            if (!isPathLegalCharacter(ch)) break;
-            if (!sawSlash) {
-                if (ch == '/') {
-                    sawSlash = TRUE;
-                } else if (ch == ':') {
-                    mustPrependDotSlash = TRUE;
-                }
-            }
-        }
-        if (idx == length) {
-            ((struct __CFURL *)url)->_flags |= POSIX_AND_URL_PATHS_MATCH;
-        }
-        if (mustPrependDotSlash) {
-            CFMutableStringRef newString = CFStringCreateMutable(allocator, 0);
-           CFStringAppend(newString, CFSTR("./"));
-           CFStringAppend(newString, url->_string);
-            CFRelease(url->_string);
-            ((struct __CFURL *)url)->_string = CFStringCreateCopy(allocator, newString);
-            CFRelease(newString);
+    result = _CFURLAlloc(allocator);
+    if ( result ) {
+        if ( !_CFURLInitWithFileSystemPath(result, filePath, fsType, isDirectory, baseURL) ) {
+            CFRelease(result);
+            result = NULL;
         }
     }
-    return url;
+    
+    return ( result );
 }
 
 static Boolean _pathHasFileIDPrefix( CFStringRef path )
@@ -3915,11 +4177,36 @@ static Boolean _pathHasFileIDOnly( CFStringRef path )
 #endif
 
 CF_EXPORT CFStringRef CFURLCopyFileSystemPath(CFURLRef anURL, CFURLPathStyle pathStyle) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
     CFAssert2(pathStyle == kCFURLPOSIXPathStyle || pathStyle == kCFURLHFSPathStyle || pathStyle == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): Encountered unknown path style %d", __PRETTY_FUNCTION__, pathStyle);
+#pragma GCC diagnostic pop
     
-    CFStringRef result;
+    CFStringRef result = NULL;
+    CFAllocatorRef alloc = CFGetAllocator(anURL);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
+    Boolean isCanonicalFileURL = false;
+    
+    if ( (pathStyle == kCFURLPOSIXPathStyle) && (CFURLGetBaseURL(anURL) == NULL) ) {
+        if ( !CF_IS_OBJC(__kCFURLTypeID, anURL) ) {
+            // We can grope the ivars
+            isCanonicalFileURL = ((anURL->_flags & IS_CANONICAL_FILE_URL) != 0);
+            if ( isCanonicalFileURL ) {
+                STACK_BUFFER_DECL(UInt8, buffer, PATH_MAX + 1);
+                if ( CanonicalFileURLStringToFileSystemRepresentation(anURL->_string, buffer, PATH_MAX + 1) ) {
+                    result = CFStringCreateWithBytes(alloc, buffer, strlen((char *)buffer), kCFStringEncodingUTF8, false);
+                }
+            }
+        }
+    }
+    if ( ! result ) {
+        // fall back to slower way.
+        result = CFURLCreateStringWithFileSystemPath(alloc, anURL, pathStyle, false);
+    }
+#else // !DEPLOYMENT_TARGET_MACOSX
+    result = CFURLCreateStringWithFileSystemPath(alloc, anURL, pathStyle, false);
+#endif // !DEPLOYMENT_TARGET_MACOSX
     
-    result = CFURLCreateStringWithFileSystemPath(CFGetAllocator(anURL), anURL, pathStyle, false);
     return ( result );
 }
 
@@ -3947,7 +4234,10 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
                 case kCFURLPOSIXPathStyle:
                     relPath = URLPathToPOSIXPath(urlPath, allocator, enc);
                     break;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
                 case kCFURLHFSPathStyle:
+#pragma GCC diagnostic pop
                    relPath = NULL;
                     break;
                 case kCFURLWindowsPathStyle:
@@ -3971,15 +4261,18 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
     }
     
     if ( relPath ) {
-        if ( basePath ) {
-            // we have both basePath and relPath -- resolve them
+        if ( basePath && (CFStringGetCharacterAtIndex(relPath, 0) != '/') ) {
+            // we have both basePath and relPath, and relPath is not absolute -- resolve them
             CFStringRef result = _resolveFileSystemPaths(relPath, basePath, CFURLHasDirectoryPath(base), fsType, allocator);
             CFRelease(basePath);
             CFRelease(relPath);
             return result;
         }
         else {
-            // we only have the relPath -- return it
+            // we only have the relPath or relpath is absolute -- return it
+            if ( basePath ) {
+                CFRelease(basePath);
+            }
             return relPath;
         }
     }
@@ -3994,18 +4287,18 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
 }
 
 Boolean CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, uint8_t *buffer, CFIndex bufLen) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
     CFAllocatorRef alloc = CFGetAllocator(url);
     CFStringRef path;
 
     if (!url) return false;
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
     if ( !resolveAgainstBase || (CFURLGetBaseURL(url) == NULL) ) {
         if (!CF_IS_OBJC(__kCFURLTypeID, url)) {
             // We can grope the ivars
             if ( url->_flags & IS_CANONICAL_FILE_URL ) {
-                return CanonicalFileURLStringToFileSystemRepresentation(url->_string, alloc, buffer, bufLen);
+                return CanonicalFileURLStringToFileSystemRepresentation(url->_string, buffer, bufLen);
             }
         }
     }
@@ -4055,209 +4348,32 @@ CF_EXPORT Boolean _CFURLGetWideFileSystemRepresentation(CFURLRef url, Boolean re
 }
 #endif
 
-static CFStringRef _createPathFromFileSystemRepresentation(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory) {
-    char pathDelim = PATH_SEP;
-    CFStringRef path;
-    if ( isDirectory ) {
-       // it is a directory: if it doesn't end with pathDelim, append a pathDelim. Limit stack buffer to PATH_MAX+1 in case a large bogus value is passed.
-       if ( (bufLen > 0) && (bufLen <= PATH_MAX) && (buffer[bufLen-1] != pathDelim) ) {
-           STACK_BUFFER_DECL(uint8_t, tempBuf, bufLen + 1);
-           memcpy(tempBuf, buffer, bufLen);
-           tempBuf[bufLen] = pathDelim;
-           path = CFStringCreateWithBytes(allocator, tempBuf, bufLen + 1, CFStringFileSystemEncoding(), false);
-       }
-       else {
-           // already had pathDelim at end of buffer or bufLen is really large
-           path = CFStringCreateWithBytes(allocator, buffer, bufLen, CFStringFileSystemEncoding(), false);
-       }
-    }
-    else {
-       // it is not a directory: remove any pathDelim characters at end (leaving at least one character)
-       while ( (bufLen > 1) && (buffer[bufLen-1] == pathDelim) ) {
-           --bufLen;
-       }
-       path = CFStringCreateWithBytes(allocator, buffer, bufLen, CFStringFileSystemEncoding(), false);
-    }
-    return path;
-}
-
-/*
- CreatePOSIXFileURLStringFromPOSIXAbsolutePath creates file URL string from the native file system representation.
- The rules for path-absolute from rfc3986 are:
- path-absolute = "/" [ segment-nz *( "/" segment ) ]
- segment       = *pchar
- segment-nz    = 1*pchar
- pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
- pct-encoded   = "%" HEXDIG HEXDIG
- unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
- sub-delims    = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
- */
-static CFStringRef CreatePOSIXFileURLStringFromPOSIXAbsolutePath(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, Boolean isDirectory, Boolean *addedPercentEncoding)
-{
-    static const UInt8 hexchars[] = "0123456789ABCDEF";
-    STACK_BUFFER_DECL(UInt8, stackBuf, (PATH_MAX * 3) + sizeof(fileURLPrefixWithAuthority));    // worst case is every byte needs to be percent-escaped
-    UInt8 *bufStartPtr;
-    UInt8 *bufBytePtr;
-    const UInt8 *bytePtr = bytes;
-    CFIndex idx;
-    CFStringRef result;
-    Boolean addedPercent = FALSE;
-    
-    // choose a buffer to percent-escape into.
-    if ( numBytes <= PATH_MAX ) {
-        bufStartPtr = &stackBuf[0];
-    }
-    else {
-        // worst case is every byte needs to be percent-escaped (numBytes * 3)
-        bufStartPtr = (UInt8 *)malloc((numBytes * 3) + sizeof(fileURLPrefixWithAuthority));
-    }
+CFURLRef CFURLCreateFromFileSystemRepresentation(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory) {
+    CFURLRef result;
     
-    if ( bufStartPtr != NULL ) {
-        // start with the fileURLPrefixWithAuthority
-        strcpy((char *)bufStartPtr, (char *)fileURLPrefixWithAuthority);
-        bufBytePtr = bufStartPtr + sizeof(fileURLPrefixWithAuthority) - 1;
-        // append the percent-escaped path
-        for ( idx = 0; (idx < numBytes) && (*bytePtr != 0); ++idx ) {
-            switch ( *bytePtr ) {
-                    // these are the visible 7-bit ascii characters that are not legal pchar octets
-                case '"':
-                case '#':
-                case '%':
-                case ';':      // we need to percent-escape ';' in file system paths so it won't be mistaken for the start of the obsolete param rule (rfc2396) that CFURL still supports
-                case '<':
-                case '>':
-                case '?':      // we need to percent-escape '?' in file system paths so it won't be mistaken for the start of a query
-                case '[':
-                case '\\':
-                case ']':
-                case '^':
-                case '`':
-                case '{':
-                case '|':
-                case '}':
-                    // percent-escape non-pchar octets spread throughout the visible 7-bit ascii range
-                    *bufBytePtr++ = '%';
-                    *bufBytePtr++ = hexchars[*bytePtr >> 4];
-                    *bufBytePtr++ = hexchars[*bytePtr & 0x0f];
-                    addedPercent = TRUE;
-                    break;
-                default:
-                    if ( (*bytePtr <= ' ') ||  // percent-escape non-pchar octets that are space or less (control characters)
-                        (*bytePtr >= 0x7f) ) { // percent-escape non-pchar octets that del and 8-bit ascii with the high bit set
-                        *bufBytePtr++ = '%';
-                        *bufBytePtr++ = hexchars[*bytePtr >> 4];
-                        *bufBytePtr++ = hexchars[*bytePtr & 0x0f];
-                        addedPercent = TRUE;
-                    }
-                    else {
-                        // copy everything else
-                        *bufBytePtr++ = *bytePtr;
-                    }
-                    break;
-            }
-            ++bytePtr;
-        }
-        
-        // did we convert numBytes?
-        if ( idx == numBytes ) {
-            // if it is a directory and it doesn't end with PATH_SEP, append a PATH_SEP.
-            if ( isDirectory && bytes[numBytes-1] != PATH_SEP) {
-                *bufBytePtr++ = PATH_SEP;
-            }
-            
-            // create the result
-            result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), __CFStringGetEightBitStringEncoding(), FALSE);
-        }
-        else {
-            // no, but it's OK if the remaining bytes are all nul (embedded nul bytes are not allowed)
-            const UInt8 *nullBytePtr = bytePtr;
-            for ( /* start where we left off */; (idx < numBytes) && (*nullBytePtr == '\0'); ++idx, ++nullBytePtr ) {
-                // do nothing
-            }
-            if ( idx == numBytes ) {
-                // create the result
-                result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), __CFStringGetEightBitStringEncoding(), FALSE);
-            }
-            else {
-                // the remaining bytes were not all nul
-                result = NULL;
-            }
-        }
-        // free the buffer if we malloc'd it
-        if ( bufStartPtr != &stackBuf[0] ) {
-            free(bufStartPtr);
+    result = _CFURLAlloc(allocator);
+    if ( result ) {
+        if ( !_CFURLInitWithFileSystemRepresentation(result, buffer, bufLen, isDirectory, NULL) ) {
+            CFRelease(result);
+            result = NULL;
         }
     }
-    else {
-        result = NULL;
-    }
-    
-    if ( addedPercentEncoding ) {
-        *addedPercentEncoding = addedPercent;
-    }
     
     return ( result );
 }
 
-CFURLRef CFURLCreateFromFileSystemRepresentation(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory) {
-    CFURLRef newURL = NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
-    if ( bufLen && (*buffer == '/') ) {
-        Boolean addedPercentEncoding;
-        
-        CFStringRef urlStr = CreatePOSIXFileURLStringFromPOSIXAbsolutePath(allocator, buffer, bufLen, isDirectory, &addedPercentEncoding);
-        if ( urlStr ) {
-            newURL = _CFURLAlloc(allocator);
-            if ( newURL ) {
-                ((struct __CFURL *)newURL)->_flags |= USES_EIGHTBITSTRINGENCODING;
-                // we know urlStr has a scheme and is absolute 
-                _CFURLInit((struct __CFURL *)newURL, urlStr, FULL_URL_REPRESENTATION, NULL);
-                ((struct __CFURL *)newURL)->_flags |= (IS_ABSOLUTE | IS_CANONICAL_FILE_URL);
-                if ( !addedPercentEncoding ) {
-                    ((struct __CFURL *)newURL)->_flags |= POSIX_AND_URL_PATHS_MATCH;
-                }
-            }
-            CFRelease(urlStr);
-        }
-        else {
-            newURL = NULL;
-        }
-    }
-    else {
-        CFStringRef path = _createPathFromFileSystemRepresentation(allocator, buffer, bufLen, isDirectory);
-        if ( path ) {
-            newURL = CFURLCreateWithFileSystemPath(allocator, path, kCFURLPOSIXPathStyle, isDirectory);
-            CFRelease(path);
-        }
-        else {
-            newURL = NULL;
+CF_EXPORT CFURLRef CFURLCreateFromFileSystemRepresentationRelativeToBase(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory, CFURLRef baseURL) {
+    CFURLRef result;
+    
+    result = _CFURLAlloc(allocator);
+    if ( result ) {
+        if ( !_CFURLInitWithFileSystemRepresentation(result, buffer, bufLen, isDirectory, baseURL) ) {
+            CFRelease(result);
+            result = NULL;
         }
     }
-#elif DEPLOYMENT_TARGET_WINDOWS
-    CFStringRef path = _createPathFromFileSystemRepresentation(allocator, buffer, bufLen, isDirectory);
-    if ( path ) {
-        newURL = CFURLCreateWithFileSystemPath(allocator, path, kCFURLWindowsPathStyle, isDirectory);
-        CFRelease(path);
-    }
-    else {
-        newURL = NULL;
-    }
-#endif
-    return newURL;
-}
-
-CF_EXPORT CFURLRef CFURLCreateFromFileSystemRepresentationRelativeToBase(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory, CFURLRef baseURL) {
-    CFStringRef path = _createPathFromFileSystemRepresentation(allocator, buffer, bufLen, isDirectory);
-    CFURLRef newURL = NULL;
-    if (!path) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
-    newURL = CFURLCreateWithFileSystemPathRelativeToBase(allocator, path, kCFURLPOSIXPathStyle, isDirectory, baseURL);
-#elif DEPLOYMENT_TARGET_WINDOWS
-    newURL = CFURLCreateWithFileSystemPathRelativeToBase(allocator, path, kCFURLWindowsPathStyle, isDirectory, baseURL);
-#endif
-    CFRelease(path);
-    return newURL;
+    
+    return ( result );
 }
 
 
@@ -4324,7 +4440,7 @@ CFStringRef CFURLCopyLastPathComponent(CFURLRef url) {
     } else {
         Boolean filePathURLCreated = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-        if ( _CFURLIsFileReferenceURL(url) ) {
+        if ( CFURLIsFileReferenceURL(url) ) {
             // use a file path URL or fail
             CFURLRef filePathURL = CFURLCreateFilePathURL(CFGetAllocator(url), url, NULL);
             if ( filePathURL ) {
@@ -4397,7 +4513,7 @@ CFURLRef CFURLCreateCopyAppendingPathComponent(CFAllocatorRef allocator, CFURLRe
 
     Boolean filePathURLCreated = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    if ( _CFURLIsFileReferenceURL(url) ) {
+    if ( CFURLIsFileReferenceURL(url) ) {
         // use a file path URL if possible (only because this is appending a path component)
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
         if ( filePathURL ) {
@@ -4447,7 +4563,7 @@ CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFUR
 
     Boolean filePathURLCreated = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    if ( _CFURLIsFileReferenceURL(url) ) {
+    if ( CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
         if ( filePathURL ) {
@@ -4524,7 +4640,7 @@ CFURLRef CFURLCreateCopyAppendingPathExtension(CFAllocatorRef allocator, CFURLRe
 
     Boolean filePathURLCreated = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    if ( _CFURLIsFileReferenceURL(url) ) {
+    if ( CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
         if ( filePathURL ) {
@@ -4568,7 +4684,7 @@ CFURLRef CFURLCreateCopyDeletingPathExtension(CFAllocatorRef allocator, CFURLRef
     
     Boolean filePathURLCreated = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    if ( _CFURLIsFileReferenceURL(url) ) {
+    if ( CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
         if ( filePathURL ) {
@@ -4694,7 +4810,7 @@ static CFStringRef escapePathComponent(CFAllocatorRef alloc, CFStringRef origCom
     return CFURLCreateStringByAddingPercentEscapes(alloc, origComponent, NULL, CFSTR(";?/"), kCFStringEncodingUTF8);
 }
 
-static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir) {
+static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir, Boolean isAbsolute) {
     CFArrayRef components = HFSPathToURLComponents(path, alloc, isDir);
     CFArrayRef newComponents = components ? copyStringArrayWithTransformation(components, escapePathComponent) : NULL;
     CFIndex cnt;
@@ -4708,6 +4824,16 @@ static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Bool
     } else {
         result = CFStringCreateByCombiningStrings(alloc, newComponents, CFSTR("/"));
     }
+    if ( isAbsolute && result )  {
+        CFStringRef temp = result;
+        if ( AddAuthorityToFileURL() ) {
+            result = CFStringCreateWithFormat(alloc, 0, CFSTR(FILE_PREFIX_WITH_AUTHORITY "%@"), temp);
+        }
+        else {
+            result = CFStringCreateWithFormat(alloc, 0, CFSTR(FILE_PREFIX "%@"), temp);
+        }
+        CFRelease(temp);
+    }
     CFRelease(newComponents);
     return result;
 }
@@ -4802,7 +4928,10 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp
         return NULL;
     }
     urlTypeNum = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("_CFURLStringType"));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
     if (!urlTypeNum || CFGetTypeID(urlTypeNum) != CFNumberGetTypeID() || !CFNumberGetValue(urlTypeNum, kCFNumberSInt32Type, &urlType) || (urlType != FULL_URL_REPRESENTATION && urlType != kCFURLPOSIXPathStyle && urlType != kCFURLHFSPathStyle && urlType != kCFURLWindowsPathStyle)) {
+#pragma GCC diagnostic pop
         return NULL;
     }
     baseString = (CFStringRef)CFDictionaryGetValue(dict, CFSTR("_CFURLBaseURLString"));
@@ -4811,8 +4940,11 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp
             return NULL;
         }
         baseTypeNum = (CFNumberRef)CFDictionaryGetValue(dict, CFSTR("_CFURLBaseStringType"));
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
         if (!baseTypeNum || CFGetTypeID(baseTypeNum) != CFNumberGetTypeID() || !CFNumberGetValue(baseTypeNum, kCFNumberSInt32Type, &baseType) ||
             (baseType != FULL_URL_REPRESENTATION && baseType != kCFURLPOSIXPathStyle && baseType != kCFURLHFSPathStyle && baseType != kCFURLWindowsPathStyle)) {
+#pragma GCC diagnostic pop
             return NULL;
         }
         if (baseType == FULL_URL_REPRESENTATION) {
@@ -4832,19 +4964,24 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 Boolean _CFURLIsFileReferenceURL(CFURLRef url)
+{
+    return ( CFURLIsFileReferenceURL(url) );
+}
+
+Boolean CFURLIsFileReferenceURL(CFURLRef url)
 {
     // returns TRUE if url is is a file URL whose path starts with a file ID reference
     Boolean result = false;
     CFURLRef baseURL = CFURLGetBaseURL(url);
     if ( baseURL ) {
-       result = _CFURLIsFileReferenceURL(baseURL);
+       result = CFURLIsFileReferenceURL(baseURL);
     }
     else {
         if ( CF_IS_OBJC(__kCFURLTypeID, url) ) {
             result = (Boolean) CF_OBJC_CALLV((NSURL *)url, isFileReferenceURL);
         }
         else {
-            result = ((_getSchemeTypeFromFlags(url->_flags) == kHasFileScheme) && (url->_flags & PATH_HAS_FILE_ID));
+            result = ((_getSchemeTypeFromFlags(url->_flags) == kHasFileScheme) && ((url->_flags & PATH_HAS_FILE_ID) != 0));
         }
     }
     return ( result );
@@ -4928,7 +5065,7 @@ CFURLRef CFURLCreateFilePathURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *
        }
        if ( fsPath ) {
            CFStringRef urlPath = _replacePathIllegalCharacters( fsPath, alloc, true );
-           newURLString = CFStringCreateWithFormat( alloc, NULL, CFSTR("file://%@%@%@%@"), (netLoc ? netLoc : CFSTR("")), urlPath, ((CFStringCompare(urlPath, CFSTR("/"), 0) != kCFCompareEqualTo) ? (CFURLHasDirectoryPath( url ) ? CFSTR("/") : CFSTR("")) : CFSTR("")), (rSpec ? rSpec : CFSTR("")));
+           newURLString = CFStringCreateWithFormat( alloc, NULL, CFSTR(FILE_PREFIX "%@%@%@%@"), (netLoc ? netLoc : CFSTR("")), urlPath, ((CFStringCompare(urlPath, CFSTR("/"), 0) != kCFCompareEqualTo) ? (CFURLHasDirectoryPath( url ) ? CFSTR("/") : CFSTR("")) : CFSTR("")), (rSpec ? rSpec : CFSTR("")));
            result = CFURLCreateWithString( alloc, newURLString, NULL );
            CFRelease( newURLString );
            CFRelease( urlPath );
diff --git a/CFURL.h b/CFURL.h
index 8eeb52523677ab6486819c24e83f8d56fe38b006..406ce5c40783bd06964c4e7b989d8366fc4e64d9 100644 (file)
--- a/CFURL.h
+++ b/CFURL.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFURL.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFURL__)
@@ -38,7 +38,7 @@ CF_EXTERN_C_BEGIN
 
 typedef CF_ENUM(CFIndex, CFURLPathStyle) {
     kCFURLPOSIXPathStyle = 0,
-    kCFURLHFSPathStyle, /* The use of kCFURLHFSPathStyle is deprecated. The Carbon File Manager, which uses HFS style paths, is deprecated. HFS style paths are unreliable because they can arbitrarily refer to multiple volumes if those volumes have identical volume names. You should instead use kCFURLPOSIXPathStyle wherever possible. */
+    kCFURLHFSPathStyle CF_ENUM_DEPRECATED(10_0, 10_9, 2_0, 7_0), /* The use of kCFURLHFSPathStyle is deprecated. The Carbon File Manager, which uses HFS style paths, is deprecated. HFS style paths are unreliable because they can arbitrarily refer to multiple volumes if those volumes have identical volume names. You should instead use kCFURLPOSIXPathStyle wherever possible. */
     kCFURLWindowsPathStyle
 };
     
@@ -63,6 +63,11 @@ CFTypeID CFURLGetTypeID(void);
 
 /* encoding will be used both to interpret the bytes of URLBytes, and to */
 /* interpret any percent-escapes within the bytes. */
+/* Using a string encoding which isn't a superset of ASCII encoding is not */
+/* supported because CFURLGetBytes and CFURLGetByteRangeForComponent require */
+/* 7-bit ASCII characters to be stored in a single 8-bit byte. */
+/* CFStringEncodings which are a superset of ASCII encoding include MacRoman, */
+/* WindowsLatin1, ISOLatin1, NextStepLatin, ASCII, and UTF8. */
 CF_EXPORT
 CFURLRef CFURLCreateWithBytes(CFAllocatorRef allocator, const UInt8 *URLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL);
 
@@ -87,7 +92,12 @@ CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef URLString,
 /* in relative portion, leading "../" components are removed from the */
 /* final URL's path, and if the relative portion contains only */
 /* resource specifier pieces (query, parameters, and fragment), then */
-/* the last path component of the base URL will not be deleted  */
+/* the last path component of the base URL will not be deleted.  */
+/* Using a string encoding which isn't a superset of ASCII encoding is not */
+/* supported because CFURLGetBytes and CFURLGetByteRangeForComponent require */
+/* 7-bit ASCII characters to be stored in a single 8-bit byte. */
+/* CFStringEncodings which are a superset of ASCII encoding include MacRoman, */
+/* WindowsLatin1, ISOLatin1, NextStepLatin, ASCII, and UTF8. */
 CF_EXPORT
 CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *relativeURLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL, Boolean useCompatibilityMode);
 
@@ -412,6 +422,18 @@ CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CF
 #if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION
 CF_IMPLICIT_BRIDGING_DISABLED
 
+/*
+    CFURLIsFileReferenceURL
+
+    Returns whether the URL is a file reference URL.
+
+    Parameters
+        url
+            The URL specifying the resource.
+ */
+CF_EXPORT
+Boolean CFURLIsFileReferenceURL(CFURLRef url) CF_AVAILABLE(10_9, 7_0);
+
 /*
     CFURLCreateFileReferenceURL
     
@@ -797,6 +819,10 @@ CF_EXPORT
 const CFStringRef kCFURLIsExcludedFromBackupKey CF_AVAILABLE(10_8, 5_1);
     /* true if resource should be excluded from backups, false otherwise (Read-write, value type CFBoolean). This property is only useful for excluding cache and other application support files which are not needed in a backup. Some operations commonly made to user documents will cause this property to be reset to false and so this property should not be used on user documents. */
 
+CF_EXPORT
+const CFStringRef kCFURLTagNamesKey CF_AVAILABLE(10_9, NA);
+    /* The array of Tag names (Read-write, value type CFArray of CFString) */
+    
 CF_EXPORT
 const CFStringRef kCFURLPathKey CF_AVAILABLE(10_8, 6_0);
     /* the URL's path as a file system path (Read-only, value type CFString) */
@@ -989,8 +1015,8 @@ const CFStringRef kCFURLUbiquitousItemHasUnresolvedConflictsKey CF_AVAILABLE(10_
     /* true if this item has conflicts outstanding. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
-const CFStringRef kCFURLUbiquitousItemIsDownloadedKey CF_AVAILABLE(10_7, 5_0);
-    /* true if there is local data present for this item. (Read-only, value type CFBoolean) */
+const CFStringRef kCFURLUbiquitousItemIsDownloadedKey CF_DEPRECATED(10_7, 10_9, 5_0, 7_0, "Use kCFURLUbiquitousItemDownloadingStatusKey instead");
+    /* Equivalent to NSURLUbiquitousItemDownloadingStatusKey == NSURLUbiquitousItemDownloadingStatusCurrent. Has never behaved as documented in earlier releases, hence deprecated. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLUbiquitousItemIsDownloadingKey CF_AVAILABLE(10_7, 5_0);
@@ -1005,15 +1031,42 @@ const CFStringRef kCFURLUbiquitousItemIsUploadingKey CF_AVAILABLE(10_7, 5_0);
     /* true if data is being uploaded for this item. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
-const CFStringRef kCFURLUbiquitousItemPercentDownloadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0);
+const CFStringRef kCFURLUbiquitousItemPercentDownloadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0, "Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead");
     /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead */
 
 CF_EXPORT
-const CFStringRef kCFURLUbiquitousItemPercentUploadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0);
+const CFStringRef kCFURLUbiquitousItemPercentUploadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0, "Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead");
     /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead */
 
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemDownloadingStatusKey CF_AVAILABLE(10_9, 7_0);
+    /* Returns the download status of this item. (Read-only, value type CFString). Possible values below. */
+
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemDownloadingErrorKey CF_AVAILABLE(10_9, 7_0);
+    /* returns the error when downloading the item from iCloud failed. See the NSUbiquitousFile section in FoundationErrors.h. */
+
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemUploadingErrorKey CF_AVAILABLE(10_9, 7_0);
+    /* returns the error when uploading the item to iCloud failed. See the NSUbiquitousFile section in FoundationErrors.h. */
+
+/* The values returned for kCFURLUbiquitousItemDownloadingStatusKey
+ */
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemDownloadingStatusNotDownloaded CF_AVAILABLE(10_9, 7_0);
+    /* this item has not been downloaded yet. Use NSFileManager's startDownloadingUbiquitousItemAtURL:error: to download it */
+
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemDownloadingStatusDownloaded CF_AVAILABLE(10_9, 7_0);
+    /* there is a local version of this item available. The most current version will get downloaded as soon as possible. */
+
+CF_EXPORT
+const CFStringRef kCFURLUbiquitousItemDownloadingStatusCurrent CF_AVAILABLE(10_9, 7_0);
+    /* there is a local version of this item and it is the most up-to-date version known to this device. */
+
+
 typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkCreationOptions) {
-    kCFURLBookmarkCreationPreferFileIDResolutionMask = ( 1UL << 8 ),  // At resolution time, this alias will prefer resolving by the embedded fileID to the path
+    kCFURLBookmarkCreationPreferFileIDResolutionMask CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0, "kCFURLBookmarkCreationPreferFileIDResolutionMask does nothing and has no effect on bookmark resolution" ) = ( 1UL << 8 ),  // This option does nothing and has no effect on bookmark resolution
     kCFURLBookmarkCreationMinimalBookmarkMask = ( 1UL << 9 ), // Creates a bookmark with "less" information, which may be smaller but still be able to resolve in certain ways
     kCFURLBookmarkCreationSuitableForBookmarkFile = ( 1UL << 10 ), // includes in the created bookmark those properties which are needed for a bookmark/alias file
     kCFURLBookmarkCreationWithSecurityScope CF_ENUM_AVAILABLE(10_7,NA) = ( 1UL << 11 ), // Mac OS X 10.7.3 and later, include information in the bookmark data which allows the same sandboxed process to access the resource after being relaunched
@@ -1075,8 +1128,8 @@ CF_EXPORT
 CFURLRef CFURLCreateByResolvingBookmarkData ( CFAllocatorRef allocator, CFDataRef bookmark, CFURLBookmarkResolutionOptions options, CFURLRef relativeToURL, CFArrayRef resourcePropertiesToInclude, Boolean* isStale, CFErrorRef* error ) CF_AVAILABLE(10_6, 4_0);
 
 /*     @function       CFURLCreatePropertiesForKeysFromBookmarkData
-       @discussion     Given a bookmark, return a dictionary of properties ( all properties if propertiesToReturn == NULL ).
-                               This returns only the properties stored within the bookmark and will not attempt to resolve the bookmark or do i/o.
+       @discussion     Given a bookmark, return a dictionary of properties .
+                       This returns only the properties stored within the bookmark and will not attempt to resolve the bookmark or do i/o.
        @param  allocator        the CFAllocator to use to create this object
        @param   bookmark a CFDataRef containing a bookmark data, created with CFURLCreateBookmarkData
        @param  propertiesToReturn a CFArrayRef of the properties of the bookmark data which the client would like returned.
diff --git a/CFURL.inc.h b/CFURL.inc.h
new file mode 100644 (file)
index 0000000..a41c7f1
--- /dev/null
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+/*     CFURL.inc.h
+       Copyright (c) 2012-2013, Apple Inc. All rights reserved.
+       Responsibility: Jim Luther
+*/
+
+
+/*
+ What's this file for?
+ CFURL's URL string parser needs to be able to parse either an array of char or an array of UniChar.
+ The code in CFURL.c used to use this macro "#define STRING_CHAR(x) (useCString ? cstring[(x)] : ustring[(x)])" to determine which array to get a character from for every character looked at in the URL string. That macro added one or more compare and branch instructins to the parser's execution for *every* character in the URL string. Those extra compares and branches added up to 10% of the time (for long URL strings) it takes to create a URL object.
+ To ensure the exact same parser code is run over a char or a UniChar string, the source code was move to this .h file and is included multiple times by CFURL.c as needed. "STRING_CHAR(x)" was replaced by "characterArray[x]", and characterArray is defined as either an "const char *" or a "const UniChar *" for the two sets of function headers that are either parsing an array of char or an array of UniChar.
+ Any changes made to the parser are made in this file so that both char and the UniChar strings are parsed exactly the same way.
+ */
+
+/*
+    static void _parseComponentsCString(CFAllocatorRef alloc, CFURLRef baseURL, UInt32 *theFlags, CFRange **range, CFIndex cfStringLength, const char *characterArray)
+    static void _parseComponentsUString(CFAllocatorRef alloc, CFURLRef baseURL, UInt32 *theFlags, CFRange **range, CFIndex cfStringLength, const UniChar *characterArray)
+ */
+#ifdef CFURL_INCLUDE_PARSE_COMPONENTS // defined when we want this block of code included
+{
+    CFRange ranges[9];
+    /* index gives the URL part involved; to calculate the correct range index, use the number of the bit of the equivalent flag (i.e. the host flag is HAS_HOST, which is 0x8.  so the range index for the host is 3.)  Note that this is true in this function ONLY, since the ranges stored in (*range) are actually packed, skipping those URL components that don't exist.  This is why the indices are hard-coded in this function. */
+    
+    CFIndex idx, base_idx = 0;
+    CFIndex string_length;
+    UInt32 flags = *theFlags;
+    Boolean isCompliant;
+    uint8_t numRanges = 0;
+    
+    string_length = cfStringLength;
+    
+    // Algorithm is as described in RFC 1808
+    // 1: parse the fragment; remainder after left-most "#" is fragment
+    for (idx = base_idx; idx < string_length; idx++) {
+        if ('#' == characterArray[idx]) {
+            flags |= HAS_FRAGMENT;
+            ranges[8].location = idx + 1;
+            ranges[8].length = string_length - (idx + 1);
+            numRanges ++;
+            string_length = idx;       // remove fragment from parse string
+            break;
+        }
+    }
+    // 2: parse the scheme
+    for (idx = base_idx; idx < string_length; idx++) {
+        UniChar ch = characterArray[idx];
+        if (':' == ch) {
+            flags |= HAS_SCHEME;
+            ranges[0].location = base_idx;
+            ranges[0].length = idx;
+            numRanges ++;
+            base_idx = idx + 1;
+            // optimization for ftp urls
+            if (idx == 3 && characterArray[0] == 'f' && characterArray[1] == 't' && characterArray[2] == 'p') {
+                _setSchemeTypeInFlags(&flags, kHasFtpScheme);
+            }
+            else if (idx == 4) {
+                // optimization for http urls
+                if (characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p') {
+                    _setSchemeTypeInFlags(&flags, kHasHttpScheme);
+                }
+                // optimization for file urls
+                if (characterArray[0] == 'f' && characterArray[1] == 'i' && characterArray[2] == 'l' && characterArray[3] == 'e') {
+                    _setSchemeTypeInFlags(&flags, kHasFileScheme);
+                }
+                // optimization for data urls
+                if (characterArray[0] == 'd' && characterArray[1] == 'a' && characterArray[2] == 't' && characterArray[3] == 'a') {
+                    _setSchemeTypeInFlags(&flags, kHasDataScheme);
+                }
+            }
+            // optimization for https urls
+            else if (idx == 5 && characterArray[0] == 'h' && characterArray[1] == 't' && characterArray[2] == 't' && characterArray[3] == 'p' && characterArray[3] == 's') {
+                _setSchemeTypeInFlags(&flags, kHasHttpsScheme);
+            }
+            break;
+        } else if (!scheme_valid(ch)) {
+            break;     // invalid scheme character -- no scheme
+        }
+    }
+    
+    // Make sure we have an RFC-1808 compliant URL - that's either something without a scheme, or scheme:/(stuff) or scheme://(stuff)
+    // Strictly speaking, RFC 1808 & 2396 bar "scheme:" (with nothing following the colon); however, common usage
+    // expects this to be treated identically to "scheme://" - REW, 12/08/03
+    if (!(flags & HAS_SCHEME)) {
+        isCompliant = true;
+    } else if (base_idx == string_length) {
+        isCompliant = false;
+    } else if (characterArray[base_idx] != '/') {
+        isCompliant = false;
+    } else {
+        isCompliant = true;
+    }
+    
+    if (!isCompliant) {
+        // Clear the fragment flag if it's been set
+        if (flags & HAS_FRAGMENT) {
+            flags &= (~HAS_FRAGMENT);
+            string_length = cfStringLength;
+        }
+        (*theFlags) = flags;
+        (*range) = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
+        (*range)->location = ranges[0].location;
+        (*range)->length = ranges[0].length;
+        
+        return;
+    }
+    // URL is 1808-compliant
+    flags |= IS_DECOMPOSABLE;
+    
+    // 3: parse the network location and login
+    if (2 <= (string_length - base_idx) && '/' == characterArray[base_idx] && '/' == characterArray[base_idx+1]) {
+        CFIndex base = 2 + base_idx, extent;
+        for (idx = base; idx < string_length; idx++) {
+            if ('/' == characterArray[idx] || '?' == characterArray[idx]) {
+                break;
+            }
+        }
+        extent = idx;
+        
+        // net_loc parts extend from base to extent (but not including), which might be to end of string
+        // net location is "<user>:<password>@<host>:<port>"
+        if (extent != base) {
+            for (idx = base; idx < extent; idx++) {
+                if ('@' == characterArray[idx]) {   // there is a user
+                    CFIndex idx2;
+                    flags |= HAS_USER;
+                    numRanges ++;
+                    ranges[1].location = base;  // base of the user
+                    for (idx2 = base; idx2 < idx; idx2++) {
+                        if (':' == characterArray[idx2]) {     // found a password separator
+                            flags |= HAS_PASSWORD;
+                            numRanges ++;
+                            ranges[2].location = idx2+1; // base of the password
+                            ranges[2].length = idx-(idx2+1);  // password extent
+                            ranges[1].length = idx2 - base; // user extent
+                            break;
+                        }
+                    }
+                    if (!(flags & HAS_PASSWORD)) {
+                        // user extends to the '@'
+                        ranges[1].length = idx - base; // user extent
+                    }
+                    base = idx + 1;
+                    break;
+                }
+            }
+            flags |= HAS_HOST;
+            numRanges ++;
+            ranges[3].location = base; // base of host
+            
+            // base has been advanced past the user and password if they existed
+            for (idx = base; idx < extent; idx++) {
+                // IPV6 support (RFC 2732) DCJ June/10/2002
+                if ('[' == characterArray[idx]) {      // starting IPV6 explicit address
+                    // Find the ']' terminator of the IPv6 address, leave idx pointing to ']' or end
+                    for ( ; idx < extent; ++ idx ) {
+                        if ( ']' == characterArray[idx]) {
+                            flags |= IS_IPV6_ENCODED;
+                            break;
+                        }
+                    }
+                }
+                // there is a port if we see a colon.  Only the last one is the port, though.
+                else if ( ':' == characterArray[idx]) {
+                    flags |= HAS_PORT;
+                    numRanges ++;
+                    ranges[4].location = idx+1; // base of port
+                    ranges[4].length = extent - (idx+1); // port extent
+                    ranges[3].length = idx - base; // host extent
+                    break;
+                }
+            }
+            if (!(flags & HAS_PORT)) {
+                ranges[3].length = extent - base;  // host extent
+            }
+        }
+        base_idx = extent;
+    }
+    
+    // 4: parse the query; remainder after left-most "?" is query
+    for (idx = base_idx; idx < string_length; idx++) {
+        if ('?' == characterArray[idx]) {
+            flags |= HAS_QUERY;
+            numRanges ++;
+            ranges[7].location = idx + 1;
+            ranges[7].length = string_length - (idx+1);
+            string_length = idx;       // remove query from parse string
+            break;
+        }
+    }
+    
+    // 5: parse the parameters; remainder after left-most ";" is parameters
+    for (idx = base_idx; idx < string_length; idx++) {
+        if (';' == characterArray[idx]) {
+            flags |= HAS_PARAMETERS;
+            numRanges ++;
+            ranges[6].location = idx + 1;
+            ranges[6].length = string_length - (idx+1);
+            string_length = idx;       // remove parameters from parse string
+            break;
+        }
+    }
+    
+    // 6: parse the path; it's whatever's left between string_length & base_idx
+    if (string_length - base_idx != 0 || (flags & NET_LOCATION_MASK))
+    {
+        // If we have a net location, we are 1808-compliant, and an empty path substring implies a path of "/"
+        UniChar ch;
+        Boolean isDir;
+        CFRange pathRg;
+        flags |= HAS_PATH;
+        numRanges ++;
+        pathRg.location = base_idx;
+        pathRg.length = string_length - base_idx;
+        ranges[5] = pathRg;
+        
+        if (pathRg.length > 0) {
+            Boolean sawPercent = FALSE;
+            for (idx = pathRg.location; idx < string_length; idx++) {
+                if ('%' == characterArray[idx]) {
+                    sawPercent = TRUE;
+                    break;
+                }
+            }
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+           if (pathRg.length > 6 && characterArray[pathRg.location] == '/' && characterArray[pathRg.location + 1] == '.' && characterArray[pathRg.location + 2] == 'f' && characterArray[pathRg.location + 3] == 'i' && characterArray[pathRg.location + 4] == 'l' && characterArray[pathRg.location + 5] == 'e' && characterArray[pathRg.location + 6] == '/') {
+               flags |= PATH_HAS_FILE_ID;
+           } else if (!sawPercent) {
+                flags |= POSIX_AND_URL_PATHS_MATCH;
+            }
+#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
+            if (!sawPercent) {
+                flags |= POSIX_AND_URL_PATHS_MATCH;
+            }
+#endif
+            
+            ch = characterArray[pathRg.location + pathRg.length - 1];
+            if (ch == '/') {
+                isDir = true;
+            } else if (ch == '.') {
+                if (pathRg.length == 1) {
+                    isDir = true;
+                } else {
+                    ch = characterArray[pathRg.location + pathRg.length - 2];
+                    if (ch == '/') {
+                        isDir = true;
+                    } else if (ch != '.') {
+                        isDir = false;
+                    } else if (pathRg.length == 2) {
+                        isDir = true;
+                    } else {
+                        isDir = (characterArray[pathRg.location + pathRg.length - 3] == '/');
+                    }
+                }
+            } else {
+                isDir = false;
+            }
+        } else {
+            isDir = (baseURL != NULL) ? CFURLHasDirectoryPath(baseURL) : false;
+        }
+        if (isDir) {
+            flags |= IS_DIRECTORY;
+        }
+    }
+    
+    (*theFlags) = flags;
+    (*range) = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange)*numRanges, 0);
+    numRanges = 0;
+    for (idx = 0, flags = 1; flags != (1<<9); flags = (flags<<1), idx ++) {
+        if ((*theFlags) & flags) {
+            (*range)[numRanges] = ranges[idx];
+            numRanges ++;
+        }
+    }
+}
+#endif  // CFURL_INCLUDE_PARSE_COMPONENTS
+
+/*
+    static Boolean scanCharactersCString(CFAllocatorRef alloc, CFMutableStringRef *escapedString, UInt32 *flags, const char *characterArray, Boolean useCString, CFIndex base, CFIndex end, CFIndex *mark, UInt32 componentFlag, CFStringEncoding encoding)
+    static Boolean scanCharactersUString(CFAllocatorRef alloc, CFMutableStringRef *escapedString, UInt32 *flags, const UniChar *characterArray, Boolean useCString, CFIndex base, CFIndex end, CFIndex *mark, UInt32 componentFlag, CFStringEncoding encoding)
+ */
+#ifdef CFURL_INCLUDE_SCAN_CHARACTERS  // defined when we want this block of code included
+{
+    CFIndex idx;
+    Boolean sawIllegalChar = false;
+    for (idx = base; idx < end; idx ++) {
+        Boolean shouldEscape;
+        UniChar ch = characterArray[idx];
+        if (isURLLegalCharacter(ch)) {
+            if ((componentFlag == HAS_USER || componentFlag == HAS_PASSWORD) && (ch == '/' || ch == '?' || ch == '@')) {
+                shouldEscape = true;
+            } else {
+                shouldEscape = false;
+            }
+        } else if (ch == '%' && idx + 2 < end && isHexDigit(characterArray[idx + 1]) && isHexDigit(characterArray[idx+2])) {
+            shouldEscape = false;
+        } else if (componentFlag == HAS_HOST && ((idx == base && ch == '[') || (idx == end-1 && ch == ']'))) {
+            shouldEscape = false;
+        } else {
+            shouldEscape = true;
+        }
+        if (shouldEscape) {
+            sawIllegalChar = true;
+            if (componentFlag && flags) {
+                *flags |= componentFlag;
+            }
+            if (!*escapedString) {
+                *escapedString = CFStringCreateMutable(alloc, 0);
+            }
+            if (useCString) {
+                CFStringRef tempString = CFStringCreateWithBytes(alloc, (uint8_t *)&(characterArray[*mark]), idx - *mark, kCFStringEncodingISOLatin1, false);
+                CFStringAppend(*escapedString, tempString);
+                CFRelease(tempString);
+            } else {
+                CFStringAppendCharacters(*escapedString, (const UniChar *)&(characterArray[*mark]), idx - *mark);
+            }
+            *mark = idx + 1;
+            _appendPercentEscapesForCharacter(ch, encoding, *escapedString); // This can never fail because anURL->_string was constructed from the encoding passed in
+        }
+    }
+    return sawIllegalChar;
+}
+#endif  // CFURL_INCLUDE_SCAN_CHARACTERS
index d0b0a4d9064d7d3cbe419c0594a979dd89054731..2da209bac0f29377479205a02ce609083f13cb6e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFURLAccess.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Chris Linn
 */
 
@@ -30,6 +30,9 @@
 CFData read/write routines
 -------*/
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
+
 #include "CFInternal.h"
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFURL.h>
@@ -852,5 +855,6 @@ Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) {
 #endif
     }
 }
+#pragma GCC diagnostic pop
 
 
index af279eac8dddd002e1144b387b7b0696135175f0..da2af3f34c2713cef62362c0495d25af4785b043 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,9 @@
  */
 
 /*     CFURLAccess.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
+
+        CFURLAccess is deprecated as of Mac OS X 10.9 and iOS 7.0. The suggested replacement for URLs with network schemes (http, https, ftp, data) is the NSURLConnection class. The suggested replacement for URLs with the file scheme are the foundation classes NSFileManager, NSFileHandle and NSURL, or the CoreFoundation classes CFStream and CFURL.
 */
 
 #if !defined(__COREFOUNDATION_CFURLACCESS__)
@@ -62,8 +64,9 @@ resource (file). Please use CFStream or other techniques if you are downloading
 large files.
 
 */
+/* Deprecated -- see top of this file for suggested replacement classes */
 CF_EXPORT
-Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *resourceData, CFDictionaryRef *properties, CFArrayRef desiredProperties, SInt32 *errorCode) CF_AVAILABLE(10_0, 2_0);
+Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *resourceData, CFDictionaryRef *properties, CFArrayRef desiredProperties, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
 /* Attempts to write the given data and properties to the given URL.
 If dataToWrite is NULL, only properties are written out (use
@@ -73,18 +76,23 @@ is NULL or empty, the URL's properties are not changed at all.
 Returns success or failure; errorCode is set as for
 CFURLCreateDataAndPropertiesFromResource(), above.
 */
+/* Deprecated -- see top of this file for suggested replacement classes */
 CF_EXPORT
-Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef dataToWrite, CFDictionaryRef propertiesToWrite, SInt32 *errorCode) CF_AVAILABLE(10_0, 2_0);
+Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef dataToWrite, CFDictionaryRef propertiesToWrite, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
-/* Destroys the resource indicated by url. */
-/* Returns success or failure; errorCode set as above. */
+/* Destroys the resource indicated by url.
+Returns success or failure; errorCode set as above.
+*/
+/* Deprecated -- see top of this file for suggested replacement classes */
 CF_EXPORT
-Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) CF_AVAILABLE(10_0, 2_0);
+Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
-/* Convenience method which calls through to CFURLCreateDataAndPropertiesFromResource(). */
-/* Returns NULL on error and sets errorCode accordingly. */
+/* Convenience method which calls through to CFURLCreateDataAndPropertiesFromResource().
+Returns NULL on error and sets errorCode accordingly.
+*/
+/* Deprecated -- see top of this file for suggested replacement classes */
 CF_EXPORT
-CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) CF_AVAILABLE(10_0, 2_0);
+CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
 
 /* Common error codes (returned only by the older APIs that predate CFError) */
@@ -98,26 +106,26 @@ typedef CF_ENUM(CFIndex, CFURLError) {
     kCFURLUnknownPropertyKeyError = -16L,
     kCFURLPropertyKeyUnavailableError = -17L,
     kCFURLTimeoutError = -18L
-};
+} CF_ENUM_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
 /* Older property keys */
 
 CF_EXPORT
-const CFStringRef kCFURLFileExists CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFileExists CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLFileDirectoryContents CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFileDirectoryContents CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLFileLength CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFileLength CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT 
-const CFStringRef kCFURLFileLastModificationTime CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFileLastModificationTime CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLFilePOSIXMode CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFilePOSIXMode CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLFileOwnerID CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLFileOwnerID CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLHTTPStatusCode CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLHTTPStatusCode CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 CF_EXPORT
-const CFStringRef kCFURLHTTPStatusLine CF_AVAILABLE(10_0, 2_0);
+const CFStringRef kCFURLHTTPStatusLine CF_DEPRECATED(10_0, 10_9, 2_0, 7_0);
 
 /* The value of kCFURLFileExists is a CFBoolean */
 /* The value of kCFURLFileDirectoryContents is a CFArray containing CFURLs.  An empty array means the directory exists, but is empty */
index 9066c9775cd3ed37db7354ce1ed6aa6501f73f31..17d94e2306853944dcbc12b85fc3573360dc2151 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFURLPriv.h
-       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2013, Apple Inc. All rights reserved.
  */
 
 #if !defined(__COREFOUNDATION_CFURLPRIV__)
@@ -69,18 +69,11 @@ enum {
 } CF_ENUM_AVAILABLE(10_5, 2_0);
 
 
-/*
-    Error user dictionary keys
-*/
-CF_EXPORT
-const CFStringRef kCFURLKeyArrayErrorKey CF_AVAILABLE(10_6, 4_0);
-
-
 /*
     Private File System Property Keys
 */
-CF_EXPORT const CFStringRef _kCFURLPathKey CF_AVAILABLE(10_6, 4_0);
-    /* File system path (CFString) */
+CF_EXPORT const CFStringRef _kCFURLPathKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLPathKey or NSURLPathKey public property keys */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeIDKey CF_AVAILABLE(10_6, 4_0);
     /* Volume ID (CFNumber) */
@@ -95,10 +88,10 @@ CF_EXPORT const CFStringRef _kCFURLParentDirectoryIDKey CF_AVAILABLE(10_6, 4_0);
     /* 64-bit file ID (for tracking a parent directory by ID. This may or may not be the inode number) (CFNumber) */
 
 CF_EXPORT const CFStringRef _kCFURLDistinctLocalizedNameKey CF_AVAILABLE(10_6, 4_0);
-    /* The localized name, if it is disnct from the real name. Otherwise, NULL (CFString) */
+    /* The localized name, if it is distinct from the real name. Otherwise, NULL (CFString) */
 
 CF_EXPORT const CFStringRef _kCFURLNameExtensionKey CF_AVAILABLE(10_6, 4_0);
-    /* The name extenison (CFString) */
+    /* The name extension (CFString) */
 
 CF_EXPORT const CFStringRef _kCFURLFinderInfoKey CF_AVAILABLE(10_6, 4_0);
     /* A 16-byte Finder Info structure immediately followed by a 16-byte Extended Finder Info structure (CFData) */
@@ -112,23 +105,23 @@ CF_EXPORT const CFStringRef _kCFURLIsApplicationKey CF_AVAILABLE(10_6, 4_0);
 CF_EXPORT const CFStringRef _kCFURLCanSetHiddenExtensionKey CF_AVAILABLE(10_6, 4_0);
     /* True if the filename extension can be hidden or unhidden (CFBoolean) */
 
-CF_EXPORT const CFStringRef _kCFURLIsReadableKey CF_AVAILABLE(10_6, 4_0);
-/* OBSOLETE */CF_EXPORT const CFStringRef _kCFURLUserCanReadKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
-    /* True if current user can read the resource (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLIsReadableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsReadableKey or NSURLIsReadableKey public property keys */
+/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanReadKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
 
-CF_EXPORT const CFStringRef _kCFURLIsWriteableKey CF_AVAILABLE(10_6, 4_0);
-/* OBSOLETE */CF_EXPORT const CFStringRef _kCFURLUserCanWriteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
-    /* True if current user can write to the resource (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLIsWriteableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsWritableKey or NSURLIsWritableKey public property keys */
+/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanWriteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
 
-CF_EXPORT const CFStringRef _kCFURLIsExecutableKey CF_AVAILABLE(10_6, 4_0);
-/* OBSOLETE */CF_EXPORT const CFStringRef _kCFURLUserCanExecuteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
-    /* True if current user can execute a file resource or search a directory resource (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLIsExecutableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsExecutableKey or NSURLIsExecutableKey public property keys */
+/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanExecuteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
 
 CF_EXPORT const CFStringRef _kCFURLParentDirectoryIsVolumeRootKey CF_AVAILABLE(10_6, 4_0);
     /* True if the parent directory is the root of a volume (CFBoolean) */
 
-CF_EXPORT const CFStringRef _kCFURLFileSecurityKey CF_AVAILABLE(10_6, 4_0); 
-    /* The file's security settings (FSFileSecurity, CarbonCore/Files.h) */
+CF_EXPORT const CFStringRef _kCFURLFileSecurityKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys */
 
 CF_EXPORT const CFStringRef _kCFURLFileSizeOfResourceForkKey CF_AVAILABLE(10_6, 4_0);
     /* Size in bytes of the resource fork (CFNumber) */
@@ -154,14 +147,14 @@ CF_EXPORT const CFStringRef _kCFURLVersionKey CF_AVAILABLE(10_6, 4_0);
 CF_EXPORT const CFStringRef _kCFURLShortVersionStringKey CF_AVAILABLE(10_6, 4_0);
     /* If resource is a bundle, the bundle short version (CFBundleShortVersionString) as a string (CFString) */
 
-CF_EXPORT const CFStringRef _kCFURLOwnerIDKey CF_AVAILABLE(10_6, 4_0);
-    /* 32-bit owner ID (uid_t) (CFNumber) */
+CF_EXPORT const CFStringRef _kCFURLOwnerIDKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetOwner() */
 
-CF_EXPORT const CFStringRef _kCFURLGroupIDKey CF_AVAILABLE(10_6, 4_0);
-    /* 32-bit group ID (gid_t) (CFNumber) */
+CF_EXPORT const CFStringRef _kCFURLGroupIDKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetGroup() */
 
-CF_EXPORT const CFStringRef _kCFURLStatModeKey CF_AVAILABLE(10_6, 4_0);
-    /* 32-bit group ID (mode_t) (CFNumber) */
+CF_EXPORT const CFStringRef _kCFURLStatModeKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetMode() */
 
 CF_EXPORT const CFStringRef _kCFURLLocalizedNameDictionaryKey CF_AVAILABLE(10_7, NA);
     /* For items with localized display names, the dictionary of all available localizations. The keys are the cannonical locale strings for the available localizations. (CFDictionary) */
@@ -181,43 +174,49 @@ CF_EXPORT const CFStringRef _kCFURLCanSetApplicationHighResolutionModeIsMagnifie
 CF_EXPORT const CFStringRef _kCFURLWriterBundleIdentifierKey CF_AVAILABLE(10_8, NA);
     /* The bundle identifier of the process writing to this object (Read-write, value type CFString) */
 
+CF_EXPORT const CFStringRef _kCFURLApplicationNapIsDisabledKey CF_AVAILABLE(10_9, NA);
+    /* True if app nap is disabled (Applications only, Per-user, CFBoolean) */
+
+CF_EXPORT const CFStringRef _kCFURLCanSetApplicationNapIsDisabledKey CF_AVAILABLE(10_9, NA);
+    /* True if the ApplicationNapIsDisabled property value can be changed (Applications only, Read only, CFBoolean) */
+
 /* Additional volume properties */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeRefNumKey CF_AVAILABLE(10_6, 4_0);
     /* The Carbon File Manager's FSVolumeRefNum for the resource volume (CFNumber) */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeUUIDStringKey CF_AVAILABLE(10_6, 4_0);
-    /* The volume's persistent unique ID as a string, or NULL if not available (CFString) */
+CF_EXPORT const CFStringRef _kCFURLVolumeUUIDStringKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeUUIDStringKey or NSURLVolumeUUIDStringKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeCreationDateKey CF_AVAILABLE(10_6, 4_0);
-    /* Value type CFDate */
+CF_EXPORT const CFStringRef _kCFURLVolumeCreationDateKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeCreationDateKey or NSURLVolumeCreationDateKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsLocalKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume is on a locally connected device -- not a network volume (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsLocalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsLocalKey or NSURLVolumeIsLocalKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsAutomountKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume was mounted by the automounter (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsAutomountKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsAutomountedKey or NSURLVolumeIsAutomountedKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeDontBrowseKey CF_AVAILABLE(10_6, 4_0);
-    /* Don't browse: generally, not shown to users (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeDontBrowseKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsBrowsableKey or NSURLVolumeIsBrowsableKey public property keys (Note: value is inverse of _kCFURLVolumeDontBrowseKey) */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsReadOnlyKey CF_AVAILABLE(10_6, 4_0);
-    /* Mounted read-only (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsReadOnlyKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsReadOnlyKey or NSURLVolumeIsReadOnlyKey public property keys */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeIsQuarantinedKey CF_AVAILABLE(10_6, 4_0);
     /* Mounted quarantined (CFBoolean) */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsEjectableKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume is ejectable media (CD, DVD, etc) (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsEjectableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsEjectableKey or NSURLVolumeIsEjectableKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsRemovableKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume can be disconnected (USB, FireWire) (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsRemovableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsRemovableKey or NSURLVolumeIsRemovableKey public property keys */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsInternalKey CF_AVAILABLE(10_6, 4_0);
-    /* Device is on an internal bus/channel (Note: this has different behavior than the public VolumeIsInternal key) (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsInternalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key) */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsExternalKey CF_AVAILABLE(10_6, 4_0);
-    /* Device is on an external bus/channel (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsExternalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key) */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeIsDiskImageKey CF_AVAILABLE(10_6, 4_0);
     /* Volume is a mounted disk image (CFBoolean) */
@@ -228,14 +227,14 @@ CF_EXPORT const CFStringRef _kCFURLDiskImageBackingURLKey CF_AVAILABLE(10_6, 4_0
 CF_EXPORT const CFStringRef _kCFURLVolumeIsFileVaultKey CF_AVAILABLE(10_6, 4_0);
     /* Volume uses File Vault encryption (CFBoolean) */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsiDiskKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume is an iDisk (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsiDiskKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeiDiskUserNameKey CF_AVAILABLE(10_6, 4_0);
-    /* If volume is an iDisk, the base member name of the iDisk owner (CFString) */
+CF_EXPORT const CFStringRef _kCFURLVolumeiDiskUserNameKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */
 
-CF_EXPORT const CFStringRef _kCFURLVolumeIsLocaliDiskMirrorKey CF_AVAILABLE(10_6, 4_0);
-    /* Volume is a local mirror of an iDisk (CFBoolean) */
+CF_EXPORT const CFStringRef _kCFURLVolumeIsLocaliDiskMirrorKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeIsiPodKey CF_AVAILABLE(10_6, 4_0);
     /* Volume is on an iPod (CFBoolean) */
@@ -252,25 +251,23 @@ CF_EXPORT const CFStringRef _kCFURLVolumeIsDeviceFileSystemKey CF_AVAILABLE(10_7
 CF_EXPORT const CFStringRef _kCFURLVolumeIsHFSStandardKey CF_AVAILABLE(10_6, 4_0);
     /* Volume is HFS standard (which includes AFP volumes). Directory IDs, but not file IDs, can be looked up. (CFBoolean) */
 
-/*  Keys specific to bookmarks at this time */
-CF_EXPORT const CFStringRef _kCFURLPropertyKeyFullPathString CF_AVAILABLE(10_6, 4_0);
-    /* the full filesystem path of the item the bookmark was create against */
-
-CF_EXPORT const CFStringRef _kCFURLURLString CF_AVAILABLE(10_6, 4_0);
-    /* the url string ( possibly relative to a base url ) of the url this bookmark was created against. */
+CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconFamilyNameKey CF_AVAILABLE(10_9, NA);
+    /* Volume's IOMediaIconFamilyName. (CFStringRef) */
 
-CF_EXPORT const CFStringRef _kCFURLFileIDData CF_AVAILABLE(10_6, 4_0);                     
-    /* the url string ( possibly relative to a base url ) of the url this bookmark was created against. */
+CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconBundleIdentifierKey CF_AVAILABLE(10_9, NA);
+    /* Volume's IOMediaIconBundleIdentifier. (CFStringRef) */
 
-CF_EXPORT const CFStringRef _kCFURLResolvedFromBookmarkDataKey CF_AVAILABLE(10_6, 4_0);                            
-    /* the bookmark data that was resolved to produce the URL, if any (CFData) */
+CF_EXPORT const CFStringRef _kCFURLResolvedFromBookmarkDataKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused (*/
 
-CF_EXPORT const CFStringRef _kCFURLVolumeMountPointStringKey CF_AVAILABLE(10_6, 4_0);                      
+CF_EXPORT const CFStringRef _kCFURLVolumeMountPointStringKey CF_AVAILABLE(10_6, 4_0);
     /* the volume mountpoint string (Read-only, value type CFString) */
 
-CF_EXPORT const CFStringRef _kCFURLCompleteMountURLKey CF_AVAILABLE(10_6, 4_0);                            
-    /* the URL to mount the volume on which the resource is stored, if any (Read-only, value type CFURL) */
+CF_EXPORT const CFStringRef _kCFURLCompleteMountURLKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
+    /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeURLForRemountingKey or NSURLVolumeURLForRemountingKey public property keys */
 
+CF_EXPORT const CFStringRef _kCFURLUbiquitousItemDownloadRequestedKey CF_AVAILABLE(10_9, 7_0);
+/* Is this Ubiquity item scheduled for download? (this is also true for items that are already downloaded). Use startDownloadingUbiquitousItemAtURL:error: to make this true (Read-only, value type CFBoolean) */
 
 
 /*
@@ -290,7 +287,8 @@ enum {
     kCFURLResourceHasHiddenExtension    = 0x00000100,
     kCFURLResourceIsApplication         = 0x00000200,
     kCFURLResourceIsCompressed          = 0x00000400,
-    /* OBSOLETE */ kCFURLResourceIsSystemCompressed    = 0x00000400,  /* -> kCFURLResourceIsCompressed */
+    kCFURLResourceIsSystemCompressed CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0)
+                                        = 0x00000400,  /* Deprecated and scheduled for removal in 10.10/8.0 - Use kCFURLResourceIsCompressed */
     kCFURLCanSetHiddenExtension         = 0x00000800,
     kCFURLResourceIsReadable           = 0x00001000,
     kCFURLResourceIsWriteable          = 0x00002000,
@@ -377,12 +375,33 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) {
        kCFURLVolumeIsExternal                          =              0x100LL,
        kCFURLVolumeIsDiskImage                         =              0x200LL,
        kCFURLVolumeIsFileVault                         =              0x400LL,
-       kCFURLVolumeIsLocaliDiskMirror                  =              0x800LL,
+       kCFURLVolumeIsLocaliDiskMirror CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0)
+                                                        =              0x800LL, // Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks
        kCFURLVolumeIsiPod                              =             0x1000LL,
-       kCFURLVolumeIsiDisk                             =             0x2000LL,
+       kCFURLVolumeIsiDisk CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0)
+                                                        =             0x2000LL, // Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks
        kCFURLVolumeIsCD                                =             0x4000LL,
        kCFURLVolumeIsDVD                               =             0x8000LL,
        kCFURLVolumeIsDeviceFileSystem                  =            0x10000LL,
+        kCFURLVolumeIsTimeMachine CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =           0x20000LL,
+        kCFURLVolumeIsAirport CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =           0x40000LL,
+        kCFURLVolumeIsVideoDisk CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =           0x80000LL,
+        kCFURLVolumeIsDVDVideo CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =          0x100000LL,
+        kCFURLVolumeIsBDVideo CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =          0x200000LL,
+        kCFURLVolumeIsMobileTimeMachine CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =          0x400000LL,
+        kCFURLVolumeIsNetworkOptical CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =          0x800000LL,
+        kCFURLVolumeIsBeingRepaired CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =         0x1000000LL,
+        kCFURLVolumeIsBeingUnmounted CF_ENUM_AVAILABLE_MAC(10_9)
+                                                        =         0x2000000LL,
+    
 // IMPORTANT: The values of the following flags must stay in sync with the
 // VolumeCapabilities flags in CarbonCore (FileIDTreeStorage.h)
        kCFURLVolumeSupportsPersistentIDs               =        0x100000000LL,
@@ -428,6 +447,53 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) {
 CF_EXPORT
 Boolean _CFURLGetVolumePropertyFlags(CFURLRef url, CFURLVolumePropertyFlags mask, CFURLVolumePropertyFlags *flags, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
+
+/*  _CFURLCopyResourcePropertyForKeyFromCache works like CFURLCopyResourcePropertyForKey
+    only it never causes I/O. If the property value requested is cached (or known
+    to be not available) for the resource, return TRUE and the property value. The
+    property value returned could be NULL meaning that property is not available
+    for the resource. If the property value requested is not cached or the resource,
+    FALSE is returned.
+
+    Only for use by DesktopServices!
+ */
+CF_EXPORT
+Boolean _CFURLCopyResourcePropertyForKeyFromCache(CFURLRef url, CFStringRef key, void *cfTypeRefValue) CF_AVAILABLE(10_8, NA);
+
+/*  _CFURLCopyResourcePropertiesForKeysFromCache works like CFURLCopyResourcePropertiesForKeys
+    only it never causes I/O. If the property values requested are cached (or known
+    to be not available) for the resource, return a CFDictionary. Property values
+    not available for the resource are not included in the CFDictionary.
+    If the values requested are not cached, return NULL.
+
+    Only for use by DesktopServices!
+ */
+CF_EXPORT
+CFDictionaryRef _CFURLCopyResourcePropertiesForKeysFromCache(CFURLRef url, CFArrayRef keys) CF_AVAILABLE(10_8, NA);
+
+/*  _CFURLCacheResourcePropertyForKey works like CFURLCopyResourcePropertyForKey
+    only it does not return the property value -- it just ensures the value is cached.
+    If no errors occur, TRUE is returned. If an error occurs, FALSE is returned
+    and the optional output error is set to a valid CFErrorRef (which must be
+    released by the caller.
+    Only for use by DesktopServices!
+ */
+CF_EXPORT
+Boolean _CFURLCacheResourcePropertyForKey(CFURLRef url, CFStringRef key, CFErrorRef *error) CF_AVAILABLE(10_8, NA);
+
+/*  _CFURLCacheResourcePropertiesForKeys works like CFURLCopyResourcePropertiesForKeys
+    only it does not return the property values -- it just ensures the values is cached.
+    If no errors occur, TRUE is returned. If an error occurs, FALSE is returned
+    and the optional output error is set to a valid CFErrorRef (which must be
+    released by the caller.
+
+    Only for use by DesktopServices!
+ */
+CF_EXPORT
+Boolean _CFURLCacheResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) CF_AVAILABLE(10_8, NA);
+
+
 /*
  _CFURLSetResourcePropertyForKeyAndUpdateFileCache - Works mostly like CFURLSetResourcePropertyForKey
  except that file system properties are updated in the URL's file cache (if it has a valid cache)
@@ -477,9 +543,9 @@ CFArrayRef _CFURLCreateDisplayPathComponentsArray(CFURLRef url, CFErrorRef *erro
 CF_EXPORT
 Boolean _CFURLIsFileURL(CFURLRef url) CF_AVAILABLE(10_6, 4_0);
 
-/* Returns true for file URLs that use the file reference form */
+/* Deprecated and scheduled for removal in 10.10/8.0 - Use the public API CFURLIsFileReferenceURL() */
 CF_EXPORT
-Boolean _CFURLIsFileReferenceURL(CFURLRef url) CF_AVAILABLE(10_6, 4_0);
+Boolean _CFURLIsFileReferenceURL(CFURLRef url) CF_DEPRECATED(10_6, 10_9, 4_0, 7_0);
 
 /* For use by Core Services */
 CF_EXPORT 
@@ -488,27 +554,6 @@ void *__CFURLResourceInfoPtr(CFURLRef url) CF_AVAILABLE(10_6, 4_0);
 CF_EXPORT 
 void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) CF_AVAILABLE(10_6, 4_0);
 
-#if TARGET_OS_MAC
-
-CF_EXPORT
-CFURLRef _CFURLCreateFileReferenceURLFromIDs( CFAllocatorRef allocator, fsid_t fsid, UInt64 inodeNumber ) CF_AVAILABLE(10_7, NA);
-
-/* _CFURLVolumeIdentifierGetVolumeRefNum is used by LaunchServices */
-CF_EXPORT
-SInt16 _CFURLVolumeIdentifierGetVolumeRefNum(UInt64 volumeIdentifier) CF_AVAILABLE(10_7, NA);
-
-CF_EXPORT
-CFURLRef _CFURLCreateFileReferenceURLFromFSRef(CFAllocatorRef allocator, const struct FSRef *ref) CF_AVAILABLE(10_7, NA);
-
-/* _CFURLGetFSRef is a very lightweight version of CFURLGetFSRef that assumes the CFURL is a file URL and the properties needed to create a FSRef are available in the file URL's cache. This is for use only by CarbonCore's FileOperations SPI and API. */
-CF_EXPORT
-Boolean _CFURLGetFSRef(CFURLRef url, struct FSRef *fsRef) CF_AVAILABLE(10_7, NA);
-
-/* _CFURLGetObjectInformationNoIO is used by LaunchServices */
-CF_EXPORT
-Boolean _CFURLGetObjectInformationNoIO(CFURLRef url, UInt64 * volumeIdentifier, UInt64 * objectIdentifier, UInt32 * statMode) CF_AVAILABLE(10_7, NA);
-
-#endif
 
 struct FSCatalogInfo;
 struct HFSUniStr255;
@@ -561,15 +606,9 @@ typedef CF_ENUM(CFIndex, CFURLBookmarkMatchResult) {
     kCFURLBookmarkComparisonExactMatch      = 0x0000f000    /* the two bookmarks are identical */
 };
 
-/*  Keys specific to bookmarks at this time */
-CF_EXPORT const CFStringRef _kCFURLPropertyKeyFullPathString;      //  the full filesystem path of the item the bookmark was create against
-CF_EXPORT const CFStringRef _kCFURLURLString;                      //  the url string ( possibly relative to a base url ) of the url this bookmark was created against.
-CF_EXPORT const CFStringRef _kCFURLFileIDData;                     //  the url string ( possibly relative to a base url ) of the url this bookmark was created against.
-
-CFURLBookmarkMatchResult _CFURLCompareBookmarkData( CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys ) CF_AVAILABLE(10_7, NA);
-
+/* The relativeToURL and matchingPropertyKeys parameters are not used and are ignored */
 CF_EXPORT
-CFURLBookmarkMatchResult _CFURLBookmarkDataCompare(CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys) CF_AVAILABLE(10_7, NA); // Use _CFURLCompareBookmarkData() instead
+CFURLBookmarkMatchResult _CFURLBookmarkDataCompare(CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys) CF_AVAILABLE(10_7, NA);
 
 CF_EXPORT
 OSStatus _CFURLBookmarkDataToAliasHandle(CFDataRef bookmarkRef, void* aliasHandleP) CF_AVAILABLE(10_7, NA);
index e820e8c0d1cf500bdc7c9842f80e2a4622f0925c..03c815d97b677ea3b0edb1ea88710fc8465824e1 100644 (file)
--- a/CFUUID.c
+++ b/CFUUID.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUUID.c
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
        Responsibility: David Smith
 */
 
@@ -232,7 +232,7 @@ static const CFRuntimeClass __CFUUIDClass = {
     __CFUUIDCopyDescription
 };
 
-__private_extern__ void __CFUUIDInitialize(void) {
+CF_PRIVATE void __CFUUIDInitialize(void) {
     __kCFUUIDTypeID = _CFRuntimeRegisterClass(&__CFUUIDClass);
 }
 
index 04b5e1da8c23569dc10181018fd1970f9bb03c7c..b1f95f95dfcd0bc5b58634d80bd13312d7980461 100644 (file)
--- a/CFUUID.h
+++ b/CFUUID.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUUID.h
-       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUUID__)
index ec635046623dd8eed690614b0825d1611f813961..56445c7f22deda4b56623550763f97b134d4626d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniChar.c
-       Copyright (c) 2001-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2001-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -76,7 +76,30 @@ CF_INLINE uint32_t __CFUniCharMapCompatibilitySetID(uint32_t cset) { return ((cs
 #include <mach-o/dyld.h>
 #include <mach-o/ldsyms.h>
 
+extern const void* unicode_csbitmaps_section_start      __asm("section$start$__UNICODE$__csbitmaps");
+extern const void* unicode_csbitmaps_section_end        __asm("section$end$__UNICODE$__csbitmaps");
+extern const void* unicode_properties_section_start     __asm("section$start$__UNICODE$__properties");
+extern const void* unicode_properties_section_end       __asm("section$end$__UNICODE$__properties");
+extern const void* unicode_data_section_start           __asm("section$start$__UNICODE$__data");
+extern const void* unicode_data_section_end             __asm("section$end$__UNICODE$__data");
+
 static const void *__CFGetSectDataPtr(const char *segname, const char *sectname, uint64_t *sizep) {
+    // special case three common sections to have fast access
+    if ( strcmp(segname, "__UNICODE") == 0 ) {
+        if ( strcmp(sectname, "__csbitmaps") == 0)  {
+            if (sizep) *sizep = &unicode_csbitmaps_section_end - &unicode_csbitmaps_section_start;
+            return &unicode_csbitmaps_section_start;
+        }
+        else if ( strcmp(sectname, "__properties") == 0 ) {
+            if (sizep) *sizep = &unicode_properties_section_end - &unicode_properties_section_start;
+            return &unicode_properties_section_start;
+        }
+        else if ( strcmp(sectname, "__data") == 0 ) {
+            if (sizep) *sizep = &unicode_data_section_end - &unicode_data_section_start;
+            return &unicode_data_section_start;
+        }
+    }
+    
     uint32_t idx, cnt = _dyld_image_count();
     for (idx = 0; idx < cnt; idx++) {
        void *mh = (void *)_dyld_get_image_header(idx);
@@ -247,7 +270,11 @@ static bool __CFUniCharLoadFile(const wchar_t *bitmapName, const void **bytes, i
     char cpath[MAXPATHLEN];
     __CFUniCharCharacterSetPath(cpath);
     strlcat(cpath, bitmapName, MAXPATHLEN);
-    return __CFUniCharLoadBytesFromFile(cpath, bytes, fileSize);
+    Boolean needToFree = false;
+    const char *possiblyFrameworkRootedCPath = CFPathRelativeToAppleFrameworksRoot(cpath, &needToFree);
+    bool result = __CFUniCharLoadBytesFromFile(possiblyFrameworkRootedCPath, bytes, fileSize);
+    if (needToFree) free((void *)possiblyFrameworkRootedCPath);
+    return result;
 #elif DEPLOYMENT_TARGET_WINDOWS
     wchar_t wpath[MAXPATHLEN];
     __CFUniCharCharacterSetPath(wpath);
@@ -403,7 +430,7 @@ static bool __CFUniCharLoadBitmapData(void) {
     return true;
 }
 
-__private_extern__ const char *__CFUniCharGetUnicodeVersionString(void) {
+CF_PRIVATE const char *__CFUniCharGetUnicodeVersionString(void) {
     if (NULL == __CFUniCharBitmapDataArray) __CFUniCharLoadBitmapData();
     return __CFUniCharUnicodeVersionString;
 }
@@ -473,7 +500,7 @@ const uint8_t *CFUniCharGetBitmapPtrForPlane(uint32_t charset, uint32_t plane) {
     return NULL;
 }
 
-__private_extern__ uint8_t CFUniCharGetBitmapForPlane(uint32_t charset, uint32_t plane, void *bitmap, bool isInverted) {
+CF_PRIVATE uint8_t CFUniCharGetBitmapForPlane(uint32_t charset, uint32_t plane, void *bitmap, bool isInverted) {
     const uint8_t *src = CFUniCharGetBitmapPtrForPlane(charset, plane);
     int numBytes = (8 * 1024);
 
@@ -601,7 +628,7 @@ __private_extern__ uint8_t CFUniCharGetBitmapForPlane(uint32_t charset, uint32_t
     return (isInverted ? kCFUniCharBitmapAll : kCFUniCharBitmapEmpty);
 }
 
-__private_extern__ uint32_t CFUniCharGetNumberOfPlanes(uint32_t charset) {
+CF_PRIVATE uint32_t CFUniCharGetNumberOfPlanes(uint32_t charset) {
     if ((charset == kCFUniCharControlCharacterSet) || (charset == kCFUniCharControlAndFormatterCharacterSet)) {
         return 15; // 0 to 14
     } else if (charset < kCFUniCharDecimalDigitCharacterSet) {
@@ -656,7 +683,7 @@ static CFSpinLock_t __CFUniCharMappingTableLock = CFSpinLockInit;
 #error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
-__private_extern__ const void *CFUniCharGetMappingData(uint32_t type) {
+CF_PRIVATE const void *CFUniCharGetMappingData(uint32_t type) {
 
     __CFSpinLock(&__CFUniCharMappingTableLock);
 
@@ -1070,7 +1097,7 @@ CF_INLINE bool __CFUniCharIsAfter_i(UTF16Char *buffer, CFIndex length) {
     return true;
 }
 
-__private_extern__ uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char theChar, UTF16Char *buffer, CFIndex currentIndex, CFIndex length, uint32_t type, const uint8_t *langCode, uint32_t lastFlags) {
+CF_PRIVATE uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char theChar, UTF16Char *buffer, CFIndex currentIndex, CFIndex length, uint32_t type, const uint8_t *langCode, uint32_t lastFlags) {
     if (theChar == 0x03A3) { // GREEK CAPITAL LETTER SIGMA
         if ((type == kCFUniCharToLowercase) && (currentIndex > 0)) {
             UTF16Char *start = buffer;
@@ -1110,10 +1137,12 @@ __private_extern__ uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char th
                 return (__CFUniCharIsAfter_i(buffer, currentIndex) ? kCFUniCharCaseMapAfter_i : 0);
             } else if (type == kCFUniCharToLowercase) {
                 if ((theChar == 0x0049) || (theChar == 0x004A) || (theChar == 0x012E)) {
-                    return (__CFUniCharIsMoreAbove(buffer + (++currentIndex), length - currentIndex) ? kCFUniCharCaseMapMoreAbove : 0);
+                    ++currentIndex;
+                    return (__CFUniCharIsMoreAbove(buffer + currentIndex, length - currentIndex) ? kCFUniCharCaseMapMoreAbove : 0);
                 }
             } else if ((theChar == 'i') || (theChar == 'j')) {
-                return (__CFUniCharIsMoreAbove(buffer + (++currentIndex), length - currentIndex) ? (kCFUniCharCaseMapAfter_i|kCFUniCharCaseMapMoreAbove) : 0);
+                ++currentIndex;
+                return (__CFUniCharIsMoreAbove(buffer + currentIndex, length - currentIndex) ? (kCFUniCharCaseMapAfter_i|kCFUniCharCaseMapMoreAbove) : 0);
             }
         } else if ((*((const uint16_t *)langCode) == TURKISH_LANG_CODE) || (*((const uint16_t *)langCode) == AZERI_LANG_CODE)) {
             if (type == kCFUniCharToLowercase) {
@@ -1139,7 +1168,7 @@ __private_extern__ uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char th
             }
         }
         if (((theChar >= 0x0370) && (theChar < 0x0400)) || ((theChar >= 0x1F00) && (theChar < 0x2000))) { // Greek/Coptic & Greek extended ranges
-            if (((type == kCFUniCharToUppercase) || (type == kCFUniCharToTitlecase))&& (CFUniCharIsMemberOf(theChar, kCFUniCharLetterCharacterSet))) return kCFUniCharCaseMapGreekTonos;
+            if ((type == kCFUniCharToUppercase) && (CFUniCharIsMemberOf(theChar, kCFUniCharLetterCharacterSet))) return kCFUniCharCaseMapGreekTonos;
         }
     }
     return 0;
@@ -1238,12 +1267,12 @@ const void *CFUniCharGetUnicodePropertyDataForPlane(uint32_t propertyType, uint3
     return (plane < __CFUniCharUnicodePropertyTable[propertyType]._numPlanes ? __CFUniCharUnicodePropertyTable[propertyType]._planes[plane] : NULL);
 }
 
-__private_extern__ uint32_t CFUniCharGetNumberOfPlanesForUnicodePropertyData(uint32_t propertyType) {
+CF_PRIVATE uint32_t CFUniCharGetNumberOfPlanesForUnicodePropertyData(uint32_t propertyType) {
     (void)CFUniCharGetUnicodePropertyDataForPlane(propertyType, 0);
     return __CFUniCharUnicodePropertyTable[propertyType]._numPlanes;
 }
 
-__private_extern__ uint32_t CFUniCharGetUnicodeProperty(UTF32Char character, uint32_t propertyType) {
+CF_PRIVATE uint32_t CFUniCharGetUnicodeProperty(UTF32Char character, uint32_t propertyType) {
     if (propertyType == kCFUniCharCombiningProperty) {
         return CFUniCharGetCombiningPropertyForCharacter(character, (const uint8_t *)CFUniCharGetUnicodePropertyDataForPlane(propertyType, (character >> 16) & 0xFF));
     } else if (propertyType == kCFUniCharBidiProperty) {
index b886945064b237d530ef6139df2cf2057fe6307a..2dc365ff000d8111ad3086f8c747f15002c91a9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniChar.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUNICHAR__)
@@ -227,7 +227,7 @@ CF_INLINE bool CFUniCharFromUTF32(const UTF32Char *src, CFIndex length, UTF16Cha
     while (src < limit) {
         character = (isBigEndien ? CFSwapInt32BigToHost(*(src++)) : CFSwapInt32LittleToHost(*(src++)));
 
-        if (character < 0xFFFF) { // BMP
+        if (character < 0x10000) { // BMP
             if (allowLossy) {
                 if (CFUniCharIsSurrogateHighCharacter(character)) {
                     UTF32Char otherCharacter = 0xFFFD; // replacement character
index de85604efbacc74e56505b9f4836457324b79a1f..205fa52df171b8e52f482a5f7296ff28ab3c6cff 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniCharPriv.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUNICHARPRIV__)
index 4026b4fd5b95aa6cc5fd3f3af8e342eac07a7301..f760704bf023f347064d51f8c93b15af03fe4964 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*    CFUnicodeDecomposition.c
-    Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+    Copyright (c) 1999-2013, Apple Inc. All rights reserved.
     Responsibility: Aki Inoue
 */
 
@@ -357,7 +357,7 @@ CF_INLINE void __CFUniCharMoveBufferFromEnd1(UTF32Char *convertedChars, CFIndex
     while (convertedChars > limit) *(--dstP) = *(--convertedChars);
 }
 
-__private_extern__ CFIndex CFUniCharCompatibilityDecompose(UTF32Char *convertedChars, CFIndex length, CFIndex maxBufferLength) {
+CF_PRIVATE CFIndex CFUniCharCompatibilityDecompose(UTF32Char *convertedChars, CFIndex length, CFIndex maxBufferLength) {
     UTF32Char currentChar;
     UTF32Char buffer[MAX_COMP_DECOMP_LEN];
     const UTF32Char *bufferP;
index 35e82b4ef0b374bd9ccba5be03c7c9313a9a1414..36a8add7b977ffc07198d4ccbabc84386cd1e432 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by aki on Wed Oct 03 2001.
- *  Copyright (c) 2001-2012, Apple Inc. All rights reserved.
+ *  Copyright (c) 2001-2013, Apple Inc. All rights reserved.
  *
  */
 
index 915bf866695eea97daab8784b483bf19fef948ac..b66532e84479a4f2870f492343b3bfe31ab72504 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUnicodePrecomposition.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -121,7 +121,7 @@ static uint32_t __CFUniCharGetMappedValue_P(const __CFUniCharPrecomposeMappings
     return 0;
 }
 
-__private_extern__
+CF_PRIVATE
 UTF32Char CFUniCharPrecomposeCharacter(UTF32Char base, UTF32Char combining) {
     uint32_t value;
 
index 97ce58810bc2028cc6b97577c3d0940fb514981c..5f01591eaabbfb07b60067cf2e0b56eb140e1d14 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by aki on Wed Oct 03 2001.
- *  Copyright (c) 2001-2012, Apple Inc. All rights reserved.
+ *  Copyright (c) 2001-2013, Apple Inc. All rights reserved.
  *
  */
 
index bc848feb96c08912fd13cce19fd244c808e253cf..805bcb8c65c4aa05ccdbdfb9e79e6b49d4e6fa67 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUserNotification.c
-       Copyright (c) 2000-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc.  All rights reserved.
        Original Author: Doug Davidson
        Responsibility: Kevin Perry
 */
@@ -128,7 +128,7 @@ static const CFRuntimeClass __CFUserNotificationClass = {
     __CFUserNotificationCopyDescription
 };
 
-__private_extern__ void __CFUserNotificationInitialize(void) {
+CF_PRIVATE void __CFUserNotificationInitialize(void) {
     __kCFUserNotificationTypeID = _CFRuntimeRegisterClass(&__CFUserNotificationClass);
 }
 
@@ -257,12 +257,17 @@ static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringR
     return retval;
 }
 
+static SInt32 _getNextToken() {
+    static uint16_t tokenCounter = 0;
+    SInt32 token = ((getpid() << 16) | (tokenCounter++));
+    return token;
+}
+
 CFUserNotificationRef CFUserNotificationCreate(CFAllocatorRef allocator, CFTimeInterval timeout, CFOptionFlags flags, SInt32 *error, CFDictionaryRef dictionary) {
     CHECK_FOR_FORK();
     CFUserNotificationRef userNotification = NULL;
     SInt32 retval = ERR_SUCCESS;
-    static uint16_t tokenCounter = 0;
-    SInt32 token = ((getpid() << 16) | (tokenCounter++));
+    SInt32 token = _getNextToken();
     CFStringRef sessionID = (dictionary ? CFDictionaryGetValue(dictionary, kCFUserNotificationSessionIDKey) : NULL);
     mach_port_t replyPort = MACH_PORT_NULL;
 
@@ -412,7 +417,6 @@ CFRunLoopSourceRef CFUserNotificationCreateRunLoopSource(CFAllocatorRef allocato
 
 SInt32 CFUserNotificationDisplayNotice(CFTimeInterval timeout, CFOptionFlags flags, CFURLRef iconURL, CFURLRef soundURL, CFURLRef localizationURL, CFStringRef alertHeader, CFStringRef alertMessage, CFStringRef defaultButtonTitle) {
     CHECK_FOR_FORK();
-    CFUserNotificationRef userNotification;
     SInt32 retval = ERR_SUCCESS;
     CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
     if (iconURL) CFDictionaryAddValue(dict, kCFUserNotificationIconURLKey, iconURL);
@@ -421,8 +425,10 @@ SInt32 CFUserNotificationDisplayNotice(CFTimeInterval timeout, CFOptionFlags fla
     if (alertHeader) CFDictionaryAddValue(dict, kCFUserNotificationAlertHeaderKey, alertHeader);
     if (alertMessage) CFDictionaryAddValue(dict, kCFUserNotificationAlertMessageKey, alertMessage);
     if (defaultButtonTitle) CFDictionaryAddValue(dict, kCFUserNotificationDefaultButtonTitleKey, defaultButtonTitle);
-    userNotification = CFUserNotificationCreate(kCFAllocatorSystemDefault, timeout, flags, &retval, dict);
-    if (userNotification) CFRelease(userNotification);
+    retval = _CFUserNotificationSendRequest(__CFGetDefaultAllocator(), NULL, MACH_PORT_NULL, _getNextToken(), timeout, flags, dict);
+    if (ERR_SUCCESS != retval) {
+        CFUserNotificationLog(alertHeader, alertMessage);
+    }
     CFRelease(dict);
     return retval;
 }
index a3e4406d2082103bb8e77eebe15a22f2ed984b1d..6699c3a17444fd934348984bc1bd82420598edde 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUserNotification.h
-       Copyright (c) 2000-2012, Apple Inc.  All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUSERNOTIFICATION__)
index b14becc450f03f7f632066f0b00f49d315dbc371..d3877b34080614296cdcf32b26112c4bcdf6a123 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFUtilities.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -75,6 +75,7 @@
 #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 #include <string.h>
 #include <pthread.h>
+#include <sys/mman.h>
 #endif
 
 /* Comparator is passed the address of the values. */
    }
    
 */
-__private_extern__ CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
+CF_PRIVATE CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) {
     const char *ptr = (const char *)list;
     while (0 < count) {
         CFIndex half = count / 2;
@@ -144,7 +145,7 @@ CFHashCode CFHashBytes(uint8_t *bytes, CFIndex length) {
 
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
-__private_extern__ uintptr_t __CFFindPointer(uintptr_t ptr, uintptr_t start) {
+CF_PRIVATE uintptr_t __CFFindPointer(uintptr_t ptr, uintptr_t start) {
     vm_map_t task = mach_task_self();
     mach_vm_address_t address = start;
     for (;;) {
@@ -170,7 +171,7 @@ __private_extern__ uintptr_t __CFFindPointer(uintptr_t ptr, uintptr_t start) {
     return 0;
 }
 
-__private_extern__ void __CFDumpAllPointerLocations(uintptr_t ptr) {
+CF_PRIVATE void __CFDumpAllPointerLocations(uintptr_t ptr) {
     uintptr_t addr = 0;
     do {
         addr = __CFFindPointer(ptr, sizeof(void *) + addr);
@@ -195,7 +196,7 @@ static unsigned __stdcall __CFWinThreadFunc(void *arg) {
 }
 #endif
 
-__private_extern__ void *__CFStartSimpleThread(void *func, void *arg) {
+CF_PRIVATE void *__CFStartSimpleThread(void *func, void *arg) {
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
     pthread_attr_t attr;
     pthread_t tid = 0;
@@ -249,24 +250,34 @@ static CFStringRef _CFCopyLocalizedVersionKey(CFBundleRef *bundlePtr, CFStringRe
 static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) {
     CFPropertyListRef plist = NULL;
     
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     CFDataRef data;
     CFURLRef url;
     
     url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, false);
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated"
     if (url && CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, url, &data, NULL, NULL, NULL)) {
+#pragma GCC diagnostic pop
        plist = CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListMutableContainers, NULL);
        CFRelease(data);
     }
     if (url) CFRelease(url);
 
     if (plist) {
+#if DEPLOYMENT_TARGET_EMBEDDED_MINI
+       CFStringRef fullVersion, vers, versExtra, build;
+       CFStringRef versionString = CFRetain(_kCFSystemVersionProductVersionStringKey);
+       CFStringRef buildString = CFRetain(_kCFSystemVersionBuildStringKey);
+       CFStringRef fullVersionString = CFRetain(CFSTR("FullVersionString"));
+#else
        CFBundleRef locBundle = NULL;
        CFStringRef fullVersion, vers, versExtra, build;
        CFStringRef versionString = _CFCopyLocalizedVersionKey(&locBundle, _kCFSystemVersionProductVersionStringKey);
        CFStringRef buildString = _CFCopyLocalizedVersionKey(&locBundle, _kCFSystemVersionBuildStringKey);
        CFStringRef fullVersionString = _CFCopyLocalizedVersionKey(&locBundle, CFSTR("FullVersionString"));
        if (locBundle) CFRelease(locBundle);
+#endif
 
         // Now build the full version string
         if (CFEqual(fullVersionString, CFSTR("FullVersionString"))) {
@@ -287,7 +298,7 @@ static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) {
        CFRelease(buildString);
        CFRelease(fullVersionString);
         CFRelease(fullVersion);
-    }    
+    }
 #elif DEPLOYMENT_TARGET_WINDOWS
     OSVERSIONINFOEX osvi;
     ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
@@ -360,7 +371,7 @@ CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version) {
 
 
 #if DEPLOYMENT_TARGET_MACOSX
-__private_extern__ void *__CFLookupCarbonCoreFunction(const char *name) {
+CF_PRIVATE void *__CFLookupCarbonCoreFunction(const char *name) {
     static void *image = NULL;
     if (NULL == image) {
        image = dlopen("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore", RTLD_LAZY | RTLD_LOCAL);
@@ -374,7 +385,7 @@ __private_extern__ void *__CFLookupCarbonCoreFunction(const char *name) {
 #endif
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-__private_extern__ void *__CFLookupCoreServicesInternalFunction(const char *name) {
+CF_PRIVATE void *__CFLookupCoreServicesInternalFunction(const char *name) {
     static void *image = NULL;
     if (NULL == image) {
         image = dlopen("/System/Library/PrivateFrameworks/CoreServicesInternal.framework/CoreServicesInternal", RTLD_LAZY | RTLD_LOCAL);
@@ -386,11 +397,11 @@ __private_extern__ void *__CFLookupCoreServicesInternalFunction(const char *name
     return dyfunc;
 }
 
-__private_extern__ void *__CFLookupCFNetworkFunction(const char *name) {
+CF_PRIVATE void *__CFLookupCFNetworkFunction(const char *name) {
     static void *image = NULL;
     if (NULL == image) {
        const char *path = NULL;
-       if (!issetugid()) {
+        if (!__CFProcessIsRestricted()) {
            path = __CFgetenv("CFNETWORK_LIBRARY_PATH");
        }
        if (!path) {
@@ -409,13 +420,13 @@ __private_extern__ void *__CFLookupCFNetworkFunction(const char *name) {
 
 #ifndef __CFGetSessionID_defined
 
-__private_extern__ uint32_t __CFGetSessionID(void) {
+CF_PRIVATE uint32_t __CFGetSessionID(void) {
     return 0;
 }
 
 #endif
 
-__private_extern__ CFIndex __CFActiveProcessorCount() {
+CF_PRIVATE CFIndex __CFActiveProcessorCount() {
     int32_t pcnt;
 #if DEPLOYMENT_TARGET_WINDOWS
     SYSTEM_INFO sysInfo;
@@ -441,7 +452,7 @@ __private_extern__ CFIndex __CFActiveProcessorCount() {
     return pcnt;
 }
 
-__private_extern__ void __CFGetUGIDs(uid_t *euid, gid_t *egid) {
+CF_PRIVATE void __CFGetUGIDs(uid_t *euid, gid_t *egid) {
 #if 1 && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     uid_t uid;
     gid_t gid;
@@ -569,11 +580,13 @@ static Boolean also_do_stderr() {
     mode_t m = sb.st_mode & S_IFMT;
     if (S_IFREG == m || S_IFSOCK == m) return true;
     if (!(S_IFIFO == m || S_IFCHR == m)) return false; // disallow any whacky stuff
+#if 0 // launchd no longer repeats everything it hears
     // if it could be a pipe back to launchd, fail
     int64_t val = 0;
     // assumes val is not written to on error
     vproc_swap_integer(NULL, VPROC_GSK_IS_MANAGED, NULL, &val);
     if (val) return false;
+#endif
 #endif
     return true;
 }
@@ -585,9 +598,8 @@ static void __CFLogCString(int32_t lev, const char *message, size_t length, char
     char *time = NULL;
     char *thread = NULL;
     char *uid = NULL;
-#if DEPLOYMENT_TARGET_WINDOWS
-    int bannerLen = 0;
-#endif
+    int bannerLen;
+    bannerLen = 0;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     // The banner path may use CF functions, but the rest of this function should not. It may be called at times when CF is not fully setup or torn down.
     if (withBanner) {
@@ -615,7 +627,7 @@ static void __CFLogCString(int32_t lev, const char *message, size_t length, char
        asprintf(&thread, "%x", GetCurrentThreadId());
 #else
        bannerLen = asprintf(&banner, "%04d-%02d-%02d %02d:%02d:%02d.%03d %s[%d:%x] ", year, month, day, hour, minute, second, ms, *_CFGetProgname(), getpid(), (unsigned int)pthread_self());
-       asprintf(&thread, "%x", pthread_self());
+       asprintf(&thread, "%lx", pthread_self());
 #endif
        asprintf(&time, "%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, ms);
 
@@ -719,7 +731,7 @@ CF_EXPORT void _CFLogvEx(CFLogFunc logit, CFStringRef (*copyDescFunc)(void *, co
 }
 
 // This CF-only log function uses no CF functionality, so it may be called anywhere within CF - including thread teardown or prior to full CF setup
-__private_extern__ void _CFLogSimple(int32_t lev, char *format, ...) {
+CF_PRIVATE void _CFLogSimple(int32_t lev, char *format, ...) {
     va_list args;
     va_start(args, format);
     char formattedMessage[1024];
@@ -866,7 +878,7 @@ static int32_t __CFProcessExitStatus = 0;
 static int __CFProcessIsKillableNotifyToken;
 static Boolean __CFProcessIsKillableNotifyTokenIsFigured = false;
 
-__private_extern__ void _CFSetSuddenTerminationEnabled(Boolean isEnabled) {
+CF_PRIVATE void _CFSetSuddenTerminationEnabled(Boolean isEnabled) {
     if (!__CFProcessIsKillableNotifyTokenIsFigured) {
         char *notificationName = NULL;
         asprintf(&notificationName, "com.apple.isKillable.%i", getpid());
@@ -938,7 +950,7 @@ size_t _CFSuddenTerminationDisablingCount(void) {
 typedef void (^ThrottleTypeA)(void);           // allows calls per nanoseconds
 typedef void (^ThrottleTypeB)(uint64_t amt);   // allows amount per nanoseconds
 
-__private_extern__ ThrottleTypeA __CFCreateThrottleTypeA(uint16_t calls, uint64_t nanoseconds) {
+CF_PRIVATE ThrottleTypeA __CFCreateThrottleTypeA(uint16_t calls, uint64_t nanoseconds) {
    struct mach_timebase_info info;
    mach_timebase_info(&info);
    uint64_t period = nanoseconds / info.numer * info.denom;
@@ -964,7 +976,7 @@ __private_extern__ ThrottleTypeA __CFCreateThrottleTypeA(uint16_t calls, uint64_
            });
 }
 
-__private_extern__ ThrottleTypeB __CFCreateThrottleTypeB(uint64_t amount, uint64_t nanoseconds) {
+CF_PRIVATE ThrottleTypeB __CFCreateThrottleTypeB(uint64_t amount, uint64_t nanoseconds) {
    struct mach_timebase_info info;
    mach_timebase_info(&info);
    uint64_t period = nanoseconds / info.numer * info.denom;
@@ -1018,7 +1030,7 @@ static CFErrorRef _CFErrorWithFilePathCodeDomain(CFStringRef domain, CFIndex cod
 }
 
 // Caller is responsible for freeing memory. munmap() if map == true, else malloc().
-__private_extern__ Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map, Boolean uncached, void **outBytes, CFIndex *outLength, CFErrorRef *errorPtr) {
+CF_PRIVATE Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map, Boolean uncached, void **outBytes, CFIndex *outLength, CFErrorRef *errorPtr) {
     void *bytes = NULL;
     unsigned long length;
     char cpath[CFMaxPathSize];
@@ -1067,7 +1079,7 @@ __private_extern__ Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map,
     if (0LL == statBuf.st_size) {
         bytes = malloc(8); // don't return constant string -- it's freed!
        length = 0;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
     } else if (map) {
         if((void *)-1 == (bytes = mmap(0, (size_t)statBuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0))) {
            int32_t savederrno = errno;
@@ -1107,7 +1119,7 @@ __private_extern__ Boolean _CFReadMappedFromFile(CFStringRef path, Boolean map,
        }
        length = (unsigned long)statBuf.st_size - numBytesRemaining;
     }
-#else
+#elif DEPLOYMENT_TARGET_WINDOWS
     } else {
         bytes = malloc(statBuf.st_size);
         DWORD numBytesRead;
diff --git a/CFUtilities.h b/CFUtilities.h
new file mode 100644 (file)
index 0000000..e2080fd
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2013 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@
+ */
+
+/*     CFUtilities.h
+       Copyright (c) 2005-2013, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFUTILITIES__)
+#define __COREFOUNDATION_CFUTILITIES__ 1
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFURL.h>
+
+CF_IMPLICIT_BRIDGING_ENABLED
+CF_EXTERN_C_BEGIN
+
+CF_EXPORT
+CFURLRef CFCopyHomeDirectoryURL(void) CF_AVAILABLE_IOS(5_0);
+
+CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
+
+#endif /* ! __COREFOUNDATION_CFUTILITIES__ */
+
index 8be1dbe010677d62b355120fef98187b8657173d..7b72dbcb109b7d61c507f24420b2be2178e6bd50 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -25,5 +25,5 @@
     Copyright 2009-2011, Apple Inc. All rights reserved.
     Responsibility: CFLite Team
 */
-const unsigned char kCFCoreFoundationVersionString[] = "@(#)PROGRAM:CoreFoundation  PROJECT:CoreFoundation-744.12  SYSTEM:Darwin  DEVELOPER:unknown  BUILT:" __DATE__ " " __TIME__ "\n";
-double kCFCoreFoundationVersionNumber = (double)744.12;
+const unsigned char kCFCoreFoundationVersionString[] = "@(#)PROGRAM:CoreFoundation  PROJECT:CoreFoundation-855.11  SYSTEM:Darwin  DEVELOPER:unknown  BUILT:" __DATE__ " " __TIME__ "\n";
+double kCFCoreFoundationVersionNumber = (double)855.11;
index af1bb39c094687f7a9e5dbf457c84587d3b29d94..6fcd04678dafdd793c51ce995f6c6f83980e55d9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -23,7 +23,7 @@
 
 /*     
     CFWindowsUtilities.c
-    Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+    Copyright (c) 2008-2013, Apple Inc. All rights reserved.
     Responsibility: Tony Parker
 */
 
index b3d735264c88f754ffffdb6c95d08a9b964edcd9..52cc6c5158494f6dd0d69a44766f688f497bdb0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLInputStream.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -145,7 +145,7 @@ CF_INLINE void _fillStringWithCharacters(CFMutableStringRef string, UniChar *cha
     }
 }
 
-__private_extern__ Boolean _openInputStream(_CFXMLInputStream *stream) {
+CF_PRIVATE Boolean _openInputStream(_CFXMLInputStream *stream) {
     if (NULL == stream->data) {
         return false;
     } else {
@@ -159,7 +159,7 @@ __private_extern__ Boolean _openInputStream(_CFXMLInputStream *stream) {
     }
 }
 
-__private_extern__ void _initializeInputStream(_CFXMLInputStream *stream, CFAllocatorRef alloc, CFURLRef dataSource, CFDataRef xmlData) {
+CF_PRIVATE void _initializeInputStream(_CFXMLInputStream *stream, CFAllocatorRef alloc, CFURLRef dataSource, CFDataRef xmlData) {
     stream->data = xmlData ? (CFDataRef)CFRetain(xmlData) : NULL;
     stream->url = dataSource ? (CFURLRef)CFRetain(dataSource) : NULL;
     stream->encoding = kCFStringEncodingInvalidId;
@@ -182,7 +182,7 @@ __private_extern__ void _initializeInputStream(_CFXMLInputStream *stream, CFAllo
 }
 
 
-__private_extern__ void _freeInputStream(_CFXMLInputStream *stream) {
+CF_PRIVATE void _freeInputStream(_CFXMLInputStream *stream) {
     if (stream->data) CFRelease(stream->data);
     if (stream->url) CFRelease(stream->url);
     if (stream->charBuffer) CFAllocatorDeallocate(stream->allocator, stream->charBuffer);
@@ -191,26 +191,26 @@ __private_extern__ void _freeInputStream(_CFXMLInputStream *stream) {
     CFRelease(stream->allocator);
 }
 
-__private_extern__ CFStringEncoding _inputStreamGetEncoding(_CFXMLInputStream *stream) {
+CF_PRIVATE CFStringEncoding _inputStreamGetEncoding(_CFXMLInputStream *stream) {
     return stream->encoding;
 }
 
-__private_extern__ CFIndex _inputStreamCurrentLocation(_CFXMLInputStream *stream) {
+CF_PRIVATE CFIndex _inputStreamCurrentLocation(_CFXMLInputStream *stream) {
     return stream->charIndex;
 }
 
-__private_extern__ CFIndex _inputStreamCurrentLine(_CFXMLInputStream *stream) {
+CF_PRIVATE CFIndex _inputStreamCurrentLine(_CFXMLInputStream *stream) {
     return stream->lineNum;
 }
 
-__private_extern__ Boolean _inputStreamAtEOF(_CFXMLInputStream *stream) {
+CF_PRIVATE Boolean _inputStreamAtEOF(_CFXMLInputStream *stream) {
     if (!(stream->flags & STREAM_OPEN)) return false;
     if (stream->currentChar) return false;
     if (stream->currentByte - CFDataGetBytePtr(stream->data) < CFDataGetLength(stream->data)) return false;
     return true;
 }
 
-__private_extern__ Boolean _inputStreamComposingErrorOccurred(_CFXMLInputStream *stream) {
+CF_PRIVATE Boolean _inputStreamComposingErrorOccurred(_CFXMLInputStream *stream) {
     return stream->flags & ENCODING_COMPOSITION_ERROR;
 }
 
@@ -428,15 +428,15 @@ CF_INLINE Boolean getCharacter(_CFXMLInputStream *stream, UniChar *ch, Boolean a
     return true;
 }
 
-__private_extern__ Boolean _inputStreamPeekCharacter(_CFXMLInputStream *stream, UniChar *ch) {
+CF_PRIVATE Boolean _inputStreamPeekCharacter(_CFXMLInputStream *stream, UniChar *ch) {
     return getCharacter(stream, ch, false);
 }
 
-__private_extern__ Boolean _inputStreamGetCharacter(_CFXMLInputStream *stream, UniChar *ch) {
+CF_PRIVATE Boolean _inputStreamGetCharacter(_CFXMLInputStream *stream, UniChar *ch) {
     return getCharacter(stream, ch, true);
 }
 
-__private_extern__ Boolean _inputStreamReturnCharacter(_CFXMLInputStream *stream, UniChar ch) {
+CF_PRIVATE Boolean _inputStreamReturnCharacter(_CFXMLInputStream *stream, UniChar ch) {
     Boolean decrementLineNum = false;
     if (ch == '\n') {
         decrementLineNum = true;
@@ -514,17 +514,17 @@ static UniChar *dropMark(_CFXMLInputStream *stream) {
 
 }
 
-__private_extern__ void _inputStreamSetMark(_CFXMLInputStream *stream) {
+CF_PRIVATE void _inputStreamSetMark(_CFXMLInputStream *stream) {
     CFAssert(stream->mark == NULL, __kCFLogAssertion, "CF internal error: parser input stream malformed");
     stream->mark = dropMark(stream);
 }
 
-__private_extern__ void _inputStreamClearMark(_CFXMLInputStream *stream) {
+CF_PRIVATE void _inputStreamClearMark(_CFXMLInputStream *stream) {
     CFAssert(stream->mark != NULL, __kCFLogAssertion, "CF internal error: parser input stream malformed");
     stream->mark = NULL;
 }
 
-__private_extern__ void _inputStreamGetCharactersFromMark(_CFXMLInputStream *stream, CFMutableStringRef string) {
+CF_PRIVATE void _inputStreamGetCharactersFromMark(_CFXMLInputStream *stream, CFMutableStringRef string) {
     UniChar *end = stream->currentChar ? stream->currentChar : stream->charBuffer + stream->bufferLength;
     CFIndex numChars = end - stream->mark;
     CFAssert(stream->mark, __kCFLogAssertion, "CF internal error: malformed XML input stream");
@@ -559,7 +559,7 @@ static void restoreToMark(_CFXMLInputStream *stream, UniChar *mark) {
     }
 }
 
-__private_extern__ void _inputStreamBackUpToMark(_CFXMLInputStream *stream) {
+CF_PRIVATE void _inputStreamBackUpToMark(_CFXMLInputStream *stream) {
     CFAssert(stream->mark != NULL || stream->charBuffer == NULL, __kCFLogAssertion, "CF internal error: malformed XML input stream");
     restoreToMark(stream, stream->mark);
 }
@@ -568,7 +568,7 @@ CF_INLINE Boolean isWhitespaceChar(UniChar ch) {
     return (ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t');
 }
 
-__private_extern__ CFIndex _inputStreamSkipWhitespace(_CFXMLInputStream *stream, CFMutableStringRef str) {
+CF_PRIVATE CFIndex _inputStreamSkipWhitespace(_CFXMLInputStream *stream, CFMutableStringRef str) {
     UniChar ch;
     CFIndex len = 0;
     if (str) {
@@ -588,7 +588,7 @@ __private_extern__ CFIndex _inputStreamSkipWhitespace(_CFXMLInputStream *stream,
 }
 
 // false return means EOF was encountered without finding scanChars
-__private_extern__ Boolean _inputStreamScanToCharacters(_CFXMLInputStream *stream, const UniChar *scanChars, CFIndex numChars, CFMutableStringRef str) {
+CF_PRIVATE Boolean _inputStreamScanToCharacters(_CFXMLInputStream *stream, const UniChar *scanChars, CFIndex numChars, CFMutableStringRef str) {
     Boolean done = false;
     CFIndex firstRepeatIndex = -1;
     CFIndex len = 0;
@@ -636,7 +636,7 @@ __private_extern__ Boolean _inputStreamScanToCharacters(_CFXMLInputStream *strea
     return true;
 }
 
-__private_extern__ Boolean _inputStreamMatchString(_CFXMLInputStream *stream, const UniChar *stringToMatch, CFIndex length) {
+CF_PRIVATE Boolean _inputStreamMatchString(_CFXMLInputStream *stream, const UniChar *stringToMatch, CFIndex length) {
     const UniChar *end = stringToMatch+length;
     const UniChar *sPtr=stringToMatch;
     stream->parserMark = dropMark(stream);
@@ -656,7 +656,7 @@ __private_extern__ Boolean _inputStreamMatchString(_CFXMLInputStream *stream, co
     }
 }
 
-__private_extern__ Boolean _inputStreamScanQuotedString(_CFXMLInputStream *stream, CFMutableStringRef str) {
+CF_PRIVATE Boolean _inputStreamScanQuotedString(_CFXMLInputStream *stream, CFMutableStringRef str) {
     UniChar ch;
     if (!_inputStreamPeekCharacter(stream, &ch)) return false;
     if (ch != '\'' && ch != '\"')  return false;
@@ -685,7 +685,7 @@ __private_extern__ Boolean _inputStreamScanQuotedString(_CFXMLInputStream *strea
  CombiningChar == kCFUniCharNonBaseCharacterSet
  Extender - complex, and not represented by a uniform character set.
  */
-__private_extern__ Boolean _inputStreamScanXMLName(_CFXMLInputStream *stream, Boolean isNMToken, CFStringRef *str) {
+CF_PRIVATE Boolean _inputStreamScanXMLName(_CFXMLInputStream *stream, Boolean isNMToken, CFStringRef *str) {
     UniChar ch;
     Boolean success = true;
     stream->parserMark = dropMark(stream);
index 0eadcee4712ae210e9911c2ec7f1439a025e6f75..9fb453295e4b81368042e81595b20a6d5c6ca416 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLInputStream.h
-       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFXMLINPUTSTREAM__)
index 10700d5b25219561d53b50fdd40a0266af3218a2..84653d24b7036937c56660abd23bf7410fa330f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLNode.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -139,7 +139,7 @@ static CFHashCode __CFXMLNodeHash(CFTypeRef  cf) {
 
 static CFStringRef __CFXMLNodeCopyDescription(CFTypeRef  cf) {
     struct __CFXMLNode *node = (struct __CFXMLNode *)cf;
-    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFXMLNode %p>{typeID = %d, string = %@}"), cf, node->dataTypeID, node->dataString);
+    return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("CFXMLNode %p>{typeID = %ld, string = %@}"), cf, (unsigned long)node->dataTypeID, node->dataString);
 }
 
 static void __CFXMLNodeDeallocate(CFTypeRef  cf) {
index 8be66f48b45e1a9fc3af16f4fab6a20d342f880a..17171727d00d5b4b5aed8d24a488e930d4443a71 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLNode.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*  CFXMLParser (and thus CFXMLNode) are deprecated as of Mac OS X 10.8 and iOS 6.0. The suggested replacements are the Foundation classes NSXMLParser and NSXMLDocument, or the libxml2 library. */
index 16dda0460ab94c26dc44dc8cdaea50c7407d8ba6..108f59e5a86e399adfe9d68359b1731e5cc87d43 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLParser.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index aa5b54d4fd6ab3d20901aef123b86530240d45c5..f151434711fb8d5312a220def53eaec3f58166c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLParser.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 /*  CFXMLParser is deprecated as of Mac OS X 10.8. The suggested replacements are the Foundation classes NSXMLParser and NSXMLDocument, or the libxml2 library. */
index 03a9b0dd051d4a2f072c86da8313ed7154550fc7..a87cbbec77028b0825fabdcb0851eebe055caf79 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLPreferencesDomain.c
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -62,7 +62,7 @@ static void getXMLKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, void *x
 static CFDictionaryRef copyXMLDomainDictionary(CFTypeRef context, void *domain);
 static void setXMLDomainIsWorldReadable(CFTypeRef context, void *domain, Boolean isWorldReadable);
 
-__private_extern__ const _CFPreferencesDomainCallBacks __kCFXMLPropertyListDomainCallBacks = {createXMLDomain, freeXMLDomain, fetchXMLValue, writeXMLValue, synchronizeXMLDomain, getXMLKeysAndValues, copyXMLDomainDictionary, setXMLDomainIsWorldReadable};
+CF_PRIVATE const _CFPreferencesDomainCallBacks __kCFXMLPropertyListDomainCallBacks = {createXMLDomain, freeXMLDomain, fetchXMLValue, writeXMLValue, synchronizeXMLDomain, getXMLKeysAndValues, copyXMLDomainDictionary, setXMLDomainIsWorldReadable};
 
 // Directly ripped from Foundation....
 static void __CFMilliSleep(uint32_t msecs) {
index 0c704a340723a9a1d0f4412c7df24feb5709d28e..9af9cc9ba15eeb1082dd2ee41d85e74d4bc46225 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLTree.c
-       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2013, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -55,7 +55,7 @@ CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlNode) {
 }
 
 // We will probably ultimately want to export this under some public API name
-__private_extern__ Boolean CFXMLTreeEqual(CFXMLTreeRef xmlTree1, CFXMLTreeRef xmlTree2) {
+CF_PRIVATE Boolean CFXMLTreeEqual(CFXMLTreeRef xmlTree1, CFXMLTreeRef xmlTree2) {
     CFXMLNodeRef node1, node2;
     CFXMLTreeRef child1, child2;
     if (CFTreeGetChildCount(xmlTree1) != CFTreeGetChildCount(xmlTree2)) return false;
@@ -101,7 +101,7 @@ static void _CFAppendXML(CFMutableStringRef str, CFXMLTreeRef tree) {
     _CFAppendXMLEpilog(str, tree);
 }
 
-__private_extern__ void appendQuotedString(CFMutableStringRef str, CFStringRef strToQuote) {
+CF_PRIVATE void appendQuotedString(CFMutableStringRef str, CFStringRef strToQuote) {
     char quoteChar = CFStringFindWithOptions(strToQuote, CFSTR("\""), CFRangeMake(0, CFStringGetLength(strToQuote)), 0, NULL) ? '\'' : '\"';
     CFStringAppendFormat(str, NULL, CFSTR("%c%@%c"), quoteChar, strToQuote, quoteChar);
 }
@@ -158,7 +158,7 @@ static void _CFAppendXMLProlog(CFMutableStringRef str, const CFXMLTreeRef tree)
             if (data->dataString) {
                 CFStringAppendFormat(str, NULL, CFSTR("<?%@ %@?>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)), data->dataString);
             } else {
-                CFStringAppendFormat(str, NULL, CFSTR("<?%@?>"));
+                CFStringAppendFormat(str, NULL, CFSTR("<?%@?>"), CFXMLNodeGetString(CFXMLTreeGetNode(tree)));
             }
             break;
         }
index 100e4e512094f45650f1398fc59b2248744e81e8..ead85b057732d874885b259e32a35deb3d11a1be 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CoreFoundation.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_COREFOUNDATION__)
index f353a9a13b89b1c7baefff87b5e2643a77f429d9..e40a7f3845ba2927b049c7d067f5eb70a9d2631d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     CoreFoundation_Prefix.h
-       Copyright (c) 2005-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2005-2013, Apple Inc. All rights reserved.
 */
 
 
@@ -61,8 +61,7 @@ typedef char * Class;
 #import <pthread.h>
 #endif
 
-/* This macro creates 3 helper functions which are useful in dealing with libdispatch:
- *  __ PREFIX SyncDispatchIsSafe  -- returns bool indicating whether calling dispatch_sync() would be safe from self-deadlock
+/* This macro creates some helper functions which are useful in dealing with libdispatch:
  *  __ PREFIX Queue -- manages and returns a singleton serial queue
  *
  * Use the macro like this:
@@ -70,11 +69,6 @@ typedef char * Class;
  */
 
 #define DISPATCH_HELPER_FUNCTIONS(PREFIX, QNAME)                       \
-static Boolean __ ## PREFIX ## SyncDispatchIsSafe(dispatch_queue_t Q) {        \
-    dispatch_queue_t C = dispatch_get_current_queue();                 \
-    return (!C || Q != C) ? true : false;                              \
-}                                                                      \
-                                                                       \
 static dispatch_queue_t __ ## PREFIX ## Queue(void) {                  \
     static volatile dispatch_queue_t __ ## PREFIX ## dq = NULL;                \
     if (!__ ## PREFIX ## dq) {                                         \
@@ -112,7 +106,7 @@ typedef int         boolean_t;
 
 #if DEPLOYMENT_TARGET_LINUX
     
-#define __private_extern__
+#define CF_PRIVATE
 #define __strong
 #define __weak
 
@@ -123,9 +117,34 @@ typedef int                boolean_t;
 #define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c)
 
 #define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__)
-    
-#define strlcat(a,b,c) strncat(a,b,c)
-#define strlcpy(a,b,c) strncpy(a,b,c)
+
+#include <pthread.h>
+
+CF_INLINE size_t
+strlcpy(char * dst, const char * src, size_t maxlen) {
+    const size_t srclen = strlen(src);
+    if (srclen < maxlen) {
+        memcpy(dst, src, srclen+1);
+    } else if (maxlen != 0) {
+        memcpy(dst, src, maxlen-1);
+        dst[maxlen-1] = '\0';
+    }
+    return srclen;
+}
+
+CF_INLINE size_t
+strlcat(char * dst, const char * src, size_t maxlen) {
+    const size_t srclen = strlen(src);
+    const size_t dstlen = strnlen(dst, maxlen);
+    if (dstlen == maxlen) return maxlen+srclen;
+    if (srclen < maxlen-dstlen) {
+        memcpy(dst+dstlen, src, srclen+1);
+    } else {
+        memcpy(dst+dstlen, src, maxlen-dstlen-1);
+        dst[maxlen-1] = '\0';
+    }
+    return dstlen + srclen;
+}
 
 #define issetugid() 0
     
@@ -133,7 +152,8 @@ typedef int         boolean_t;
 bool OSAtomicCompareAndSwapPtr(void *oldp, void *newp, void *volatile *dst);
 bool OSAtomicCompareAndSwapLong(long oldl, long newl, long volatile *dst);
 bool OSAtomicCompareAndSwapPtrBarrier(void *oldp, void *newp, void *volatile *dst);
-
+bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
+    
 int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst);
 int32_t OSAtomicIncrement32Barrier(volatile int32_t *dst);
 int32_t OSAtomicIncrement32(volatile int32_t *theValue);
@@ -149,6 +169,11 @@ void OSMemoryBarrier();
 CF_INLINE size_t malloc_size(void *memblock) {
     return malloc_usable_size(memblock);
 }
+    
+// substitute for dispatch_once
+typedef pthread_once_t dispatch_once_t;
+typedef void (^dispatch_block_t)(void);
+void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block);
 
 #endif
 
@@ -178,7 +203,7 @@ CF_INLINE size_t malloc_size(void *memblock) {
 #define mode_t uint16_t
         
 // This works because things aren't actually exported from the DLL unless they have a __declspec(dllexport) on them... so extern by itself is closest to __private_extern__ on Mac OS
-#define __private_extern__ extern
+#define CF_PRIVATE extern
     
 #define __builtin_expect(P1,P2) P1
     
@@ -239,6 +264,8 @@ typedef int gid_t;
 #define getuid() 0
 #define getegid() 0
 
+#define scalbn(A, B) _scalb(A, B)
+
 #define fsync(a) _commit(a)
 #define malloc_create_zone(a,b) 123
 #define malloc_set_zone_name(zone,name)
@@ -278,14 +305,38 @@ CF_INLINE long long llabs(long long v) {
 #define strtoul_l(a,b,c,locale) strtoul(a,b,c)
 #define strtol_l(a,b,c,locale) strtol(a,b,c)
 #define strtoll_l(a,b,c,locale) _strtoi64(a,b,c)
+#define strncasecmp(a, b, c) _strnicmp(a, b, c)
 #define strncasecmp_l(a, b, c, d) _strnicmp(a, b, c)
 #define snprintf _snprintf
 
 #define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__)
 
-#define strlcat(a,b,c) strncat(a,b,c)
-#define strlcpy(a,b,c) strncpy(a,b,c)
-    
+CF_INLINE size_t
+strlcpy(char * dst, const char * src, size_t maxlen) {
+    const size_t srclen = strlen(src);
+    if (srclen < maxlen) {
+        memcpy(dst, src, srclen+1);
+    } else if (maxlen != 0) {
+        memcpy(dst, src, maxlen-1);
+        dst[maxlen-1] = '\0';
+    }
+    return srclen;
+}
+
+CF_INLINE size_t
+strlcat(char * dst, const char * src, size_t maxlen) {
+    const size_t srclen = strlen(src);
+    const size_t dstlen = strnlen(dst, maxlen);
+    if (dstlen == maxlen) return maxlen+srclen;
+    if (srclen < maxlen-dstlen) {
+        memcpy(dst+dstlen, src, srclen+1);
+    } else {
+        memcpy(dst+dstlen, src, maxlen-dstlen-1);
+        dst[maxlen-1] = '\0';
+    }
+    return dstlen + srclen;
+}
+
 #define sleep(x) Sleep(1000*x)
 
 #define issetugid() 0
@@ -322,6 +373,10 @@ CF_EXPORT int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *_
     
 #endif
 
+#if !defined(CF_PRIVATE)
+#define CF_PRIVATE __attribute__((__visibility__("hidden")))
+#endif
+
 #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
 
 #include <stdarg.h>
@@ -341,7 +396,7 @@ CF_INLINE int popcountll(long long x) {
     return count;
 }
 
-__private_extern__ int asprintf(char **ret, const char *format, ...);
+CF_PRIVATE int asprintf(char **ret, const char *format, ...);
 
 #endif
 
index 2a304eac518b3003dede9a6ddb0d675e9e2ea147..14711b01a9ed1f2881225cab6579182716a51cb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -22,7 +22,7 @@
  */
 
 /*     ForFoundationOnly.h
-       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2013, Apple Inc. All rights reserved.
 */
 
 #if !CF_BUILDING_CF && !NSBUILDINGFOUNDATION
@@ -77,14 +77,9 @@ CF_EXPORT const CFStringRef _kCFBundleResolvedPathKey;
 CF_EXPORT const CFStringRef _kCFBundlePrincipalClassKey;
 
 #if __BLOCKS__
-CF_EXPORT CFArrayRef _CFFindBundleResources(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef subDirName, CFArrayRef searchLanguages, CFStringRef resName, CFArrayRef resTypes, CFIndex limit, Boolean (^predicate)(CFStringRef filename, Boolean *stop), UInt8 version);
-// new look up algorithm is in place (look for CFBUNDLE_NEWLOOKUP)
 CF_EXPORT CFTypeRef _CFBundleCopyFindResources(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subPath, CFStringRef lproj, Boolean returnArray, Boolean localized, Boolean (^predicate)(CFStringRef filename, Boolean *stop));
 #endif
 
-CF_EXPORT UInt8 _CFBundleLayoutVersion(CFBundleRef bundle);
-
-CF_EXPORT CFArrayRef _CFBundleCopyLanguageSearchListInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt8 *version);
 CF_EXPORT CFArrayRef _CFBundleGetLanguageSearchList(CFBundleRef bundle);
 
 CF_EXPORT Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceGlobal, CFErrorRef *error);
@@ -177,6 +172,38 @@ CF_EXTERN_C_END
 
 #include <CoreFoundation/CFStringEncodingExt.h>
 
+#define NSSTRING_BOUNDSERROR \
+    [NSException raise:NSRangeException format:@"%@: Range or index out of bounds", __CFExceptionProem((id)self, _cmd)]
+
+#define NSSTRING_RANGEERROR(range, len) \
+    [NSException raise:NSRangeException format:@"%@: Range {%lu, %lu} out of bounds; string length %lu", __CFExceptionProem((id)self, _cmd), (unsigned long)range.location, (unsigned long)range.length, (unsigned long)len]
+
+#define NSSTRING_INDEXERROR(index, len) \
+    [NSException raise:NSRangeException format:@"%@: Index %lu out of bounds; string length %lu", __CFExceptionProem((id)self, _cmd), (unsigned long)index, (unsigned long)len]
+
+// This can be made into an exception for post-10.9 apps
+#define NSSTRING_POSSIBLE_RANGEERROR(range, len)     \
+    if (__CFStringNoteErrors()) {       \
+        static bool warnonce = false;   \
+        if (!warnonce) {                \
+            warnonce = true;            \
+            CFLog(kCFLogLevelWarning, CFSTR("*** %@: Range {%lu, %lu} out of bounds; string length %lu. This will become an exception for apps linked after 10.9. Warning shown once per app execution."), __CFExceptionProem((id)self, _cmd), (unsigned long)range.location, (unsigned long)range.length, (unsigned long)len);        \
+    }   \
+}
+
+#define NSSTRING_ILLEGALREQUESTERROR \
+    [NSException raise:NSInvalidArgumentException format:@"Can't call %s in %@", sel_getName(_cmd), object_getClass((id)self)]
+
+#define NSSTRING_INVALIDMUTATIONERROR \
+    [NSException raise:NSInvalidArgumentException format:@"Attempt to mutate immutable object with %s", sel_getName(_cmd)]
+
+#define NSSTRING_NULLCSTRINGERROR \
+    [NSException raise:NSInvalidArgumentException format:@"%@: NULL cString", __CFExceptionProem((id)self, _cmd)]
+
+#define NSSTRING_NILSTRINGERROR \
+    [NSException raise:NSInvalidArgumentException format:@"%@: nil argument", __CFExceptionProem((id)self, _cmd)]
+
+
 CF_EXTERN_C_BEGIN
 
 /* Create a byte stream from a CFString backing. Can convert a string piece at a
@@ -285,12 +312,10 @@ CF_INLINE Boolean __CFIsWhitespace(UniChar theChar) {
 /* Same as CFStringGetCharacterFromInlineBuffer() but returns 0xFFFF on out of bounds access
 */
 CF_INLINE UniChar __CFStringGetCharacterFromInlineBufferAux(CFStringInlineBuffer *buf, CFIndex idx) {
-    if (buf->directBuffer) {
-       if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0xFFFF;
-        return buf->directBuffer[idx + buf->rangeToBuffer.location];
-    }
+    if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0xFFFF;
+    if (buf->directUniCharBuffer) return buf->directUniCharBuffer[idx + buf->rangeToBuffer.location];
+    if (buf->directCStringBuffer) return (UniChar)(buf->directCStringBuffer[idx + buf->rangeToBuffer.location]);
     if (idx >= buf->bufferedRangeEnd || idx < buf->bufferedRangeStart) {
-       if (idx < 0 || idx >= buf->rangeToBuffer.length) return 0xFFFF;
        if ((buf->bufferedRangeStart = idx - 4) < 0) buf->bufferedRangeStart = 0;
        buf->bufferedRangeEnd = buf->bufferedRangeStart + __kCFStringInlineBufferLength;
        if (buf->bufferedRangeEnd > buf->rangeToBuffer.length) buf->bufferedRangeEnd = buf->rangeToBuffer.length;
@@ -302,7 +327,8 @@ CF_INLINE UniChar __CFStringGetCharacterFromInlineBufferAux(CFStringInlineBuffer
 /* Same as CFStringGetCharacterFromInlineBuffer(), but without the bounds checking (will return garbage or crash)
 */
 CF_INLINE UniChar __CFStringGetCharacterFromInlineBufferQuick(CFStringInlineBuffer *buf, CFIndex idx) {
-    if (buf->directBuffer) return buf->directBuffer[idx + buf->rangeToBuffer.location];
+    if (buf->directUniCharBuffer) return buf->directUniCharBuffer[idx + buf->rangeToBuffer.location];
+    if (buf->directCStringBuffer) return (UniChar)(buf->directCStringBuffer[idx + buf->rangeToBuffer.location]);
     if (idx >= buf->bufferedRangeEnd || idx < buf->bufferedRangeStart) {
        if ((buf->bufferedRangeStart = idx - 4) < 0) buf->bufferedRangeStart = 0;
        buf->bufferedRangeEnd = buf->bufferedRangeStart + __kCFStringInlineBufferLength;
@@ -499,9 +525,9 @@ CF_EXPORT CFStringRef _CFErrorCreateLocalizedRecoverySuggestion(CFErrorRef err);
 CF_EXPORT CFStringRef _CFErrorCreateDebugDescription(CFErrorRef err);
 
 CF_EXPORT CFURLRef _CFURLAlloc(CFAllocatorRef allocator);
-CF_EXPORT void _CFURLInitWithString(CFURLRef url, CFStringRef string, CFURLRef baseURL);
-CF_EXPORT void _CFURLInitFSPath(CFURLRef url, CFStringRef path);
-CF_EXPORT Boolean _CFStringIsLegalURLString(CFStringRef string);
+CF_EXPORT Boolean _CFURLInitWithURLString(CFURLRef uninitializedURL, CFStringRef string, Boolean checkForLegalCharacters, CFURLRef baseURL);
+CF_EXPORT Boolean _CFURLInitWithFileSystemPath(CFURLRef uninitializedURL, CFStringRef fileSystemPath, CFURLPathStyle pathStyle, Boolean isDirectory, CFURLRef baseURL);
+CF_EXPORT Boolean _CFURLInitWithFileSystemRepresentation(CFURLRef uninitializedURL, const UInt8 *buffer, CFIndex bufLen, Boolean isDirectory, CFURLRef baseURL);
 CF_EXPORT void *__CFURLReservedPtr(CFURLRef  url);
 CF_EXPORT void __CFURLSetReservedPtr(CFURLRef  url, void *ptr);
 CF_EXPORT CFStringEncoding _CFURLGetEncoding(CFURLRef url);
index 944c11fbd93d60b1f6ab8204b342115f7b21a2d0..6cca5eb6ffc0f5a311536184228832d8c4d3b208 100644 (file)
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.8</string>
+       <string>6.9</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>$(CURRENT_PROJECT_VERSION)</string>
-        <key>CarbonLazyValues</key>
-        <dict>
-               <key>CodeFragmentManager</key>
-               <dict>
-                       <key>CoreFoundation</key>
-                       <string>CFMPriv_CoreFoundation</string>
-               </dict>
-        </dict>
 </dict>
 </plist>
index 7093efad54dee46297b596d894e7a13e4a3b5db1..10522542690ae1591bd7b631c058bbe716feed8f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,17 +1,17 @@
 
 include MakefileVersion
 
-MIN_MACOSX_VERSION=10.8
-MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_8
+MIN_MACOSX_VERSION=10.9
+MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_9
 
 OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c))
 OBJECTS += CFBasicHash.o
 HFILES = $(wildcard *.h)
 INTERMEDIATE_HFILES = $(addprefix $(OBJBASE)/CoreFoundation/,$(HFILES))
 
-PUBLIC_HEADERS=CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFBundle.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMessagePort.h CFNumber.h CFNumberFormatter.h CFPlugIn.h CFPlugInCOM.h CFPreferences.h CFPropertyList.h CFRunLoop.h CFSet.h CFSocket.h CFStream.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CFUserNotification.h CFXMLNode.h CFXMLParser.h CoreFoundation.h
+PUBLIC_HEADERS=CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFBundle.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMessagePort.h CFNumber.h CFNumberFormatter.h CFPlugIn.h CFPlugInCOM.h CFPreferences.h CFPropertyList.h CFRunLoop.h CFSet.h CFSocket.h CFStream.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CFUserNotification.h CFXMLNode.h CFXMLParser.h CFAvailability.h CFUtilities.h CoreFoundation.h
 
-PRIVATE_HEADERS=CFBundlePriv.h CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStreamAbstract.h CFStreamPriv.h CFStreamInternal.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h CFBurstTrie.h
+PRIVATE_HEADERS=CFBundlePriv.h CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStreamAbstract.h CFStreamPriv.h CFStreamInternal.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h CFBurstTrie.h CFICULogging.h
 
 MACHINE_TYPE := $(shell uname -p)
 unicode_data_file_name = $(if $(or $(findstring i386,$(1)),$(findstring i686,$(1)),$(findstring x86_64,$(1))),CFUnicodeData-L.mapping,CFUnicodeData-B.mapping)
index 19e6ee73a82d6425c1a14a7cfa920ccbb6411de2..ec1f9972e7a6e492618f66a220f2e572a041bb6d 100644 (file)
@@ -1,17 +1,17 @@
 
 include MakefileVersion
 
-MIN_MACOSX_VERSION=10.7
-MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_7
+MIN_MACOSX_VERSION=10.9
+MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_9
 
 OBJECTS = CFCharacterSet.o CFPreferences.o CFApplicationPreferences.o CFXMLPreferencesDomain.o CFStringEncodingConverter.o CFUniChar.o CFArray.o CFOldStylePList.o CFPropertyList.o CFStringEncodingDatabase.o CFUnicodeDecomposition.o CFBag.o CFData.o  CFStringEncodings.o CFUnicodePrecomposition.o CFBase.o CFDate.o CFNumber.o CFRuntime.o CFStringScanner.o CFBinaryHeap.o CFDateFormatter.o CFNumberFormatter.o CFSet.o CFStringUtilities.o CFUtilities.o CFBinaryPList.o CFDictionary.o CFPlatform.o CFSystemDirectories.o CFVersion.o CFBitVector.o CFError.o CFPlatformConverters.o CFTimeZone.o  CFBuiltinConverters.o CFFileUtilities.o  CFSortFunctions.o CFTree.o CFICUConverters.o CFURL.o CFLocale.o  CFURLAccess.o CFCalendar.o CFLocaleIdentifier.o CFString.o CFUUID.o CFStorage.o CFLocaleKeys.o
 OBJECTS += CFBasicHash.o
 HFILES = $(wildcard *.h)
 INTERMEDIATE_HFILES = $(addprefix $(OBJBASE)/CoreFoundation/,$(HFILES))
 
-PUBLIC_HEADERS=CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMachPort.h CFNumber.h CFNumberFormatter.h CFPreferences.h CFPropertyList.h CFSet.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CoreFoundation.h TargetConditionals.h
+PUBLIC_HEADERS=CFArray.h CFBag.h CFBase.h CFBinaryHeap.h CFBitVector.h CFByteOrder.h CFCalendar.h CFCharacterSet.h CFData.h CFDate.h CFDateFormatter.h CFDictionary.h CFError.h CFLocale.h CFMachPort.h CFNumber.h CFNumberFormatter.h CFPreferences.h CFPropertyList.h CFSet.h CFString.h CFStringEncodingExt.h CFTimeZone.h CFTree.h CFURL.h CFURLAccess.h CFUUID.h CFAvailability.h CFUtilities.h CoreFoundation.h TargetConditionals.h
 
-PRIVATE_HEADERS= CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h 
+PRIVATE_HEADERS= CFCharacterSetPriv.h CFError_Private.h CFLogUtilities.h CFPriv.h CFRuntime.h CFStorage.h CFStringDefaultEncoding.h CFStringEncodingConverter.h CFStringEncodingConverterExt.h CFUniChar.h CFUnicodeDecomposition.h CFUnicodePrecomposition.h ForFoundationOnly.h CFICULogging.h
 
 RESOURCES = CFCharacterSetBitmaps.bitmap CFUnicodeData-L.mapping CFUnicodeData-B.mapping
 
index 261dcb6a4a5aa8673099d7dfd2e02f21d1418a86..5e02d2ef000a9cbcde496ee7afdbb7207468568e 100644 (file)
@@ -1 +1 @@
-VERSION=744.12
+VERSION=855.11
index 84b94212390fcfcc29c98469a2adbde74a217208..6380cdb3419d899d39bee1f60d083a9b9b05c06d 100644 (file)
@@ -93,4 +93,6 @@ _kCFNumberFormatterSecondaryGroupingSizeKey   _kCFNumberFormatterSecondaryGrouping
 _kCFNumberFormatterUseGroupingSeparatorKey     _kCFNumberFormatterUseGroupingSeparator
 _kCFNumberFormatterUseSignificantDigitsKey     _kCFNumberFormatterUseSignificantDigits
 _kCFNumberFormatterZeroSymbolKey               _kCFNumberFormatterZeroSymbol
+_kCFNumberFormatterUsesCharacterDirectionKey   _kCFNumberFormatterUsesCharacterDirection
+_kCFDateFormatterUsesCharacterDirectionKey     _kCFDateFormatterUsesCharacterDirection
 _kCFDateFormatterCalendarIdentifierKey         _kCFDateFormatterCalendarName
index b256dae79da6246886e7e6783bf2eaaaf6762138..80cb7a34eb2909b589228c3c72d0f39a3f1be515 100644 (file)
@@ -1,5 +1,5 @@
 /*     TargetConditionals.h
-       Copyright (c) 2010-2012, Apple Inc. All rights reserved.
+       Copyright (c) 2010-2013, Apple Inc. All rights reserved.
        For CF on Linux ONLY
 */
 
index 2a886ed7003f5f599cc0f226cd6f03c200753731..480e63b44aba4ec62def734c5eeef243d566583e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012 Apple Inc. All rights reserved.
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *