]> git.saurik.com Git - apple/cf.git/commitdiff
CF-744.tar.gz mac-os-x-108 mac-os-x-1081 v744
authorApple <opensource@apple.com>
Thu, 23 Aug 2012 20:45:35 +0000 (20:45 +0000)
committerApple <opensource@apple.com>
Thu, 23 Aug 2012 20:45:35 +0000 (20:45 +0000)
151 files changed:
CFApplicationPreferences.c
CFArray.c
CFArray.h
CFBag.c
CFBag.h
CFBase.c
CFBase.h
CFBasicHash.c [new file with mode: 0644]
CFBasicHash.h
CFBasicHash.m [deleted file]
CFBasicHashFindBucket.m
CFBigNumber.c [new file with mode: 0644]
CFBigNumber.h [new file with mode: 0644]
CFBinaryHeap.c
CFBinaryHeap.h
CFBinaryPList.c
CFBitVector.c
CFBitVector.h
CFBuiltinConverters.c
CFBundle.c
CFBundle.h
CFBundlePriv.h
CFBundle_BinaryTypes.h
CFBundle_Internal.h
CFBundle_Resources.c
CFBurstTrie.c [new file with mode: 0644]
CFBurstTrie.h [new file with mode: 0644]
CFByteOrder.h
CFCalendar.c
CFCalendar.h
CFCharacterSet.c
CFCharacterSet.h
CFCharacterSetBitmaps.bitmap
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
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 [new file with mode: 0644]
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
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
CFURLAccess.c
CFURLAccess.h
CFURLPriv.h
CFUUID.c
CFUUID.h
CFUniChar.c
CFUniChar.h
CFUniCharPriv.h
CFUniCharPropertyDatabase.data
CFUnicodeData-B.mapping
CFUnicodeData-L.mapping
CFUnicodeDecomposition.c
CFUnicodeDecomposition.h
CFUnicodePrecomposition.c
CFUnicodePrecomposition.h
CFUserNotification.c
CFUserNotification.h
CFUtilities.c
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
TargetConditionals.h

index a66a8d95aecd54d3a84e3840079845fcc59d22bb..937d7cdf7462bea63c8c85592a5cbebf3fe45ce5 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFApplicationPreferences.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index 8c38e1552674587ccd3bc89c07a18e9dc6b8fee2..ff1bc597b863cf3c640607e94bd142d3a6839eaa 100644 (file)
--- a/CFArray.c
+++ b/CFArray.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFArray.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -31,6 +31,7 @@
 #include "CFInternal.h"
 #include <string.h>
 
+
 const CFArrayCallBacks kCFTypeArrayCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual};
 static const CFArrayCallBacks __kCFNullArrayCallBacks = {0, NULL, NULL, NULL, NULL};
 
@@ -314,6 +315,7 @@ static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) {
 static void __CFArrayDeallocate(CFTypeRef cf) {
     CFArrayRef array = (CFArrayRef)cf;
     BEGIN_MUTATION(array);
+#if DEPLOYMENT_TARGET_MACOSX
     // Under GC, keep contents alive when we know we can, either standard callbacks or NULL
     // if (__CFBitfieldGetValue(cf->info, 5, 4)) return; // bits only ever set under GC
     CFAllocatorRef allocator = __CFGetAllocator(array);
@@ -334,6 +336,7 @@ static void __CFArrayDeallocate(CFTypeRef cf) {
             return;
         }
     }
+#endif
     __CFArrayReleaseValues(array, CFRangeMake(0, __CFArrayGetCount(array)), true);
     END_MUTATION(array);
 }
@@ -544,7 +547,7 @@ CFMutableArrayRef CFArrayCreateMutableCopy(CFAllocatorRef allocator, CFIndex cap
 #endif
 
 CFIndex CFArrayGetCount(CFArrayRef array) {
-    CF_OBJC_FUNCDISPATCH0(__kCFArrayTypeID, CFIndex, array, "count");
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, CFIndex, (NSArray *)array, count);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CHECK_FOR_MUTATION(array);
     return __CFArrayGetCount(array);
@@ -582,7 +585,7 @@ Boolean CFArrayContainsValue(CFArrayRef array, CFRange range, const void *value)
 }
 
 const void *CFArrayGetValueAtIndex(CFArrayRef array, CFIndex idx) {
-    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void *, array, "objectAtIndex:", idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, const void *, (NSArray *)array, objectAtIndex:idx);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
     CHECK_FOR_MUTATION(array);
@@ -598,7 +601,7 @@ const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx) {
 
 
 void CFArrayGetValues(CFArrayRef array, CFRange range, const void **values) {
-    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "getObjects:range:", values, range);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSArray *)array, getObjects:(id *)values range:NSMakeRange(range.location, range.length));
     __CFGenericValidateType(array, __kCFArrayTypeID);
     __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
     CFAssert1(NULL != values, __kCFLogAssertion, "%s(): pointer to values may not be NULL", __PRETTY_FUNCTION__);
@@ -682,7 +685,8 @@ CFIndex CFArrayGetLastIndexOfValue(CFArrayRef array, CFRange range, const void *
 }
 
 void CFArrayAppendValue(CFMutableArrayRef array, const void *value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void, array, "addObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, addObject:(id)value);
+    
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
     CHECK_FOR_MUTATION(array);
@@ -690,7 +694,7 @@ void CFArrayAppendValue(CFMutableArrayRef array, const void *value) {
 }
 
 void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) {
-    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "setObject:atIndex:", value, idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, setObject:(id)value atIndex:(NSUInteger)idx);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
     CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
@@ -717,7 +721,7 @@ void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *va
 }
 
 void CFArrayInsertValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *value) {
-    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "insertObject:atIndex:", value, idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, insertObject:(id)value atIndex:(NSUInteger)idx);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
     CFAssert2(0 <= idx && idx <= __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
@@ -730,7 +734,7 @@ void CFArrayInsertValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void
 void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFIndex idx2) {
     const void *tmp;
     struct __CFArrayBucket *bucket1, *bucket2;
-    CF_OBJC_FUNCDISPATCH2(__kCFArrayTypeID, void, array, "exchangeObjectAtIndex:withObjectAtIndex:", idx1, idx2);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert2(0 <= idx1 && idx1 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #1 (%d) out of bounds", __PRETTY_FUNCTION__, idx1);
     CFAssert2(0 <= idx2 && idx2 < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index #2 (%d) out of bounds", __PRETTY_FUNCTION__, idx2);
@@ -748,7 +752,7 @@ void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFInd
 }
 
 void CFArrayRemoveValueAtIndex(CFMutableArrayRef array, CFIndex idx) {
-    CF_OBJC_FUNCDISPATCH1(__kCFArrayTypeID, void, array, "removeObjectAtIndex:", idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, removeObjectAtIndex:(NSUInteger)idx);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
     CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%d) out of bounds", __PRETTY_FUNCTION__, idx);
@@ -757,7 +761,7 @@ void CFArrayRemoveValueAtIndex(CFMutableArrayRef array, CFIndex idx) {
 }
 
 void CFArrayRemoveAllValues(CFMutableArrayRef array) {
-    CF_OBJC_FUNCDISPATCH0(__kCFArrayTypeID, void, array, "removeAllObjects");
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, removeAllObjects);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
     CHECK_FOR_MUTATION(array);
@@ -905,7 +909,7 @@ void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) {
 
 
 void CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void **newValues, CFIndex newCount) {
-    CF_OBJC_FUNCDISPATCH3(__kCFArrayTypeID, void, array, "replaceObjectsInRange:withObjects:count:", range, (void **)newValues, newCount);
+    CF_OBJC_FUNCDISPATCHV(__kCFArrayTypeID, void, (NSMutableArray *)array, replaceObjectsInRange:NSMakeRange(range.location, range.length) withObjects:(id *)newValues count:(NSUInteger)newCount);
     __CFGenericValidateType(array, __kCFArrayTypeID);
     __CFArrayValidateRange(array, range, __PRETTY_FUNCTION__);
     CFAssert1(__CFArrayGetType(array) != __kCFArrayImmutable, __kCFLogAssertion, "%s(): array is immutable", __PRETTY_FUNCTION__);
@@ -1037,7 +1041,7 @@ void CFArraySortValues(CFMutableArrayRef array, CFRange range, CFComparatorFunct
     Boolean immutable = false;
     if (CF_IS_OBJC(__kCFArrayTypeID, array)) {
         BOOL result;
-        CF_OBJC_CALL1(BOOL, result, array, "isKindOfClass:", objc_lookUpClass("NSMutableArray"));
+        result = CF_OBJC_CALLV((NSMutableArray *)array, isKindOfClass:[NSMutableArray class]);
         immutable = !result;
     } else if (__kCFArrayImmutable == __CFArrayGetType(array)) {
         immutable = true;
index 069d6205e03c4e70f24e8ddbbc3850465f27ff06..020cece2d3c8b42ff05e85d4b97785eadd6f0a04 100644 (file)
--- a/CFArray.h
+++ b/CFArray.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFArray.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 /*!
@@ -69,6 +69,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -689,6 +690,7 @@ CF_EXPORT
 void CFArrayAppendArray(CFMutableArrayRef theArray, CFArrayRef otherArray, CFRange otherRange);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFARRAY__ */
 
diff --git a/CFBag.c b/CFBag.c
index d5eb878136370408d4ed707ca70ef9bb968f5d2f..da9e3362b76d5a8814989e64188214680e746685 100644 (file)
--- a/CFBag.c
+++ b/CFBag.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFBag.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -36,6 +36,7 @@
 #include "CFBasicHash.h"
 #include <CoreFoundation/CFString.h>
 
+
 #define CFDictionary 0
 #define CFSet 0
 #define CFBag 0
@@ -217,7 +218,7 @@ static CFBasicHashCallbacks *__CFBagCopyCallbacks(CFConstBasicHashRef ht, CFAllo
     } else {
         newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
     }
-    if (!newcb) HALT;
+    if (!newcb) return NULL;
     memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
     return newcb;
 }
@@ -386,7 +387,7 @@ static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, const CFHas
         } else {
             newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) HALT;
+        if (!newcb) return NULL;
         newcb->copyCallbacks = __CFBagCopyCallbacks;
         newcb->freeCallbacks = __CFBagFreeCallbacks;
         newcb->retainValue = __CFBagRetainValue;
@@ -427,7 +428,8 @@ static CFBasicHashRef __CFBagCreateGeneric(CFAllocatorRef allocator, const CFHas
     }
 
     CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, specialBits);
+    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
+    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
     return ht;
 }
 
@@ -468,6 +470,7 @@ CFHashRef CFBagCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn
     CFTypeID typeID = CFBagGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFBasicHashRef ht = __CFBagCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
+    if (!ht) return NULL;
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
@@ -489,6 +492,7 @@ CFMutableHashRef CFBagCreateMutable(CFAllocatorRef allocator, CFIndex capacity,
     CFTypeID typeID = CFBagGetTypeID();
     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);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)");
@@ -513,8 +517,8 @@ CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -522,6 +526,7 @@ CFHashRef CFBagCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
@@ -548,8 +553,8 @@ CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFBagCreateGeneric(allocator, & kCFTypeBagKeyCallBacks, CFDictionary ? & kCFTypeBagValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -557,6 +562,7 @@ CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFBag (mutable)");
@@ -564,8 +570,8 @@ CFMutableHashRef CFBagCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
 }
 
 CFIndex CFBagGetCount(CFHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID, CFIndex, hc, "count");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID, CFIndex, hc, "count");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, CFIndex, (NSDictionary *)hc, count);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, CFIndex, (NSSet *)hc, count);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     return CFBasicHashGetCount((CFBasicHashRef)hc);
 }
@@ -576,8 +582,8 @@ CFIndex CFBagGetCountOfKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 CFIndex CFBagGetCountOfValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, CFIndex, hc, "countForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, CFIndex, hc, "countForObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, CFIndex, (NSDictionary *)hc, countForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, CFIndex, (NSSet *)hc, countForObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key);
 }
@@ -588,23 +594,23 @@ Boolean CFBagContainsKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 Boolean CFBagContainsValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, char, hc, "containsKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, char, hc, "containsObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, char, (NSDictionary *)hc, containsKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, char, (NSSet *)hc, containsObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key));
 }
 
 const_any_pointer_t CFBagGetValue(CFHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, const_any_pointer_t, hc, "objectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, const_any_pointer_t, hc, "member:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, const_any_pointer_t, (NSSet *)hc, member:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0);
 }
 
 Boolean CFBagGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, Boolean, hc, "__getValue:forKey:", (any_t *)value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, Boolean, hc, "__getValue:forObj:", (any_t *)value, key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -622,19 +628,18 @@ Boolean CFBagGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_
 
 #if CFDictionary
 CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, CFIndex, hc, "countForObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, CFIndex, (NSDictionary *)hc, countForObject:(id)value);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value);
 }
 
 Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, char, hc, "containsObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, char, (NSDictionary *)hc, containsObject:(id)value);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value));
 }
 
 CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) {
-    CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, Boolean, hc, "getActualKey:forKey:", actualkey, key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -658,8 +663,8 @@ void CFBagGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_
 void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
     const_any_pointer_t *valuebuf = 0;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "getObjects:andKeys:", (any_t *)valuebuf, (any_t *)keybuf);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "getObjects:", (any_t *)keybuf);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSSet *)hc, getObjects:(id *)keybuf);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     if (kCFUseCollectableAllocator) {
         CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc);
@@ -681,8 +686,8 @@ void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
 
 void CFBagApplyFunction(CFHashRef hc, CFBagApplierFunction applier, any_pointer_t context) {
     FAULT_CALLBACK((void **)&(applier));
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "__apply:context:", applier, context);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "__applyValues:context:", applier, context);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
 #if CFDictionary
@@ -756,8 +761,8 @@ void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_point
 void CFBagAddValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "addObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "addObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableSet *)hc, addObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -775,8 +780,8 @@ void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_p
 void CFBagReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "replaceObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "replaceObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableSet *)hc, replaceObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -794,8 +799,8 @@ 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_FUNCDISPATCH2(__kCFBagTypeID, void, hc, "setObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "setObject:", 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);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -808,8 +813,8 @@ void CFBagSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFBagRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "removeObjectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFBagTypeID, void, hc, "removeObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableSet *)hc, removeObject:(id)key);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -821,8 +826,8 @@ void CFBagRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFBagRemoveAllValues(CFMutableHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID, void, hc, "removeAllObjects");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFBagTypeID, void, hc, "removeAllObjects");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableDictionary *)hc, removeAllObjects);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFBagTypeID, void, (NSMutableSet *)hc, removeAllObjects);
     __CFGenericValidateType(hc, __kCFBagTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
diff --git a/CFBag.h b/CFBag.h
index 1ee36638338aa009aa01c5cbcb61c70213b79895..a6e60d517860f0caf97f2a60eebd79da88b79b01 100644 (file)
--- a/CFBag.h
+++ b/CFBag.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFBag.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBAG__)
@@ -30,6 +30,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef const void *   (*CFBagRetainCallBack)(CFAllocatorRef allocator, const void *value);
@@ -108,6 +109,7 @@ CF_EXPORT
 void CFBagRemoveAllValues(CFMutableBagRef theBag);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFBAG__ */
 
index 089aef35d04409eed5f2aa00103f682ef59e996a..2ed181dd0355d044367c61e765558c2b16cec8ec 100644 (file)
--- a/CFBase.c
+++ b/CFBase.c
  */
 
 /*     CFBase.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
 #include <CoreFoundation/CFBase.h>
 #include "CFInternal.h"
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    #include <pthread.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#include <pthread.h>
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    #include <malloc/malloc.h>
-    extern size_t malloc_good_size(size_t size);
-    #include <mach/mach.h>
-    #include <dlfcn.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#include <malloc/malloc.h>
+#include <mach/mach.h>
+#include <dlfcn.h>
 #endif
 #include <stdlib.h>
 #include <string.h>
 
 // -------- -------- -------- -------- -------- -------- -------- --------
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-// CFAllocator structure must match struct _malloc_zone_t!
-// The first two reserved fields in struct _malloc_zone_t are for us with CFRuntimeBase
-#endif
-
-
 struct __CFAllocator {
     CFRuntimeBase _base;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    // CFAllocator structure must match struct _malloc_zone_t!
+    // The first two reserved fields in struct _malloc_zone_t are for us with CFRuntimeBase
     size_t     (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
     void       *(*malloc)(struct _malloc_zone_t *zone, size_t size);
     void       *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
@@ -119,7 +114,7 @@ CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction
     return retval;
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
 __private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
 
@@ -256,9 +251,8 @@ static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
     malloc_zone_free(info, ptr);
 }
 
-#endif
+#else
 
-#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
     return malloc(size);
 }
@@ -298,7 +292,7 @@ static void __CFAllocatorCPPFree(void *ptr, void *info)
 
 static struct __CFAllocator __kCFAllocatorMalloc = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -327,7 +321,7 @@ static struct __CFAllocator __kCFAllocatorMalloc = {
 
 static struct __CFAllocator __kCFAllocatorMallocZone = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -349,7 +343,7 @@ static struct __CFAllocator __kCFAllocatorMallocZone = {
 
 static struct __CFAllocator __kCFAllocatorSystemDefault = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __CFAllocatorCustomSize,
     __CFAllocatorCustomMalloc,
     __CFAllocatorCustomCalloc,
@@ -371,7 +365,7 @@ static struct __CFAllocator __kCFAllocatorSystemDefault = {
 
 static struct __CFAllocator __kCFAllocatorNull = {
     INIT_CFRUNTIME_BASE(),
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __CFAllocatorNullSize,
     __CFAllocatorNullMalloc,
     __CFAllocatorNullCalloc,
@@ -457,7 +451,7 @@ __private_extern__ void __CFAllocatorInitialize(void) {
 
     _CFRuntimeSetInstanceTypeID(&__kCFAllocatorSystemDefault, __kCFAllocatorTypeID);
     __kCFAllocatorSystemDefault._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     __kCFAllocatorSystemDefault._context.info = (kCFUseCollectableAllocator ? objc_collectableZone() : malloc_default_zone());
 #endif
     __kCFAllocatorSystemDefault._allocator = kCFAllocatorSystemDefault;
@@ -466,8 +460,8 @@ __private_extern__ void __CFAllocatorInitialize(void) {
     __kCFAllocatorMalloc._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
     __kCFAllocatorMalloc._allocator = kCFAllocatorSystemDefault;
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-       _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
     __kCFAllocatorMallocZone._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
     __kCFAllocatorMallocZone._allocator = kCFAllocatorSystemDefault;
     __kCFAllocatorMallocZone._context.info = malloc_default_zone();
@@ -497,7 +491,7 @@ void CFAllocatorSetDefault(CFAllocatorRef allocator) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {      // malloc_zone_t *
        return;         // require allocator to this function to be an allocator
     }
@@ -517,7 +511,7 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     CFAllocatorRetainCallBack retainFunc;
     CFAllocatorAllocateCallBack allocateFunc;
     void *retainedInfo;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator && kCFAllocatorUseContext != allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {       // malloc_zone_t *
        return NULL;    // require allocator to this function to be an allocator
     }
@@ -558,7 +552,7 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC
     memory->_base._cfinfo[CF_INFO_BITS] = 0;
     _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
     memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     memory->size = __CFAllocatorCustomSize;
     memory->malloc = __CFAllocatorCustomMalloc;
     memory->calloc = __CFAllocatorCustomCalloc;
@@ -613,7 +607,7 @@ void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags
        allocator = __CFGetDefaultAllocator();
     }
 
-#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -621,7 +615,7 @@ void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     if (0 == size) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_zone_malloc((malloc_zone_t *)allocator, size);
     }
@@ -653,7 +647,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
         allocator = __CFGetDefaultAllocator();
     }
 
-#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -661,7 +655,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     if (NULL == ptr && 0 < newsize) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {        // malloc_zone_t *
            return malloc_zone_malloc((malloc_zone_t *)allocator, newsize);
        }
@@ -674,7 +668,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
        return newptr;
     }
     if (NULL != ptr && 0 == newsize) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {        // malloc_zone_t *
 #if defined(DEBUG)
            size_t size = malloc_size(ptr);
@@ -691,7 +685,7 @@ void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize
        return NULL;
     }
     if (NULL == ptr && 0 == newsize) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_zone_realloc((malloc_zone_t *)allocator, ptr, newsize);
     }
@@ -716,14 +710,14 @@ void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
         allocator = __CFGetDefaultAllocator();
     }
 
-#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #else
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
 #if defined(DEBUG)
        size_t size = malloc_size(ptr);
@@ -751,14 +745,14 @@ CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex siz
         allocator = __CFGetDefaultAllocator();
     }
 
-#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
 #else
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return malloc_good_size(size);
     }
@@ -781,7 +775,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
         allocator = __CFGetDefaultAllocator();
     }
 
-#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI)
     if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
        __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
     }
@@ -789,7 +783,7 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
     __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
 #endif
     CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) {   // malloc_zone_t *
        return;
     }
@@ -803,15 +797,6 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context
     context->reallocate = __CFAllocatorGetReallocateFunction(&allocator->_context);
     context->deallocate = __CFAllocatorGetDeallocateFunction(&allocator->_context);
     context->preferredSize = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
-#if SUPPORT_CFM
-    context->retain = (void *)((uintptr_t)context->retain & ~0x3);
-    context->release = (void *)((uintptr_t)context->release & ~0x3);
-    context->copyDescription = (void *)((uintptr_t)context->copyDescription & ~0x3);
-    context->allocate = (void *)((uintptr_t)context->allocate & ~0x3);
-    context->reallocate = (void *)((uintptr_t)context->reallocate & ~0x3);
-    context->deallocate = (void *)((uintptr_t)context->deallocate & ~0x3);
-    context->preferredSize = (void *)((uintptr_t)context->preferredSize & ~0x3);
-#endif
 }
 
 __private_extern__ void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
@@ -901,71 +886,9 @@ CFTypeID CFNullGetTypeID(void) {
 void CFCollection_non_gc_storage_error(void) { }
 
 
-#if !SUPPORT_CFM
-void _CFRuntimeSetCFMPresent(void *addr) {
-}
-#endif
-
-#if SUPPORT_CFM
-
-static int hasCFM = 0;
-
 void _CFRuntimeSetCFMPresent(void *addr) {
-    hasCFM = 1;
 }
 
-/* See comments below */
-__private_extern__ void __CF_FAULT_CALLBACK(void **ptr) {
-    uintptr_t p = (uintptr_t)*ptr;
-    if ((0 == p) || (p & 0x1)) return;
-    if (0 == hasCFM || (0x90000000 <= p && p < 0xA0000000)) {
-       *ptr = (void *)(p | 0x1);
-    } else {
-       uintptr_t known = ~0;
-           Dl_info info;
-           known = dladdr((void *)p, &info);
-       *ptr = (void *)(p | (known ? 0x1 : 0x3));
-    }
-}
-
-/*
-Jump to callback function.  r2 is not saved and restored
-in the jump-to-CFM case, since we assume that dyld code
-never uses that register and that CF is dyld.
-
-There are three states for (ptr & 0x3):
-       0b00:   check not yet done (or not going to be done, and is a dyld func ptr)
-       0b01:   check done, dyld function pointer
-       0b11:   check done, CFM tvector pointer
-(but a NULL callback just stays NULL)
-
-There may be up to 5 word-sized arguments. Floating point
-arguments can be done, but count as two word arguments.
-Return value can be integral or real.
-*/
-
-/* Keep this assembly at the bottom of the source file! */
-
-__asm__ (
-".text\n"
-"        .align 2\n"
-".private_extern ___CF_INVOKE_CALLBACK\n"
-"___CF_INVOKE_CALLBACK:\n"
-       "rlwinm r12,r3,0,0,29\n"
-       "andi. r0,r3,0x2\n"
-       "or r3,r4,r4\n"
-       "or r4,r5,r5\n"
-       "or r5,r6,r6\n"
-       "or r6,r7,r7\n"
-       "or r7,r8,r8\n"
-       "beq- Lcall\n"
-       "lwz r2,0x4(r12)\n"
-       "lwz r12,0x0(r12)\n"
-"Lcall:  mtspr ctr,r12\n"
-       "bctr\n");
-
-#endif
-
 
 // void __HALT(void);
 
index f0f4ccdf129c9fff9b7ccb1de56f20d2032f349a..e2d7aca7d80c1b379b2128d1096b8206d6a00593 100644 (file)
--- a/CFBase.h
+++ b/CFBase.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFBase.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBASE__)
 #define __WIN32__ 1
 #endif
 
+#if defined(_WIN64) && !defined(__WIN64__)
+#define __WIN64__ 1
+#endif
+
+#if defined(__WIN64__) && !defined(__LLP64__)
+#define __LLP64__ 1
+#endif
+
 #if defined(_MSC_VER) && defined(_M_IX86)
 #define __i386__ 1
 #endif
 #define __has_feature(x) 0
 #endif
 
+// Some compilers provide the capability to test if certain attributes are available. This macro provides a compatibility path for other compilers.
+#ifndef __has_attribute
+#define __has_attribute(x) 0
+#endif
+
+#ifndef __has_extension
+#define __has_extension(x) 0
+#endif
+
 #if defined(__GNUC__) || TARGET_OS_WIN32
 #include <stdint.h>
 #include <stdbool.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)
+#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) AVAILABLE_MAC_OS_X_VERSION_##_mac##_AND_LATER
+#define CF_AVAILABLE(_mac, _ios) __OSX_AVAILABLE_STARTING(__MAC_##_mac, __IPHONE_##_ios)
 
 // Available on MacOS only
-#define CF_AVAILABLE_MAC(_mac) AVAILABLE_MAC_OS_X_VERSION_##_mac##_AND_LATER
+#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) AVAILABLE_MAC_OS_X_VERSION_##_macIntro##_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_##_macDep
+#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) AVAILABLE_MAC_OS_X_VERSION_##_macIntro##_AND_LATER_BUT_DEPRECATED_IN_MAC_OS_X_VERSION_##_macDep
+#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)
 
-#elif (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
-#include <AvailabilityMacros.h>
-#include <Availability.h>
-
-#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)
-
 #else
 
 #if TARGET_OS_WIN32
 
 #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)
@@ -216,7 +257,7 @@ CF_EXTERN_C_BEGIN
         #define CF_INLINE static __inline__ __attribute__((always_inline))
     #elif defined(__GNUC__)
         #define CF_INLINE static __inline__
-    #elif defined(__MWERKS__) || defined(__cplusplus)
+    #elif defined(__cplusplus)
        #define CF_INLINE static inline
     #elif defined(_MSC_VER)
         #define CF_INLINE static __inline
@@ -227,19 +268,41 @@ CF_EXTERN_C_BEGIN
 
 // Marks functions which return a CF type that needs to be released by the caller but whose names are not consistent with CoreFoundation naming rules. The recommended fix to this is to rename the functions, but this macro can be used to let the clang static analyzer know of any exceptions that cannot be fixed.
 // This macro is ONLY to be used in exceptional circumstances, not to annotate functions which conform to the CoreFoundation naming rules.
+#ifndef CF_RETURNS_RETAINED
 #if __has_feature(attribute_cf_returns_retained)
 #define CF_RETURNS_RETAINED __attribute__((cf_returns_retained))
 #else
 #define CF_RETURNS_RETAINED
 #endif
+#endif
 
 // Marks functions which return a CF type that may need to be retained by the caller but whose names are not consistent with CoreFoundation naming rules. The recommended fix to this is to rename the functions, but this macro can be used to let the clang static analyzer know of any exceptions that cannot be fixed. 
 // This macro is ONLY to be used in exceptional circumstances, not to annotate functions which conform to the CoreFoundation naming rules.
+#ifndef CF_RETURNS_NOT_RETAINED
 #if __has_feature(attribute_cf_returns_not_retained)
 #define CF_RETURNS_NOT_RETAINED __attribute__((cf_returns_not_retained))
 #else
 #define CF_RETURNS_NOT_RETAINED
 #endif
+#endif
+
+// Marks function arguments which are released by the callee.
+#ifndef CF_RELEASES_ARGUMENT
+#if __has_feature(attribute_cf_consumed)
+#define CF_RELEASES_ARGUMENT __attribute__((cf_consumed))
+#else
+#define CF_RELEASES_ARGUMENT
+#endif
+#endif
+
+// Compatibility
+#ifndef CF_CONSUMED
+#if __has_feature(attribute_cf_consumed)
+#define CF_CONSUMED __attribute__((cf_consumed))
+#else
+#define CF_CONSUMED
+#endif
+#endif
 
 // Marks functions which cannot be used when compiling in automatic reference counting mode.
 #if __has_feature(objc_arc)
@@ -248,6 +311,23 @@ CF_EXTERN_C_BEGIN
 #define CF_AUTOMATED_REFCOUNT_UNAVAILABLE
 #endif
 
+#ifndef CF_IMPLICIT_BRIDGING_ENABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_ENABLED _Pragma("clang arc_cf_code_audited begin")
+#else
+#define CF_IMPLICIT_BRIDGING_ENABLED
+#endif
+#endif
+
+#ifndef CF_IMPLICIT_BRIDGING_DISABLED
+#if __has_feature(arc_cf_code_audited)
+#define CF_IMPLICIT_BRIDGING_DISABLED _Pragma("clang arc_cf_code_audited end")
+#else
+#define CF_IMPLICIT_BRIDGING_DISABLED
+#endif
+#endif
+
+
 CF_EXPORT double kCFCoreFoundationVersionNumber;
 
 #if TARGET_OS_MAC
@@ -308,6 +388,14 @@ CF_EXPORT double kCFCoreFoundationVersionNumber;
 #define kCFCoreFoundationVersionNumber10_6_3   550.19
 #define kCFCoreFoundationVersionNumber10_6_4   550.29
 #define kCFCoreFoundationVersionNumber10_6_5   550.42
+#define kCFCoreFoundationVersionNumber10_6_6   550.42
+#define kCFCoreFoundationVersionNumber10_6_7   550.42
+#define kCFCoreFoundationVersionNumber10_6_8   550.43
+#define kCFCoreFoundationVersionNumber10_7      635.00
+#define kCFCoreFoundationVersionNumber10_7_1    635.00
+#define kCFCoreFoundationVersionNumber10_7_2    635.15
+#define kCFCoreFoundationVersionNumber10_7_3    635.19
+#define kCFCoreFoundationVersionNumber10_7_4    635.21
 #endif
 
 #if TARGET_OS_IPHONE
@@ -320,12 +408,22 @@ CF_EXPORT double kCFCoreFoundationVersionNumber;
 #define kCFCoreFoundationVersionNumber_iOS_4_0 550.32
 #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
 #endif
 
+#if __LLP64__
+typedef unsigned long long CFTypeID;
+typedef unsigned long long CFOptionFlags;
+typedef unsigned long long CFHashCode;
+typedef signed long long CFIndex;
+#else
 typedef unsigned long CFTypeID;
 typedef unsigned long CFOptionFlags;
 typedef unsigned long CFHashCode;
 typedef signed long CFIndex;
+#endif
 
 /* Base "type" of all "CF objects", and polymorphic functions on them */
 typedef const void * CFTypeRef;
@@ -341,12 +439,11 @@ typedef struct __CFString * CFMutableStringRef;
 typedef CFTypeRef CFPropertyListRef;
 
 /* Values returned from comparison functions */
-enum {
-    kCFCompareLessThan = -1,
+typedef CF_ENUM(CFIndex, CFComparisonResult) {
+    kCFCompareLessThan = -1L,
     kCFCompareEqualTo = 0,
     kCFCompareGreaterThan = 1
 };
-typedef CFIndex CFComparisonResult;
 
 /* A standard comparison function */
 typedef CFComparisonResult (*CFComparatorFunction)(const void *val1, const void *val2, void *context);
diff --git a/CFBasicHash.c b/CFBasicHash.c
new file mode 100644 (file)
index 0000000..6e94e1a
--- /dev/null
@@ -0,0 +1,1752 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*     CFBasicHash.m
+       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+       Responsibility: Christopher Kane
+*/
+
+#import "CFBasicHash.h"
+#import <CoreFoundation/CFRuntime.h>
+#import <CoreFoundation/CFSet.h>
+#import <Block.h>
+#import <math.h>
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#define __SetLastAllocationEventName(A, B) do { if (__CFOASafe && (A)) __CFSetLastAllocationEventName(A, B); } while (0)
+#else
+#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
+#define ENABLE_MEMORY_COUNTERS 0
+
+#if defined(DTRACE_PROBES_DISABLED) && DTRACE_PROBES_DISABLED
+#undef ENABLE_DTRACE_PROBES
+#define ENABLE_DTRACE_PROBES 0
+#endif
+
+/*
+// dtrace -h -s foo.d
+// Note: output then changed by casts of the arguments
+// dtrace macros last generated 2010-09-08 on 10.7 prerelease (11A259)
+
+provider Cocoa_HashTable {
+        probe hash_key(unsigned long table, unsigned long key, unsigned long hash);
+        probe test_equal(unsigned long table, unsigned long key1, unsigned long key2);
+        probe probing_start(unsigned long table, unsigned long num_buckets);
+        probe probe_empty(unsigned long table, unsigned long idx);
+        probe probe_deleted(unsigned long table, unsigned long idx);
+        probe probe_valid(unsigned long table, unsigned long idx);
+        probe probing_end(unsigned long table, unsigned long num_probes);
+        probe rehash_start(unsigned long table, unsigned long num_buckets, unsigned long total_size);
+        probe rehash_end(unsigned long table, unsigned long num_buckets, unsigned long total_size);
+};
+
+#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable provider
+#pragma D attributes Private/Private/Unknown provider Cocoa_HashTable module
+#pragma D attributes Private/Private/Unknown provider Cocoa_HashTable function
+#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable name
+#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable args
+*/
+
+#if ENABLE_DTRACE_PROBES
+
+#define COCOA_HASHTABLE_STABILITY "___dtrace_stability$Cocoa_HashTable$v1$4_4_5_1_1_0_1_1_0_4_4_5_4_4_5"
+
+#define COCOA_HASHTABLE_TYPEDEFS "___dtrace_typedefs$Cocoa_HashTable$v2"
+
+#define COCOA_HASHTABLE_REHASH_END(arg0, arg1, arg2) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$rehash_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_REHASH_END_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$rehash_end$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_REHASH_START(arg0, arg1, arg2) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$rehash_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_REHASH_START_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$rehash_start$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_HASH_KEY(arg0, arg1, arg2) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$hash_key$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_HASH_KEY_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$hash_key$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_PROBE_DELETED(arg0, arg1) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$probe_deleted$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_PROBE_DELETED_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_deleted$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_PROBE_EMPTY(arg0, arg1) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$probe_empty$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_PROBE_EMPTY_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_empty$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_PROBE_VALID(arg0, arg1) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$probe_valid$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_PROBE_VALID_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_valid$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_PROBING_END(arg0, arg1) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$probing_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_PROBING_END_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probing_end$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_PROBING_START(arg0, arg1) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$probing_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_PROBING_START_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probing_start$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+#define COCOA_HASHTABLE_TEST_EQUAL(arg0, arg1, arg2) \
+do { \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
+        __dtrace_probe$Cocoa_HashTable$test_equal$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
+        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
+} while (0)
+#define        COCOA_HASHTABLE_TEST_EQUAL_ENABLED() \
+       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$test_equal$v1(); \
+               __asm__ volatile(""); \
+               _r; })
+
+extern void __dtrace_probe$Cocoa_HashTable$hash_key$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$hash_key$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$probe_deleted$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$probe_deleted$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$probe_empty$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$probe_empty$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$probe_valid$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$probe_valid$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$probing_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$probing_end$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$probing_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$probing_start$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$rehash_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$rehash_end$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$rehash_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$rehash_start$v1(void);
+extern void __dtrace_probe$Cocoa_HashTable$test_equal$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
+extern int __dtrace_isenabled$Cocoa_HashTable$test_equal$v1(void);
+
+#else
+
+#define COCOA_HASHTABLE_REHASH_END(arg0, arg1, arg2) do {} while (0)
+#define COCOA_HASHTABLE_REHASH_END_ENABLED() 0
+#define COCOA_HASHTABLE_REHASH_START(arg0, arg1, arg2) do {} while (0)
+#define COCOA_HASHTABLE_REHASH_START_ENABLED() 0
+#define COCOA_HASHTABLE_HASH_KEY(arg0, arg1, arg2) do {} while (0)
+#define COCOA_HASHTABLE_HASH_KEY_ENABLED() 0
+#define COCOA_HASHTABLE_PROBE_DELETED(arg0, arg1) do {} while (0)
+#define COCOA_HASHTABLE_PROBE_DELETED_ENABLED() 0
+#define COCOA_HASHTABLE_PROBE_EMPTY(arg0, arg1) do {} while (0)
+#define COCOA_HASHTABLE_PROBE_EMPTY_ENABLED() 0
+#define COCOA_HASHTABLE_PROBE_VALID(arg0, arg1) do {} while (0)
+#define COCOA_HASHTABLE_PROBE_VALID_ENABLED() 0
+#define COCOA_HASHTABLE_PROBING_END(arg0, arg1) do {} while (0)
+#define COCOA_HASHTABLE_PROBING_END_ENABLED() 0
+#define COCOA_HASHTABLE_PROBING_START(arg0, arg1) do {} while (0)
+#define COCOA_HASHTABLE_PROBING_START_ENABLED() 0
+#define COCOA_HASHTABLE_TEST_EQUAL(arg0, arg1, arg2) do {} while (0)
+#define COCOA_HASHTABLE_TEST_EQUAL_ENABLED() 0
+
+#endif
+
+
+#if !defined(__LP64__)
+#define __LP64__ 0
+#endif
+
+// Prime numbers. Values above 100 have been adjusted up so that the
+// malloced block size will be just below a multiple of 512; values
+// above 1200 have been adjusted up to just below a multiple of 4096.
+static const uintptr_t __CFBasicHashTableSizes[64] = {
+    0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
+    2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
+    214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
+    6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
+    111638519, 180634607, 292272623, 472907251,
+#if __LP64__
+    765180413UL, 1238087663UL, 2003267557UL, 3241355263UL, 5244622819UL,
+#if 0
+    8485977589UL, 13730600407UL, 22216578047UL, 35947178479UL,
+    58163756537UL, 94110934997UL, 152274691561UL, 246385626107UL,
+    398660317687UL, 645045943807UL, 1043706260983UL, 1688752204787UL,
+    2732458465769UL, 4421210670577UL, 7153669136377UL,
+    11574879807461UL, 18728548943849UL, 30303428750843UL
+#endif
+#endif
+};
+
+static const uintptr_t __CFBasicHashTableCapacities[64] = {
+    0, 3, 6, 11, 19, 32, 52, 85, 118, 155, 237, 390, 672, 1065,
+    1732, 2795, 4543, 7391, 12019, 19302, 31324, 50629, 81956,
+    132580, 214215, 346784, 561026, 907847, 1468567, 2376414,
+    3844982, 6221390, 10066379, 16287773, 26354132, 42641916,
+    68996399, 111638327, 180634415, 292272755,
+#if __LP64__
+    472907503UL, 765180257UL, 1238087439UL, 2003267722UL, 3241355160UL,
+#if 0
+    5244622578UL, 8485977737UL, 13730600347UL, 22216578100UL,
+    35947178453UL, 58163756541UL, 94110935011UL, 152274691274UL,
+    246385626296UL, 398660317578UL, 645045943559UL, 1043706261135UL,
+    1688752204693UL, 2732458465840UL, 4421210670552UL,
+    7153669136706UL, 11574879807265UL, 18728548943682UL
+#endif
+#endif
+};
+
+// Primitive roots for the primes above
+static const uintptr_t __CFBasicHashPrimitiveRoots[64] = {
+    0, 2, 3, 2, 5, 6, 7, 3, 19, 6, 5, 3, 3, 3,
+    2, 5, 6, 3, 3, 6, 2, 3, 3,
+    3, 5, 10, 3, 3, 22, 3,
+    3, 3, 5, 2, 22, 2,
+    11, 5, 5, 2,
+#if __LP64__
+    3, 10, 2, 3, 10,
+    2, 3, 5, 3,
+    3, 2, 7, 2,
+    3, 3, 3, 2,
+    3, 5, 5,
+    2, 3, 2
+#endif
+};
+
+CF_INLINE void *__CFBasicHashAllocateMemory(CFConstBasicHashRef ht, CFIndex count, CFIndex elem_size, Boolean strong, Boolean compactable) {
+    CFAllocatorRef allocator = CFGetAllocator(ht);
+    void *new_mem = NULL;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        new_mem = auto_zone_allocate_object(objc_collectableZone(), count * elem_size, strong ? (compactable ? AUTO_POINTERS_ONLY : AUTO_MEMORY_SCANNED) : AUTO_UNSCANNED, false, false);
+    } else {
+        new_mem = CFAllocatorAllocate(allocator, count * elem_size, 0);
+    }
+    return new_mem;
+}
+
+CF_INLINE void *__CFBasicHashAllocateMemory2(CFAllocatorRef allocator, CFIndex count, CFIndex elem_size, Boolean strong, Boolean compactable) {
+    void *new_mem = NULL;
+    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        new_mem = auto_zone_allocate_object(objc_collectableZone(), count * elem_size, strong ? (compactable ? AUTO_POINTERS_ONLY : AUTO_MEMORY_SCANNED) : AUTO_UNSCANNED, false, false);
+    } else {
+        new_mem = CFAllocatorAllocate(allocator, count * elem_size, 0);
+    }
+    return new_mem;
+}
+
+#define __CFBasicHashSubABZero 0xa7baadb1
+#define __CFBasicHashSubABOne 0xa5baadb9
+
+typedef union {
+    uintptr_t neutral;
+    id strong;
+    id weak;
+} CFBasicHashValue;
+
+struct __CFBasicHash {
+    CFRuntimeBase base;
+    struct { // 128 bits
+        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;
+        uint8_t hashes_offset:2;
+        uint8_t strong_values:1;
+        uint8_t strong_keys:1;
+        uint8_t weak_values:1;
+        uint8_t weak_keys:1;
+        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;
+    } 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
+}
+
+__private_extern__ Boolean CFBasicHashHasStrongKeys(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.strong_keys ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE Boolean __CFBasicHashHasCompactableKeys(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.compactable_keys ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE Boolean __CFBasicHashHasCompactableValues(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.compactable_values ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE Boolean __CFBasicHashHasWeakValues(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.weak_values ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE Boolean __CFBasicHashHasWeakKeys(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.weak_keys ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE Boolean __CFBasicHashHasHashCache(CFConstBasicHashRef ht) {
+#if DEPLOYMENT_TARGET_MACOSX
+    return ht->bits.hashes_offset ? true : false;
+#else
+    return false;
+#endif
+}
+
+CF_INLINE uintptr_t __CFBasicHashImportValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+    return ht->callbacks->retainValue(ht, stack_value);
+}
+
+CF_INLINE uintptr_t __CFBasicHashImportKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    return ht->callbacks->retainKey(ht, stack_key);
+}
+
+CF_INLINE void __CFBasicHashEjectValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+    ht->callbacks->releaseValue(ht, stack_value);
+}
+
+CF_INLINE void __CFBasicHashEjectKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    ht->callbacks->releaseKey(ht, 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);
+}
+
+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);
+}
+
+CF_INLINE CFHashCode __CFBasicHashHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    CFHashCode hash_code = (CFHashCode)ht->callbacks->hashKey(ht, stack_key);
+    COCOA_HASHTABLE_HASH_KEY(ht, stack_key, hash_code);
+    return hash_code;
+}
+
+CF_INLINE CFBasicHashValue *__CFBasicHashGetValues(CFConstBasicHashRef ht) {
+    return (CFBasicHashValue *)ht->pointers[0];
+}
+
+CF_INLINE void __CFBasicHashSetValues(CFBasicHashRef ht, CFBasicHashValue *ptr) {
+    __AssignWithWriteBarrier(&ht->pointers[0], ptr);
+}
+
+CF_INLINE CFBasicHashValue *__CFBasicHashGetKeys(CFConstBasicHashRef ht) {
+    return (CFBasicHashValue *)ht->pointers[ht->bits.keys_offset];
+}
+
+CF_INLINE void __CFBasicHashSetKeys(CFBasicHashRef ht, CFBasicHashValue *ptr) {
+    __AssignWithWriteBarrier(&ht->pointers[ht->bits.keys_offset], ptr);
+}
+
+CF_INLINE void *__CFBasicHashGetCounts(CFConstBasicHashRef ht) {
+    return (void *)ht->pointers[ht->bits.counts_offset];
+}
+
+CF_INLINE void __CFBasicHashSetCounts(CFBasicHashRef ht, void *ptr) {
+    __AssignWithWriteBarrier(&ht->pointers[ht->bits.counts_offset], ptr);
+}
+
+CF_INLINE uintptr_t __CFBasicHashGetValue(CFConstBasicHashRef ht, CFIndex idx) {
+    uintptr_t val = __CFBasicHashGetValues(ht)[idx].neutral;
+    if (__CFBasicHashSubABZero == val) return 0UL;
+    if (__CFBasicHashSubABOne == val) return ~0UL;
+    return val;
+}
+
+CF_INLINE void __CFBasicHashSetValue(CFBasicHashRef ht, CFIndex idx, uintptr_t stack_value, Boolean ignoreOld, Boolean literal) {
+    CFBasicHashValue *valuep = &(__CFBasicHashGetValues(ht)[idx]);
+    uintptr_t old_value = ignoreOld ? 0 : valuep->neutral;
+    if (!literal) {
+        if (0UL == stack_value) stack_value = __CFBasicHashSubABZero;
+        if (~0UL == stack_value) stack_value = __CFBasicHashSubABOne;
+    }
+    if (CFBasicHashHasStrongValues(ht)) valuep->strong = (id)stack_value; else valuep->neutral = stack_value;
+    if (!ignoreOld) {
+        if (!(old_value == 0UL || old_value == ~0UL)) {
+            if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
+            if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
+            __CFBasicHashEjectValue(ht, old_value);
+        }
+    }
+}
+
+CF_INLINE uintptr_t __CFBasicHashGetKey(CFConstBasicHashRef ht, CFIndex idx) {
+    if (ht->bits.keys_offset) {
+        uintptr_t key = __CFBasicHashGetKeys(ht)[idx].neutral;
+        if (__CFBasicHashSubABZero == key) return 0UL;
+        if (__CFBasicHashSubABOne == key) return ~0UL;
+        return key;
+    }
+    if (ht->bits.indirect_keys) {
+        uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
+        return ht->callbacks->getIndirectKey(ht, stack_value);
+    }
+    return __CFBasicHashGetValue(ht, idx);
+}
+
+CF_INLINE void __CFBasicHashSetKey(CFBasicHashRef ht, CFIndex idx, uintptr_t stack_key, Boolean ignoreOld, Boolean literal) {
+    if (0 == ht->bits.keys_offset) HALT;
+    CFBasicHashValue *keyp = &(__CFBasicHashGetKeys(ht)[idx]);
+    uintptr_t old_key = ignoreOld ? 0 : keyp->neutral;
+    if (!literal) {
+        if (0UL == stack_key) stack_key = __CFBasicHashSubABZero;
+        if (~0UL == stack_key) stack_key = __CFBasicHashSubABOne;
+    }
+    if (CFBasicHashHasStrongKeys(ht)) keyp->strong = (id)stack_key; else keyp->neutral = stack_key;
+    if (!ignoreOld) {
+        if (!(old_key == 0UL || old_key == ~0UL)) {
+            if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
+            if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
+            __CFBasicHashEjectKey(ht, old_key);
+        }
+    }
+}
+
+CF_INLINE uintptr_t __CFBasicHashIsEmptyOrDeleted(CFConstBasicHashRef ht, CFIndex idx) {
+    uintptr_t stack_value = __CFBasicHashGetValues(ht)[idx].neutral;
+    return (0UL == stack_value || ~0UL == stack_value);
+}
+
+CF_INLINE uintptr_t __CFBasicHashIsDeleted(CFConstBasicHashRef ht, CFIndex idx) {
+    uintptr_t stack_value = __CFBasicHashGetValues(ht)[idx].neutral;
+    return (~0UL == stack_value);
+}
+
+CF_INLINE uintptr_t __CFBasicHashGetSlotCount(CFConstBasicHashRef ht, CFIndex idx) {
+    void *counts = __CFBasicHashGetCounts(ht);
+    switch (ht->bits.counts_width) {
+    case 0: return ((uint8_t *)counts)[idx];
+    case 1: return ((uint16_t *)counts)[idx];
+    case 2: return ((uint32_t *)counts)[idx];
+    case 3: return ((uint64_t *)counts)[idx];
+    }
+    return 0;
+}
+
+CF_INLINE void __CFBasicHashBumpCounts(CFBasicHashRef ht) {
+    void *counts = __CFBasicHashGetCounts(ht);
+    CFAllocatorRef allocator = CFGetAllocator(ht);
+    switch (ht->bits.counts_width) {
+    case 0: {
+        uint8_t *counts08 = (uint8_t *)counts;
+        ht->bits.counts_width = 1;
+        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        uint16_t *counts16 = (uint16_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 2, false, false);
+        if (!counts16) HALT;
+        __SetLastAllocationEventName(counts16, "CFBasicHash (count-store)");
+        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
+            counts16[idx2] = counts08[idx2];
+        }
+        __CFBasicHashSetCounts(ht, counts16);
+        if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+            CFAllocatorDeallocate(allocator, counts08);
+        }
+        break;
+    }
+    case 1: {
+        uint16_t *counts16 = (uint16_t *)counts;
+        ht->bits.counts_width = 2;
+        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        uint32_t *counts32 = (uint32_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 4, false, false);
+        if (!counts32) HALT;
+        __SetLastAllocationEventName(counts32, "CFBasicHash (count-store)");
+        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
+            counts32[idx2] = counts16[idx2];
+        }
+        __CFBasicHashSetCounts(ht, counts32);
+         if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+            CFAllocatorDeallocate(allocator, counts16);
+        }
+        break;
+    }
+    case 2: {
+        uint32_t *counts32 = (uint32_t *)counts;
+        ht->bits.counts_width = 3;
+        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        uint64_t *counts64 = (uint64_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 8, false, false);
+        if (!counts64) HALT;
+        __SetLastAllocationEventName(counts64, "CFBasicHash (count-store)");
+        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
+            counts64[idx2] = counts32[idx2];
+        }
+        __CFBasicHashSetCounts(ht, counts64);
+         if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+            CFAllocatorDeallocate(allocator, counts32);
+        }
+        break;
+    }
+    case 3: {
+        HALT;
+        break;
+    }
+    }
+}
+
+static void __CFBasicHashIncSlotCount(CFBasicHashRef ht, CFIndex idx) {
+    void *counts = __CFBasicHashGetCounts(ht);
+    switch (ht->bits.counts_width) {
+    case 0: {
+        uint8_t *counts08 = (uint8_t *)counts;
+        uint8_t val = counts08[idx];
+        if (val < INT8_MAX) {
+            counts08[idx] = val + 1;
+            return;
+        }
+        __CFBasicHashBumpCounts(ht);
+        __CFBasicHashIncSlotCount(ht, idx);
+        break;
+    }
+    case 1: {
+        uint16_t *counts16 = (uint16_t *)counts;
+        uint16_t val = counts16[idx];
+        if (val < INT16_MAX) {
+            counts16[idx] = val + 1;
+            return;
+        }
+        __CFBasicHashBumpCounts(ht);
+        __CFBasicHashIncSlotCount(ht, idx);
+        break;
+    }
+    case 2: {
+        uint32_t *counts32 = (uint32_t *)counts;
+        uint32_t val = counts32[idx];
+        if (val < INT32_MAX) {
+            counts32[idx] = val + 1;
+            return;
+        }
+        __CFBasicHashBumpCounts(ht);
+        __CFBasicHashIncSlotCount(ht, idx);
+        break;
+    }
+    case 3: {
+        uint64_t *counts64 = (uint64_t *)counts;
+        uint64_t val = counts64[idx];
+        if (val < INT64_MAX) {
+            counts64[idx] = val + 1;
+            return;
+        }
+        __CFBasicHashBumpCounts(ht);
+        __CFBasicHashIncSlotCount(ht, idx);
+        break;
+    }
+    }
+}
+
+CF_INLINE void __CFBasicHashDecSlotCount(CFBasicHashRef ht, CFIndex idx) {
+    void *counts = __CFBasicHashGetCounts(ht);
+    switch (ht->bits.counts_width) {
+    case 0: ((uint8_t  *)counts)[idx]--; return;
+    case 1: ((uint16_t *)counts)[idx]--; return;
+    case 2: ((uint32_t *)counts)[idx]--; return;
+    case 3: ((uint64_t *)counts)[idx]--; return;
+    }
+}
+
+CF_INLINE uintptr_t *__CFBasicHashGetHashes(CFConstBasicHashRef ht) {
+    return (uintptr_t *)ht->pointers[ht->bits.hashes_offset];
+}
+
+CF_INLINE void __CFBasicHashSetHashes(CFBasicHashRef ht, uintptr_t *ptr) {
+    __AssignWithWriteBarrier(&ht->pointers[ht->bits.hashes_offset], ptr);
+}
+
+
+// to expose the load factor, expose this function to customization
+CF_INLINE CFIndex __CFBasicHashGetCapacityForNumBuckets(CFConstBasicHashRef ht, CFIndex num_buckets_idx) {
+    return __CFBasicHashTableCapacities[num_buckets_idx];
+}
+
+CF_INLINE CFIndex __CFBasicHashGetNumBucketsIndexForCapacity(CFConstBasicHashRef ht, CFIndex capacity) {
+    for (CFIndex idx = 0; idx < 64; idx++) {
+        if (capacity <= __CFBasicHashGetCapacityForNumBuckets(ht, idx)) return idx;
+    }
+    HALT;
+    return 0;
+}
+
+__private_extern__ CFIndex CFBasicHashGetNumBuckets(CFConstBasicHashRef ht) {
+    return __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+}
+
+__private_extern__ CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht) {
+    return __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx);
+}
+
+// In returned struct, .count is zero if the bucket is empty or deleted,
+// and the .weak_key field indicates which. .idx is either the index of
+// 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) {
+    CFBasicHashBucket result;
+    result.idx = idx;
+    if (__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
+        result.count = 0;
+        result.weak_value = 0;
+        result.weak_key = 0;
+    } else {
+        result.count = (ht->bits.counts_offset) ? __CFBasicHashGetSlotCount(ht, idx) : 1;
+        result.weak_value = __CFBasicHashGetValue(ht, idx);
+        result.weak_key = __CFBasicHashGetKey(ht, idx);
+    }
+    return result;
+}
+
+#if defined(__arm__)
+static uintptr_t __CFBasicHashFold(uintptr_t dividend, uint8_t idx) {
+    switch (idx) {
+    case 1: return dividend % 3;
+    case 2: return dividend % 7;
+    case 3: return dividend % 13;
+    case 4: return dividend % 23;
+    case 5: return dividend % 41;
+    case 6: return dividend % 71;
+    case 7: return dividend % 127;
+    case 8: return dividend % 191;
+    case 9: return dividend % 251;
+    case 10: return dividend % 383;
+    case 11: return dividend % 631;
+    case 12: return dividend % 1087;
+    case 13: return dividend % 1723;
+    case 14: return dividend % 2803;
+    case 15: return dividend % 4523;
+    case 16: return dividend % 7351;
+    case 17: return dividend % 11959;
+    case 18: return dividend % 19447;
+    case 19: return dividend % 31231;
+    case 20: return dividend % 50683;
+    case 21: return dividend % 81919;
+    case 22: return dividend % 132607;
+    case 23: return dividend % 214519;
+    case 24: return dividend % 346607;
+    case 25: return dividend % 561109;
+    case 26: return dividend % 907759;
+    case 27: return dividend % 1468927;
+    case 28: return dividend % 2376191;
+    case 29: return dividend % 3845119;
+    case 30: return dividend % 6221311;
+    case 31: return dividend % 10066421;
+    case 32: return dividend % 16287743;
+    case 33: return dividend % 26354171;
+    case 34: return dividend % 42641881;
+    case 35: return dividend % 68996069;
+    case 36: return dividend % 111638519;
+    case 37: return dividend % 180634607;
+    case 38: return dividend % 292272623;
+    case 39: return dividend % 472907251;
+    }
+    HALT;
+    return ~0;
+}
+#endif
+
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear
+#define FIND_BUCKET_HASH_STYLE         1
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_NoCollision
+#define FIND_BUCKET_HASH_STYLE         1
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_Indirect
+#define FIND_BUCKET_HASH_STYLE         1
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_Indirect_NoCollision
+#define FIND_BUCKET_HASH_STYLE         1
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double
+#define FIND_BUCKET_HASH_STYLE         2
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_NoCollision
+#define FIND_BUCKET_HASH_STYLE         2
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_Indirect
+#define FIND_BUCKET_HASH_STYLE         2
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_Indirect_NoCollision
+#define FIND_BUCKET_HASH_STYLE         2
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential
+#define FIND_BUCKET_HASH_STYLE         3
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_NoCollision
+#define FIND_BUCKET_HASH_STYLE         3
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   0
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_Indirect
+#define FIND_BUCKET_HASH_STYLE         3
+#define FIND_BUCKET_FOR_REHASH         0
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_Indirect_NoCollision
+#define FIND_BUCKET_HASH_STYLE         3
+#define FIND_BUCKET_FOR_REHASH         1
+#define FIND_BUCKET_FOR_INDIRECT_KEY   1
+#include "CFBasicHashFindBucket.m"
+
+
+CF_INLINE CFBasicHashBucket __CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    if (0 == ht->bits.num_buckets_idx) {
+        CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
+        return result;
+    }
+    if (ht->bits.indirect_keys) {
+        switch (ht->bits.hash_style) {
+        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_Indirect(ht, stack_key);
+        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_Indirect(ht, stack_key);
+        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_Indirect(ht, stack_key);
+        }
+    } else {
+        switch (ht->bits.hash_style) {
+        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear(ht, stack_key);
+        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double(ht, stack_key);
+        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential(ht, stack_key);
+        }
+    }
+    HALT;
+    CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
+    return result;
+}
+
+CF_INLINE CFIndex __CFBasicHashFindBucket_NoCollision(CFConstBasicHashRef ht, uintptr_t stack_key, uintptr_t key_hash) {
+    if (0 == ht->bits.num_buckets_idx) {
+        return kCFNotFound;
+    }
+    if (ht->bits.indirect_keys) {
+        switch (ht->bits.hash_style) {
+        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_Indirect_NoCollision(ht, stack_key, key_hash);
+        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_Indirect_NoCollision(ht, stack_key, key_hash);
+        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_Indirect_NoCollision(ht, stack_key, key_hash);
+        }
+    } else {
+        switch (ht->bits.hash_style) {
+        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_NoCollision(ht, stack_key, key_hash);
+        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_NoCollision(ht, stack_key, key_hash);
+        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_NoCollision(ht, stack_key, key_hash);
+        }
+    }
+    HALT;
+    return kCFNotFound;
+}
+
+__private_extern__ CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
+        CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
+        return result;
+    }
+    return __CFBasicHashFindBucket(ht, stack_key);
+}
+
+__private_extern__ uint16_t CFBasicHashGetSpecialBits(CFConstBasicHashRef ht) {
+    return ht->bits.special_bits;
+}
+
+__private_extern__ uint16_t CFBasicHashSetSpecialBits(CFBasicHashRef ht, uint16_t bits) {
+    uint16_t old =  ht->bits.special_bits;
+    ht->bits.special_bits = bits;
+    return old;
+}
+
+__private_extern__ 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;
+    if (__CFBasicHashHasHashCache(ht)) flags |= kCFBasicHashHasHashCache;
+    return flags;
+}
+
+__private_extern__ const CFBasicHashCallbacks *CFBasicHashGetCallbacks(CFConstBasicHashRef ht) {
+    return ht->callbacks;
+}
+
+__private_extern__ CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht) {
+    if (ht->bits.counts_offset) {
+        CFIndex total = 0L;
+        CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        for (CFIndex idx = 0; idx < cnt; idx++) {
+            total += __CFBasicHashGetSlotCount(ht, idx);
+        }
+        return total;
+    }
+    return (CFIndex)ht->bits.used_buckets;
+}
+
+__private_extern__ CFIndex CFBasicHashGetCountOfKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
+    if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
+        return 0L;
+    }
+    if (0L == ht->bits.used_buckets) {
+        return 0L;
+    }
+    return __CFBasicHashFindBucket(ht, stack_key).count;
+}
+
+__private_extern__ CFIndex CFBasicHashGetCountOfValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
+    if (__CFBasicHashSubABZero == stack_value) {
+        return 0L;
+    }
+    if (0L == ht->bits.used_buckets) {
+        return 0L;
+    }
+    if (!(ht->bits.keys_offset)) {
+        return __CFBasicHashFindBucket(ht, stack_value).count;
+    }
+    __block CFIndex total = 0L;
+    CFBasicHashApply(ht, ^(CFBasicHashBucket bkt) {
+            if ((stack_value == bkt.weak_value) || __CFBasicHashTestEqualValue(ht, bkt.weak_value, stack_value)) total += bkt.count;
+            return (Boolean)true;
+        });
+    return total;
+}
+
+__private_extern__ Boolean CFBasicHashesAreEqual(CFConstBasicHashRef ht1, CFConstBasicHashRef ht2) {
+    CFIndex cnt1 = CFBasicHashGetCount(ht1);
+    if (cnt1 != CFBasicHashGetCount(ht2)) return false;
+    if (0 == cnt1) return true;
+    __block Boolean equal = true;
+    CFBasicHashApply(ht1, ^(CFBasicHashBucket bkt1) {
+            CFBasicHashBucket bkt2 = __CFBasicHashFindBucket(ht2, bkt1.weak_key);
+            if (bkt1.count != bkt2.count) {
+                equal = false;
+                return (Boolean)false;
+            }
+            if ((ht1->bits.keys_offset) && (bkt1.weak_value != bkt2.weak_value) && !__CFBasicHashTestEqualValue(ht1, bkt1.weak_value, bkt2.weak_value)) {
+                equal = false;
+                return (Boolean)false;
+            }
+            return (Boolean)true;
+        });
+    return equal;
+}
+
+__private_extern__ 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);
+        if (0 < bkt.count) {
+            if (!block(bkt)) {
+                return;
+            }
+            used--;
+        }
+    }
+}
+
+__private_extern__ 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];
+    if (cnt < range.location + range.length) HALT;
+    for (CFIndex idx = 0; idx < range.length; idx++) {
+        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, range.location + idx);
+        if (0 < bkt.count) {
+            if (!block(bkt)) {
+                return;
+            }
+        }
+    }
+}
+
+__private_extern__ 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++) {
+        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
+        if (0 < bkt.count) {
+            used--;
+            for (CFIndex cnt = bkt.count; cnt-- && offset < bufferslen;) {
+                if (weak_values) { weak_values[offset] = bkt.weak_value; }
+                if (weak_keys) { weak_keys[offset] = bkt.weak_key; }
+                offset++;
+            }
+        }
+    }
+}
+
+__private_extern__ 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->itemsPtr = (unsigned long *)stackbuffer;
+    CFIndex cntx = 0;
+    CFIndex used = (CFIndex)ht->bits.used_buckets, cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+    for (CFIndex idx = (CFIndex)state->state; 0 < used && idx < cnt && cntx < (CFIndex)count; idx++) {
+        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
+        if (0 < bkt.count) {
+            state->itemsPtr[cntx++] = (unsigned long)bkt.weak_key;
+            used--;
+        }
+        state->state++;
+    }
+    return cntx;
+}
+
+#if ENABLE_MEMORY_COUNTERS
+static volatile int64_t __CFBasicHashTotalCount = 0ULL;
+static volatile int64_t __CFBasicHashTotalSize = 0ULL;
+static volatile int64_t __CFBasicHashPeakCount = 0ULL;
+static volatile int64_t __CFBasicHashPeakSize = 0ULL;
+static volatile int32_t __CFBasicHashSizes[64] = {0};
+#endif
+
+static void __CFBasicHashDrain(CFBasicHashRef ht, Boolean forFinalization) {
+#if ENABLE_MEMORY_COUNTERS
+    OSAtomicAdd64Barrier(-1 * (int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+#endif
+
+    CFIndex old_num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+
+    CFAllocatorRef allocator = CFGetAllocator(ht);
+    Boolean nullify = (!forFinalization || !CF_IS_COLLECTABLE_ALLOCATOR(allocator));
+
+    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
+    void *old_counts = NULL;
+    uintptr_t *old_hashes = NULL;
+
+    old_values = __CFBasicHashGetValues(ht);
+    if (nullify) __CFBasicHashSetValues(ht, NULL);
+    if (ht->bits.keys_offset) {
+        old_keys = __CFBasicHashGetKeys(ht);
+        if (nullify) __CFBasicHashSetKeys(ht, NULL);
+    }
+    if (ht->bits.counts_offset) {
+        old_counts = __CFBasicHashGetCounts(ht);
+        if (nullify) __CFBasicHashSetCounts(ht, NULL);
+    }
+    if (__CFBasicHashHasHashCache(ht)) {
+        old_hashes = __CFBasicHashGetHashes(ht);
+        if (nullify) __CFBasicHashSetHashes(ht, NULL);
+    }
+
+    if (nullify) {
+        ht->bits.mutations++;
+        ht->bits.num_buckets_idx = 0;
+        ht->bits.used_buckets = 0;
+        ht->bits.deleted = 0;
+    }
+    
+        for (CFIndex idx = 0; idx < old_num_buckets; idx++) {
+            uintptr_t stack_value = old_values[idx].neutral;
+            if (stack_value != 0UL && stack_value != ~0UL) {
+                uintptr_t old_value = stack_value;
+                if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
+                if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
+                __CFBasicHashEjectValue(ht, old_value);
+                if (old_keys) {
+                    uintptr_t old_key = old_keys[idx].neutral;
+                    if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
+                    if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
+                    __CFBasicHashEjectKey(ht, old_key);
+                }
+            }
+        }
+
+    if (forFinalization) {
+        ht->callbacks->freeCallbacks(ht, allocator, ht->callbacks);
+    }
+
+    if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        CFAllocatorDeallocate(allocator, old_values);
+        CFAllocatorDeallocate(allocator, old_keys);
+        CFAllocatorDeallocate(allocator, old_counts);
+        CFAllocatorDeallocate(allocator, old_hashes);
+    }
+
+#if ENABLE_MEMORY_COUNTERS
+    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
+#endif
+}
+
+static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) {
+#if ENABLE_MEMORY_COUNTERS
+    OSAtomicAdd64Barrier(-1 * (int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+    OSAtomicAdd32Barrier(-1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+
+    if (COCOA_HASHTABLE_REHASH_START_ENABLED()) COCOA_HASHTABLE_REHASH_START(ht, CFBasicHashGetNumBuckets(ht), CFBasicHashGetSize(ht, true));
+
+    CFIndex new_num_buckets_idx = ht->bits.num_buckets_idx;
+    if (0 != newItemCount) {
+        if (newItemCount < 0) newItemCount = 0;
+        CFIndex new_capacity_req = ht->bits.used_buckets + newItemCount;
+        new_num_buckets_idx = __CFBasicHashGetNumBucketsIndexForCapacity(ht, new_capacity_req);
+        if (1 == newItemCount && ht->bits.fast_grow) {
+            new_num_buckets_idx++;
+        }
+    }
+
+    CFIndex new_num_buckets = __CFBasicHashTableSizes[new_num_buckets_idx];
+    CFIndex old_num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+
+    CFBasicHashValue *new_values = NULL, *new_keys = NULL;
+    void *new_counts = NULL;
+    uintptr_t *new_hashes = NULL;
+
+    if (0 < new_num_buckets) {
+        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), __CFBasicHashHasCompactableValues(ht));
+        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));
+            if (!new_keys) HALT;
+            __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)");
+            memset(new_keys, 0, new_num_buckets * sizeof(CFBasicHashValue));
+        }
+        if (ht->bits.counts_offset) {
+            new_counts = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, (1 << ht->bits.counts_width), false, false);
+            if (!new_counts) HALT;
+            __SetLastAllocationEventName(new_counts, "CFBasicHash (count-store)");
+            memset(new_counts, 0, new_num_buckets * (1 << ht->bits.counts_width));
+        }
+        if (__CFBasicHashHasHashCache(ht)) {
+            new_hashes = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(uintptr_t), false, false);
+            if (!new_hashes) HALT;
+            __SetLastAllocationEventName(new_hashes, "CFBasicHash (hash-store)");
+            memset(new_hashes, 0, new_num_buckets * sizeof(uintptr_t));
+        }
+    }
+
+    ht->bits.num_buckets_idx = new_num_buckets_idx;
+    ht->bits.deleted = 0;
+
+    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
+    void *old_counts = NULL;
+    uintptr_t *old_hashes = NULL;
+
+    old_values = __CFBasicHashGetValues(ht);
+    __CFBasicHashSetValues(ht, new_values);
+    if (ht->bits.keys_offset) {
+        old_keys = __CFBasicHashGetKeys(ht);
+        __CFBasicHashSetKeys(ht, new_keys);
+    }
+    if (ht->bits.counts_offset) {
+        old_counts = __CFBasicHashGetCounts(ht);
+        __CFBasicHashSetCounts(ht, new_counts);
+    }
+    if (__CFBasicHashHasHashCache(ht)) {
+        old_hashes = __CFBasicHashGetHashes(ht);
+        __CFBasicHashSetHashes(ht, new_hashes);
+    }
+
+    if (0 < old_num_buckets) {
+        for (CFIndex idx = 0; idx < old_num_buckets; idx++) {
+            uintptr_t stack_value = old_values[idx].neutral;
+            if (stack_value != 0UL && stack_value != ~0UL) {
+                if (__CFBasicHashSubABZero == stack_value) stack_value = 0UL;
+                if (__CFBasicHashSubABOne == stack_value) stack_value = ~0UL;
+                uintptr_t stack_key = stack_value;
+                if (ht->bits.keys_offset) {
+                    stack_key = old_keys[idx].neutral;
+                    if (__CFBasicHashSubABZero == stack_key) stack_key = 0UL;
+                    if (__CFBasicHashSubABOne == stack_key) stack_key = ~0UL;
+                }
+                if (ht->bits.indirect_keys) {
+                    stack_key = ht->callbacks->getIndirectKey(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);
+                if (old_keys) {
+                    __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
+                }
+                if (old_counts) {
+                    switch (ht->bits.counts_width) {
+                    case 0: ((uint8_t *)new_counts)[bkt_idx] = ((uint8_t *)old_counts)[idx]; break;
+                    case 1: ((uint16_t *)new_counts)[bkt_idx] = ((uint16_t *)old_counts)[idx]; break;
+                    case 2: ((uint32_t *)new_counts)[bkt_idx] = ((uint32_t *)old_counts)[idx]; break;
+                    case 3: ((uint64_t *)new_counts)[bkt_idx] = ((uint64_t *)old_counts)[idx]; break;
+                    }
+                }
+                if (old_hashes) {
+                    new_hashes[bkt_idx] = old_hashes[idx];
+                }
+            }
+        }
+    }
+
+    CFAllocatorRef allocator = CFGetAllocator(ht);
+    if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        CFAllocatorDeallocate(allocator, old_values);
+        CFAllocatorDeallocate(allocator, old_keys);
+        CFAllocatorDeallocate(allocator, old_counts);
+        CFAllocatorDeallocate(allocator, old_hashes);
+    }
+
+    if (COCOA_HASHTABLE_REHASH_END_ENABLED()) COCOA_HASHTABLE_REHASH_END(ht, CFBasicHashGetNumBuckets(ht), CFBasicHashGetSize(ht, true));
+
+#if ENABLE_MEMORY_COUNTERS
+    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), &__CFBasicHashTotalSize);
+    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
+    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+}
+
+__private_extern__ void CFBasicHashSetCapacity(CFBasicHashRef ht, CFIndex capacity) {
+    if (!CFBasicHashIsMutable(ht)) HALT;
+    if (ht->bits.used_buckets < capacity) {
+        ht->bits.mutations++;
+        __CFBasicHashRehash(ht, capacity - ht->bits.used_buckets);
+    }
+}
+
+static void __CFBasicHashAddValue(CFBasicHashRef ht, CFIndex bkt_idx, uintptr_t stack_key, uintptr_t stack_value) {
+    ht->bits.mutations++;
+    if (CFBasicHashGetCapacity(ht) < ht->bits.used_buckets + 1) {
+        __CFBasicHashRehash(ht, 1);
+        bkt_idx = __CFBasicHashFindBucket_NoCollision(ht, stack_key, 0);
+    } else if (__CFBasicHashIsDeleted(ht, bkt_idx)) {
+        ht->bits.deleted--;
+    }
+    uintptr_t key_hash = 0;
+    if (__CFBasicHashHasHashCache(ht)) {
+        key_hash = __CFBasicHashHashKey(ht, stack_key);
+    }
+    stack_value = __CFBasicHashImportValue(ht, stack_value);
+    if (ht->bits.keys_offset) {
+        stack_key = __CFBasicHashImportKey(ht, stack_key);
+    }
+    __CFBasicHashSetValue(ht, bkt_idx, stack_value, false, false);
+    if (ht->bits.keys_offset) {
+        __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
+    }
+    if (ht->bits.counts_offset) {
+        __CFBasicHashIncSlotCount(ht, bkt_idx);
+    }
+    if (__CFBasicHashHasHashCache(ht)) {
+        __CFBasicHashGetHashes(ht)[bkt_idx] = key_hash;
+    }
+    ht->bits.used_buckets++;
+}
+
+static void __CFBasicHashReplaceValue(CFBasicHashRef ht, CFIndex bkt_idx, uintptr_t stack_key, uintptr_t stack_value) {
+    ht->bits.mutations++;
+    stack_value = __CFBasicHashImportValue(ht, stack_value);
+    if (ht->bits.keys_offset) {
+        stack_key = __CFBasicHashImportKey(ht, stack_key);
+    }
+    __CFBasicHashSetValue(ht, bkt_idx, stack_value, false, false);
+    if (ht->bits.keys_offset) {
+        __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
+    }
+}
+
+static void __CFBasicHashRemoveValue(CFBasicHashRef ht, CFIndex bkt_idx) {
+    ht->bits.mutations++;
+    __CFBasicHashSetValue(ht, bkt_idx, ~0UL, false, true);
+    if (ht->bits.keys_offset) {
+        __CFBasicHashSetKey(ht, bkt_idx, ~0UL, false, true);
+    }
+    if (ht->bits.counts_offset) {
+        __CFBasicHashDecSlotCount(ht, bkt_idx);
+    }
+    if (__CFBasicHashHasHashCache(ht)) {
+        __CFBasicHashGetHashes(ht)[bkt_idx] = 0;
+    }
+    ht->bits.used_buckets--;
+    ht->bits.deleted++;
+    Boolean do_shrink = false;
+    if (ht->bits.fast_grow) { // == slow shrink
+        do_shrink = (5 < ht->bits.num_buckets_idx && ht->bits.used_buckets < __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx - 5));
+    } else {
+        do_shrink = (2 < ht->bits.num_buckets_idx && ht->bits.used_buckets < __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx - 2));
+    }
+    if (do_shrink) {
+        __CFBasicHashRehash(ht, -1);
+        return;
+    }
+    do_shrink = (0 == ht->bits.deleted); // .deleted roll-over
+    CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+    do_shrink = do_shrink || ((20 <= num_buckets) && (num_buckets / 4 <= ht->bits.deleted));
+    if (do_shrink) {
+        __CFBasicHashRehash(ht, 0);
+    }
+}
+
+__private_extern__ 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;
+    if (__CFBasicHashSubABZero == stack_value) HALT;
+    if (__CFBasicHashSubABOne == stack_value) HALT;
+    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
+    if (0 < bkt.count) {
+        ht->bits.mutations++;
+        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not yet as large as a CFIndex can be... otherwise clamp and do nothing
+            __CFBasicHashIncSlotCount(ht, bkt.idx);
+            return true;
+        }
+    } else {
+        __CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
+        return true;
+    }
+    return false;
+}
+
+__private_extern__ 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;
+    if (__CFBasicHashSubABZero == stack_value) HALT;
+    if (__CFBasicHashSubABOne == stack_value) HALT;
+    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
+    if (0 < bkt.count) {
+        __CFBasicHashReplaceValue(ht, bkt.idx, stack_key, stack_value);
+    }
+}
+
+__private_extern__ 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;
+    if (__CFBasicHashSubABZero == stack_value) HALT;
+    if (__CFBasicHashSubABOne == stack_value) HALT;
+    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
+    if (0 < bkt.count) {
+        __CFBasicHashReplaceValue(ht, bkt.idx, stack_key, stack_value);
+    } else {
+        __CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
+    }
+}
+
+__private_extern__ 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);
+    if (1 < bkt.count) {
+        ht->bits.mutations++;
+        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not as large as a CFIndex can be... otherwise clamp and do nothing
+            __CFBasicHashDecSlotCount(ht, bkt.idx);
+        }
+    } else if (0 < bkt.count) {
+        __CFBasicHashRemoveValue(ht, bkt.idx);
+    }
+    return bkt.count;
+}
+
+__private_extern__ CFIndex CFBasicHashRemoveValueAtIndex(CFBasicHashRef ht, CFIndex idx) {
+    if (!CFBasicHashIsMutable(ht)) HALT;
+    CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
+    if (1 < bkt.count) {
+        ht->bits.mutations++;
+        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not as large as a CFIndex can be... otherwise clamp and do nothing
+            __CFBasicHashDecSlotCount(ht, bkt.idx);
+        }
+    } else if (0 < bkt.count) {
+        __CFBasicHashRemoveValue(ht, bkt.idx);
+    }
+    return bkt.count;
+}
+
+__private_extern__ 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) {
+    if (!CFBasicHashIsMutable(ht)) HALT;
+    if (__CFBasicHashSubABZero == stack_key) HALT;
+    if (__CFBasicHashSubABOne == stack_key) HALT;
+    if (__CFBasicHashSubABZero == int_value) HALT;
+    if (__CFBasicHashSubABOne == int_value) HALT;
+    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
+    if (0 < bkt.count) {
+        ht->bits.mutations++;
+    } else {
+        // must rehash before renumbering
+        if (CFBasicHashGetCapacity(ht) < ht->bits.used_buckets + 1) {
+            __CFBasicHashRehash(ht, 1);
+            bkt.idx = __CFBasicHashFindBucket_NoCollision(ht, stack_key, 0);
+        }
+        CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        for (CFIndex idx = 0; idx < cnt; idx++) {
+            if (!__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
+                uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
+                if (int_value <= stack_value) {
+                    stack_value++;
+                    __CFBasicHashSetValue(ht, idx, stack_value, true, false);
+                    ht->bits.mutations++;
+                }
+            }
+        }
+        __CFBasicHashAddValue(ht, bkt.idx, stack_key, int_value);
+        return true;
+    }
+    return false;
+}
+
+void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value) {
+    if (!CFBasicHashIsMutable(ht)) HALT;
+    if (__CFBasicHashSubABZero == int_value) HALT;
+    if (__CFBasicHashSubABOne == int_value) HALT;
+    uintptr_t bkt_idx = ~0UL;
+    CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+    for (CFIndex idx = 0; idx < cnt; idx++) {
+        if (!__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
+            uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
+            if (int_value == stack_value) {
+                bkt_idx = idx;
+            }
+            if (int_value < stack_value) {
+                stack_value--;
+                __CFBasicHashSetValue(ht, idx, stack_value, true, false);
+                ht->bits.mutations++;
+            }
+        }
+    }
+    __CFBasicHashRemoveValue(ht, bkt_idx);
+}
+
+__private_extern__ 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 *);
+    if (__CFBasicHashHasHashCache(ht)) size += sizeof(uintptr_t *);
+    if (total) {
+        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
+        if (0 < num_buckets) {
+            size += malloc_size(__CFBasicHashGetValues(ht));
+            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) {
+    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("%@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("%@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);
+    CFBasicHashApply(ht, ^(CFBasicHashBucket bkt) {
+            CFStringRef vDesc = NULL, kDesc = NULL;
+            if (!describeElements) {
+                vDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)bkt.weak_value);
+                if (ht->bits.keys_offset) {
+                    kDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)bkt.weak_key);
+                }
+            } else {
+                vDesc = ht->callbacks->copyValueDescription(ht, bkt.weak_value);
+                if (ht->bits.keys_offset) {
+                    kDesc = ht->callbacks->copyKeyDescription(ht, bkt.weak_key);
+                }
+            }
+            if (ht->bits.keys_offset && ht->bits.counts_offset) {
+                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ = %@ (%ld)\n"), entryPrefix, bkt.idx, kDesc, vDesc, bkt.count);
+            } else if (ht->bits.keys_offset) {
+                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ = %@\n"), entryPrefix, bkt.idx, kDesc, vDesc);
+            } else if (ht->bits.counts_offset) {
+                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ (%ld)\n"), entryPrefix, bkt.idx, vDesc, bkt.count);
+            } else {
+                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@\n"), entryPrefix, bkt.idx, vDesc);
+            }
+            if (kDesc) CFRelease(kDesc);
+            if (vDesc) CFRelease(vDesc);
+            return (Boolean)true;
+        });
+    CFStringAppendFormat(result, NULL, CFSTR("%@}\n"), prefix);
+    return result;
+}
+
+__private_extern__ 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) {
+    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) {
+    CFBasicHashRef ht = (CFBasicHashRef)cf;
+    return CFBasicHashGetCount(ht);
+}
+
+__private_extern__ 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);
+    CFRelease(desc);
+    return result;
+}
+
+__private_extern__ void __CFBasicHashDeallocate(CFTypeRef cf) {
+    CFBasicHashRef ht = (CFBasicHashRef)cf;
+    if (ht->bits.finalized) HALT;
+    ht->bits.finalized = 1;
+    __CFBasicHashDrain(ht, true);
+#if ENABLE_MEMORY_COUNTERS
+    OSAtomicAdd64Barrier(-1, &__CFBasicHashTotalCount);
+    OSAtomicAdd32Barrier(-1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+}
+
+static CFTypeID __kCFBasicHashTypeID = _kCFRuntimeNotATypeID;
+
+static const CFRuntimeClass __CFBasicHashClass = {
+    _kCFRuntimeScannedObject,
+    "CFBasicHash",
+    NULL,        // init
+    NULL,        // copy
+    __CFBasicHashDeallocate,
+    __CFBasicHashEqual,
+    __CFBasicHashHash,
+    NULL,        //
+    __CFBasicHashCopyDescription
+};
+
+__private_extern__ CFTypeID CFBasicHashGetTypeID(void) {
+    if (_kCFRuntimeNotATypeID == __kCFBasicHashTypeID) __kCFBasicHashTypeID = _CFRuntimeRegisterClass(&__CFBasicHashClass);
+    return __kCFBasicHashTypeID;
+}
+
+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
+    if (flags & kCFBasicHashHasHashCache) size += sizeof(uintptr_t *); // hashes
+    CFBasicHashRef ht = (CFBasicHashRef)_CFRuntimeCreateInstance(allocator, CFBasicHashGetTypeID(), size, NULL);
+    if (NULL == ht) return NULL;
+
+    ht->bits.finalized = 0;
+    ht->bits.hash_style = (flags >> 13) & 0x3;
+    ht->bits.fast_grow = (flags & kCFBasicHashAggressiveGrowth) ? 1 : 0;
+    ht->bits.counts_width = 0;
+    ht->bits.strong_values = (flags & kCFBasicHashStrongValues) ? 1 : 0;
+    ht->bits.strong_keys = (flags & kCFBasicHashStrongKeys) ? 1 : 0;
+    ht->bits.weak_values = (flags & kCFBasicHashWeakValues) ? 1 : 0;
+    ht->bits.weak_keys = (flags & kCFBasicHashWeakKeys) ? 1 : 0;
+    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;
+    ht->bits.mutations = 1;
+
+    if (ht->bits.strong_values && ht->bits.weak_values) HALT;
+    if (ht->bits.strong_values && ht->bits.int_values) HALT;
+    if (ht->bits.strong_keys && ht->bits.weak_keys) HALT;
+    if (ht->bits.strong_keys && ht->bits.int_keys) HALT;
+    if (ht->bits.weak_values && ht->bits.int_values) HALT;
+    if (ht->bits.weak_keys && ht->bits.int_keys) HALT;
+    if (ht->bits.indirect_keys && ht->bits.strong_keys) HALT;
+    if (ht->bits.indirect_keys && ht->bits.weak_keys) HALT;
+    if (ht->bits.indirect_keys && ht->bits.int_keys) HALT;
+
+    uint64_t offset = 1;
+    ht->bits.keys_offset = (flags & kCFBasicHashHasKeys) ? offset++ : 0;
+    ht->bits.counts_offset = (flags & kCFBasicHashHasCounts) ? offset++ : 0;
+    ht->bits.hashes_offset = (flags & kCFBasicHashHasHashCache) ? offset++ : 0;
+
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    ht->bits.hashes_offset = 0;
+    ht->bits.strong_values = 0;
+    ht->bits.strong_keys = 0;
+    ht->bits.weak_values = 0;
+    ht->bits.weak_keys = 0;
+#endif
+
+    __AssignWithWriteBarrier(&ht->callbacks, cb);
+    for (CFIndex idx = 0; idx < offset; idx++) {
+        ht->pointers[idx] = NULL;
+    }
+
+#if ENABLE_MEMORY_COUNTERS
+    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
+    int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
+    while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
+    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+
+    return ht;
+}
+
+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;
+    uintptr_t *new_hashes = NULL;
+
+    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);
+        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) {
+            new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemory2(allocator, new_num_buckets, sizeof(CFBasicHashValue), strongKeys, false);
+            if (!new_keys) return NULL; // in this unusual circumstance, leak previously allocated blocks for now
+            __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)");
+        }
+        if (src_ht->bits.counts_offset) {
+            new_counts = (uintptr_t *)__CFBasicHashAllocateMemory2(allocator, new_num_buckets, (1 << src_ht->bits.counts_width), false, false);
+            if (!new_counts) return NULL; // in this unusual circumstance, leak previously allocated blocks for now
+            __SetLastAllocationEventName(new_counts, "CFBasicHash (count-store)");
+        }
+        if (__CFBasicHashHasHashCache(src_ht)) {
+            new_hashes = (uintptr_t *)__CFBasicHashAllocateMemory2(allocator, new_num_buckets, sizeof(uintptr_t), false, false);
+            if (!new_hashes) return NULL; // in this unusual circumstance, leak previously allocated blocks for now
+            __SetLastAllocationEventName(new_hashes, "CFBasicHash (hash-store)");
+        }
+    }
+
+    CFBasicHashRef ht = (CFBasicHashRef)_CFRuntimeCreateInstance(allocator, CFBasicHashGetTypeID(), size, NULL);
+    if (NULL == ht) return NULL; // in this unusual circumstance, leak previously allocated blocks for now
+
+    memmove((uint8_t *)ht + sizeof(CFRuntimeBase), (uint8_t *)src_ht + sizeof(CFRuntimeBase), sizeof(ht->bits));
+    if (kCFUseCollectableAllocator && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
+        ht->bits.strong_values = 0;
+        ht->bits.strong_keys = 0;
+        ht->bits.weak_values = 0;
+        ht->bits.weak_keys = 0;
+    }
+    ht->bits.finalized = 0;
+    ht->bits.mutations = 1;
+    __AssignWithWriteBarrier(&ht->callbacks, newcb);
+
+    if (0 == new_num_buckets) {
+#if ENABLE_MEMORY_COUNTERS
+        int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+        while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
+        int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
+        while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
+        OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+        return ht;
+    }
+
+    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
+    void *old_counts = NULL;
+    uintptr_t *old_hashes = NULL;
+
+    old_values = __CFBasicHashGetValues(src_ht);
+    if (src_ht->bits.keys_offset) {
+        old_keys = __CFBasicHashGetKeys(src_ht);
+    }
+    if (src_ht->bits.counts_offset) {
+        old_counts = __CFBasicHashGetCounts(src_ht);
+    }
+    if (__CFBasicHashHasHashCache(src_ht)) {
+        old_hashes = __CFBasicHashGetHashes(src_ht);
+    }
+
+    __CFBasicHashSetValues(ht, new_values);
+    if (new_keys) {
+        __CFBasicHashSetKeys(ht, new_keys);
+    }
+    if (new_counts) {
+        __CFBasicHashSetCounts(ht, new_counts);
+    }
+    if (new_hashes) {
+        __CFBasicHashSetHashes(ht, new_hashes);
+    }
+
+    for (CFIndex idx = 0; idx < new_num_buckets; idx++) {
+        uintptr_t stack_value = old_values[idx].neutral;
+        if (stack_value != 0UL && stack_value != ~0UL) {
+            uintptr_t old_value = stack_value;
+            if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
+            if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
+            __CFBasicHashSetValue(ht, idx, __CFBasicHashImportValue(ht, old_value), true, false);
+            if (new_keys) {
+                uintptr_t old_key = old_keys[idx].neutral;
+                if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
+                if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
+                __CFBasicHashSetKey(ht, idx, __CFBasicHashImportKey(ht, old_key), true, false);
+            }
+        } else {
+            __CFBasicHashSetValue(ht, idx, stack_value, true, true);
+            if (new_keys) {
+                __CFBasicHashSetKey(ht, idx, stack_value, true, true);
+            }
+        }
+    }
+    if (new_counts) memmove(new_counts, old_counts, new_num_buckets * (1 << ht->bits.counts_width));
+    if (new_hashes) memmove(new_hashes, old_hashes, new_num_buckets * sizeof(uintptr_t));
+
+#if ENABLE_MEMORY_COUNTERS
+    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
+    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
+    int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
+    while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
+    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
+#endif
+
+    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 311868444ac51610c0720090964d3d6ded2a4ad2..eb85edfde781a43b4618fb5c5a313f64af41cae1 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBasicHash.h
-       Copyright (c) 2008-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
 */
 
 #include <CoreFoundation/CFBase.h>
diff --git a/CFBasicHash.m b/CFBasicHash.m
deleted file mode 100644 (file)
index 1554f86..0000000
+++ /dev/null
@@ -1,1726 +0,0 @@
-/*
- * Copyright (c) 2012 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@
- */
-
-/*     CFBasicHash.m
-       Copyright (c) 2008-2011, Apple Inc. All rights reserved.
-       Responsibility: Christopher Kane
-*/
-
-#import "CFBasicHash.h"
-#import <CoreFoundation/CFRuntime.h>
-#import <CoreFoundation/CFSet.h>
-#import <Block.h>
-#import <math.h>
-
-#if DEPLOYMENT_TARGET_WINDOWS
-#define __SetLastAllocationEventName(A, B) do { } while (0)
-#else
-#define __SetLastAllocationEventName(A, B) do { if (__CFOASafe && (A)) __CFSetLastAllocationEventName(A, B); } 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
-#define ENABLE_MEMORY_COUNTERS 0
-
-#if defined(DTRACE_PROBES_DISABLED) && DTRACE_PROBES_DISABLED
-#undef ENABLE_DTRACE_PROBES
-#define ENABLE_DTRACE_PROBES 0
-#endif
-
-/*
-// dtrace -h -s foo.d
-// Note: output then changed by casts of the arguments
-// dtrace macros last generated 2010-09-08 on 10.7 prerelease (11A259)
-
-provider Cocoa_HashTable {
-        probe hash_key(unsigned long table, unsigned long key, unsigned long hash);
-        probe test_equal(unsigned long table, unsigned long key1, unsigned long key2);
-        probe probing_start(unsigned long table, unsigned long num_buckets);
-        probe probe_empty(unsigned long table, unsigned long idx);
-        probe probe_deleted(unsigned long table, unsigned long idx);
-        probe probe_valid(unsigned long table, unsigned long idx);
-        probe probing_end(unsigned long table, unsigned long num_probes);
-        probe rehash_start(unsigned long table, unsigned long num_buckets, unsigned long total_size);
-        probe rehash_end(unsigned long table, unsigned long num_buckets, unsigned long total_size);
-};
-
-#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable provider
-#pragma D attributes Private/Private/Unknown provider Cocoa_HashTable module
-#pragma D attributes Private/Private/Unknown provider Cocoa_HashTable function
-#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable name
-#pragma D attributes Unstable/Unstable/Common provider Cocoa_HashTable args
-*/
-
-#if ENABLE_DTRACE_PROBES
-
-#define COCOA_HASHTABLE_STABILITY "___dtrace_stability$Cocoa_HashTable$v1$4_4_5_1_1_0_1_1_0_4_4_5_4_4_5"
-
-#define COCOA_HASHTABLE_TYPEDEFS "___dtrace_typedefs$Cocoa_HashTable$v2"
-
-#define COCOA_HASHTABLE_REHASH_END(arg0, arg1, arg2) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$rehash_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_REHASH_END_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$rehash_end$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_REHASH_START(arg0, arg1, arg2) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$rehash_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_REHASH_START_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$rehash_start$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_HASH_KEY(arg0, arg1, arg2) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$hash_key$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_HASH_KEY_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$hash_key$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_PROBE_DELETED(arg0, arg1) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$probe_deleted$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_PROBE_DELETED_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_deleted$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_PROBE_EMPTY(arg0, arg1) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$probe_empty$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_PROBE_EMPTY_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_empty$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_PROBE_VALID(arg0, arg1) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$probe_valid$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_PROBE_VALID_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probe_valid$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_PROBING_END(arg0, arg1) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$probing_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_PROBING_END_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probing_end$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_PROBING_START(arg0, arg1) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$probing_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_PROBING_START_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$probing_start$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-#define COCOA_HASHTABLE_TEST_EQUAL(arg0, arg1, arg2) \
-do { \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_TYPEDEFS); \
-        __dtrace_probe$Cocoa_HashTable$test_equal$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67((unsigned long)(arg0), (unsigned long)(arg1), (unsigned long)(arg2)); \
-        __asm__ volatile(".reference " COCOA_HASHTABLE_STABILITY); \
-} while (0)
-#define        COCOA_HASHTABLE_TEST_EQUAL_ENABLED() \
-       ({ int _r = __dtrace_isenabled$Cocoa_HashTable$test_equal$v1(); \
-               __asm__ volatile(""); \
-               _r; })
-
-extern void __dtrace_probe$Cocoa_HashTable$hash_key$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$hash_key$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$probe_deleted$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$probe_deleted$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$probe_empty$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$probe_empty$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$probe_valid$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$probe_valid$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$probing_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$probing_end$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$probing_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$probing_start$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$rehash_end$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$rehash_end$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$rehash_start$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$rehash_start$v1(void);
-extern void __dtrace_probe$Cocoa_HashTable$test_equal$v1$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67$756e7369676e6564206c6f6e67(unsigned long, unsigned long, unsigned long);
-extern int __dtrace_isenabled$Cocoa_HashTable$test_equal$v1(void);
-
-#else
-
-#define COCOA_HASHTABLE_REHASH_END(arg0, arg1, arg2) do {} while (0)
-#define COCOA_HASHTABLE_REHASH_END_ENABLED() 0
-#define COCOA_HASHTABLE_REHASH_START(arg0, arg1, arg2) do {} while (0)
-#define COCOA_HASHTABLE_REHASH_START_ENABLED() 0
-#define COCOA_HASHTABLE_HASH_KEY(arg0, arg1, arg2) do {} while (0)
-#define COCOA_HASHTABLE_HASH_KEY_ENABLED() 0
-#define COCOA_HASHTABLE_PROBE_DELETED(arg0, arg1) do {} while (0)
-#define COCOA_HASHTABLE_PROBE_DELETED_ENABLED() 0
-#define COCOA_HASHTABLE_PROBE_EMPTY(arg0, arg1) do {} while (0)
-#define COCOA_HASHTABLE_PROBE_EMPTY_ENABLED() 0
-#define COCOA_HASHTABLE_PROBE_VALID(arg0, arg1) do {} while (0)
-#define COCOA_HASHTABLE_PROBE_VALID_ENABLED() 0
-#define COCOA_HASHTABLE_PROBING_END(arg0, arg1) do {} while (0)
-#define COCOA_HASHTABLE_PROBING_END_ENABLED() 0
-#define COCOA_HASHTABLE_PROBING_START(arg0, arg1) do {} while (0)
-#define COCOA_HASHTABLE_PROBING_START_ENABLED() 0
-#define COCOA_HASHTABLE_TEST_EQUAL(arg0, arg1, arg2) do {} while (0)
-#define COCOA_HASHTABLE_TEST_EQUAL_ENABLED() 0
-
-#endif
-
-
-#if !defined(__LP64__)
-#define __LP64__ 0
-#endif
-
-// Prime numbers. Values above 100 have been adjusted up so that the
-// malloced block size will be just below a multiple of 512; values
-// above 1200 have been adjusted up to just below a multiple of 4096.
-static const uintptr_t __CFBasicHashTableSizes[64] = {
-    0, 3, 7, 13, 23, 41, 71, 127, 191, 251, 383, 631, 1087, 1723,
-    2803, 4523, 7351, 11959, 19447, 31231, 50683, 81919, 132607,
-    214519, 346607, 561109, 907759, 1468927, 2376191, 3845119,
-    6221311, 10066421, 16287743, 26354171, 42641881, 68996069,
-    111638519, 180634607, 292272623, 472907251,
-#if __LP64__
-    765180413UL, 1238087663UL, 2003267557UL, 3241355263UL, 5244622819UL,
-#if 0
-    8485977589UL, 13730600407UL, 22216578047UL, 35947178479UL,
-    58163756537UL, 94110934997UL, 152274691561UL, 246385626107UL,
-    398660317687UL, 645045943807UL, 1043706260983UL, 1688752204787UL,
-    2732458465769UL, 4421210670577UL, 7153669136377UL,
-    11574879807461UL, 18728548943849UL, 30303428750843UL
-#endif
-#endif
-};
-
-static const uintptr_t __CFBasicHashTableCapacities[64] = {
-    0, 3, 6, 11, 19, 32, 52, 85, 118, 155, 237, 390, 672, 1065,
-    1732, 2795, 4543, 7391, 12019, 19302, 31324, 50629, 81956,
-    132580, 214215, 346784, 561026, 907847, 1468567, 2376414,
-    3844982, 6221390, 10066379, 16287773, 26354132, 42641916,
-    68996399, 111638327, 180634415, 292272755,
-#if __LP64__
-    472907503UL, 765180257UL, 1238087439UL, 2003267722UL, 3241355160UL,
-#if 0
-    5244622578UL, 8485977737UL, 13730600347UL, 22216578100UL,
-    35947178453UL, 58163756541UL, 94110935011UL, 152274691274UL,
-    246385626296UL, 398660317578UL, 645045943559UL, 1043706261135UL,
-    1688752204693UL, 2732458465840UL, 4421210670552UL,
-    7153669136706UL, 11574879807265UL, 18728548943682UL
-#endif
-#endif
-};
-
-// Primitive roots for the primes above
-static const uintptr_t __CFBasicHashPrimitiveRoots[64] = {
-    0, 2, 3, 2, 5, 6, 7, 3, 19, 6, 5, 3, 3, 3,
-    2, 5, 6, 3, 3, 6, 2, 3, 3,
-    3, 5, 10, 3, 3, 22, 3,
-    3, 3, 5, 2, 22, 2,
-    11, 5, 5, 2,
-#if __LP64__
-    3, 10, 2, 3, 10,
-    2, 3, 5, 3,
-    3, 2, 7, 2,
-    3, 3, 3, 2,
-    3, 5, 5,
-    2, 3, 2
-#endif
-};
-
-CF_INLINE void *__CFBasicHashAllocateMemory(CFConstBasicHashRef ht, CFIndex count, CFIndex elem_size, Boolean strong, Boolean compactable) {
-    CFAllocatorRef allocator = CFGetAllocator(ht);
-    void *new_mem = NULL;
-    if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        new_mem = auto_zone_allocate_object(objc_collectableZone(), count * elem_size, strong ? (compactable ? AUTO_POINTERS_ONLY : AUTO_MEMORY_SCANNED) : AUTO_UNSCANNED, false, false);
-    } else {
-        new_mem = CFAllocatorAllocate(allocator, count * elem_size, 0);
-    }
-    if (!new_mem) HALT;
-    return new_mem;
-}
-
-#define __CFBasicHashSubABZero 0xa7baadb1
-#define __CFBasicHashSubABOne 0xa5baadb9
-
-typedef union {
-    uintptr_t neutral;
-    id strong;
-    id weak;
-} CFBasicHashValue;
-
-struct __CFBasicHash {
-    CFRuntimeBase base;
-    struct { // 128 bits
-        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;
-        uint8_t hashes_offset:2;
-        uint8_t strong_values:1;
-        uint8_t strong_keys:1;
-        uint8_t weak_values:1;
-        uint8_t weak_keys:1;
-        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;
-    } bits;
-    __strong CFBasicHashCallbacks *callbacks;
-    void *pointers[1];
-};
-
-__private_extern__ Boolean CFBasicHashHasStrongValues(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.strong_values ? true : false;
-#endif
-}
-
-__private_extern__ Boolean CFBasicHashHasStrongKeys(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.strong_keys ? true : false;
-#endif
-}
-
-CF_INLINE Boolean __CFBasicHashHasCompactableKeys(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.compactable_keys ? true : false;
-#endif
-}
-
-CF_INLINE Boolean __CFBasicHashHasCompactableValues(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.compactable_values ? true : false;
-#endif
-}
-
-CF_INLINE Boolean __CFBasicHashHasWeakValues(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.weak_values ? true : false;
-#endif
-}
-
-CF_INLINE Boolean __CFBasicHashHasWeakKeys(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.weak_keys ? true : false;
-#endif
-}
-
-CF_INLINE Boolean __CFBasicHashHasHashCache(CFConstBasicHashRef ht) {
-#if defined(__arm__)
-    return false;
-#else
-    return ht->bits.hashes_offset ? true : false;
-#endif
-}
-
-CF_INLINE uintptr_t __CFBasicHashImportValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    return ht->callbacks->retainValue(ht, stack_value);
-}
-
-CF_INLINE uintptr_t __CFBasicHashImportKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    return ht->callbacks->retainKey(ht, stack_key);
-}
-
-CF_INLINE void __CFBasicHashEjectValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    ht->callbacks->releaseValue(ht, stack_value);
-}
-
-CF_INLINE void __CFBasicHashEjectKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    ht->callbacks->releaseKey(ht, 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);
-}
-
-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);
-}
-
-CF_INLINE CFHashCode __CFBasicHashHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    CFHashCode hash_code = (CFHashCode)ht->callbacks->hashKey(ht, stack_key);
-    COCOA_HASHTABLE_HASH_KEY(ht, stack_key, hash_code);
-    return hash_code;
-}
-
-CF_INLINE CFBasicHashValue *__CFBasicHashGetValues(CFConstBasicHashRef ht) {
-    return (CFBasicHashValue *)ht->pointers[0];
-}
-
-CF_INLINE void __CFBasicHashSetValues(CFBasicHashRef ht, CFBasicHashValue *ptr) {
-    __AssignWithWriteBarrier(&ht->pointers[0], ptr);
-}
-
-CF_INLINE CFBasicHashValue *__CFBasicHashGetKeys(CFConstBasicHashRef ht) {
-    return (CFBasicHashValue *)ht->pointers[ht->bits.keys_offset];
-}
-
-CF_INLINE void __CFBasicHashSetKeys(CFBasicHashRef ht, CFBasicHashValue *ptr) {
-    __AssignWithWriteBarrier(&ht->pointers[ht->bits.keys_offset], ptr);
-}
-
-CF_INLINE void *__CFBasicHashGetCounts(CFConstBasicHashRef ht) {
-    return (void *)ht->pointers[ht->bits.counts_offset];
-}
-
-CF_INLINE void __CFBasicHashSetCounts(CFBasicHashRef ht, void *ptr) {
-    __AssignWithWriteBarrier(&ht->pointers[ht->bits.counts_offset], ptr);
-}
-
-CF_INLINE uintptr_t __CFBasicHashGetValue(CFConstBasicHashRef ht, CFIndex idx) {
-    uintptr_t val = __CFBasicHashGetValues(ht)[idx].neutral;
-    if (__CFBasicHashSubABZero == val) return 0UL;
-    if (__CFBasicHashSubABOne == val) return ~0UL;
-    return val;
-}
-
-CF_INLINE void __CFBasicHashSetValue(CFBasicHashRef ht, CFIndex idx, uintptr_t stack_value, Boolean ignoreOld, Boolean literal) {
-    CFBasicHashValue *valuep = &(__CFBasicHashGetValues(ht)[idx]);
-    uintptr_t old_value = ignoreOld ? 0 : valuep->neutral;
-    if (!literal) {
-        if (0UL == stack_value) stack_value = __CFBasicHashSubABZero;
-        if (~0UL == stack_value) stack_value = __CFBasicHashSubABOne;
-    }
-    if (CFBasicHashHasStrongValues(ht)) valuep->strong = (id)stack_value; else valuep->neutral = stack_value;
-    if (!ignoreOld) {
-        if (!(old_value == 0UL || old_value == ~0UL)) {
-            if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
-            if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
-            __CFBasicHashEjectValue(ht, old_value);
-        }
-    }
-}
-
-CF_INLINE uintptr_t __CFBasicHashGetKey(CFConstBasicHashRef ht, CFIndex idx) {
-    if (ht->bits.keys_offset) {
-        uintptr_t key = __CFBasicHashGetKeys(ht)[idx].neutral;
-        if (__CFBasicHashSubABZero == key) return 0UL;
-        if (__CFBasicHashSubABOne == key) return ~0UL;
-        return key;
-    }
-    if (ht->bits.indirect_keys) {
-        uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
-        return ht->callbacks->getIndirectKey(ht, stack_value);
-    }
-    return __CFBasicHashGetValue(ht, idx);
-}
-
-CF_INLINE void __CFBasicHashSetKey(CFBasicHashRef ht, CFIndex idx, uintptr_t stack_key, Boolean ignoreOld, Boolean literal) {
-    if (0 == ht->bits.keys_offset) HALT;
-    CFBasicHashValue *keyp = &(__CFBasicHashGetKeys(ht)[idx]);
-    uintptr_t old_key = ignoreOld ? 0 : keyp->neutral;
-    if (!literal) {
-        if (0UL == stack_key) stack_key = __CFBasicHashSubABZero;
-        if (~0UL == stack_key) stack_key = __CFBasicHashSubABOne;
-    }
-    if (CFBasicHashHasStrongKeys(ht)) keyp->strong = (id)stack_key; else keyp->neutral = stack_key;
-    if (!ignoreOld) {
-        if (!(old_key == 0UL || old_key == ~0UL)) {
-            if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
-            if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
-            __CFBasicHashEjectKey(ht, old_key);
-        }
-    }
-}
-
-CF_INLINE uintptr_t __CFBasicHashIsEmptyOrDeleted(CFConstBasicHashRef ht, CFIndex idx) {
-    uintptr_t stack_value = __CFBasicHashGetValues(ht)[idx].neutral;
-    return (0UL == stack_value || ~0UL == stack_value);
-}
-
-CF_INLINE uintptr_t __CFBasicHashIsDeleted(CFConstBasicHashRef ht, CFIndex idx) {
-    uintptr_t stack_value = __CFBasicHashGetValues(ht)[idx].neutral;
-    return (~0UL == stack_value);
-}
-
-CF_INLINE uintptr_t __CFBasicHashGetSlotCount(CFConstBasicHashRef ht, CFIndex idx) {
-    void *counts = __CFBasicHashGetCounts(ht);
-    switch (ht->bits.counts_width) {
-    case 0: return ((uint8_t *)counts)[idx];
-    case 1: return ((uint16_t *)counts)[idx];
-    case 2: return ((uint32_t *)counts)[idx];
-    case 3: return ((uint64_t *)counts)[idx];
-    }
-    return 0;
-}
-
-CF_INLINE void __CFBasicHashBumpCounts(CFBasicHashRef ht) {
-    void *counts = __CFBasicHashGetCounts(ht);
-    CFAllocatorRef allocator = CFGetAllocator(ht);
-    switch (ht->bits.counts_width) {
-    case 0: {
-        uint8_t *counts08 = (uint8_t *)counts;
-        ht->bits.counts_width = 1;
-        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        uint16_t *counts16 = (uint16_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 2, false, false);
-        __SetLastAllocationEventName(counts16, "CFBasicHash (count-store)");
-        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
-            counts16[idx2] = counts08[idx2];
-        }
-        __CFBasicHashSetCounts(ht, counts16);
-        if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            CFAllocatorDeallocate(allocator, counts08);
-        }
-        break;
-    }
-    case 1: {
-        uint16_t *counts16 = (uint16_t *)counts;
-        ht->bits.counts_width = 2;
-        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        uint32_t *counts32 = (uint32_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 4, false, false);
-        __SetLastAllocationEventName(counts32, "CFBasicHash (count-store)");
-        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
-            counts32[idx2] = counts16[idx2];
-        }
-        __CFBasicHashSetCounts(ht, counts32);
-         if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            CFAllocatorDeallocate(allocator, counts16);
-        }
-        break;
-    }
-    case 2: {
-        uint32_t *counts32 = (uint32_t *)counts;
-        ht->bits.counts_width = 3;
-        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        uint64_t *counts64 = (uint64_t *)__CFBasicHashAllocateMemory(ht, num_buckets, 8, false, false);
-        __SetLastAllocationEventName(counts64, "CFBasicHash (count-store)");
-        for (CFIndex idx2 = 0; idx2 < num_buckets; idx2++) {
-            counts64[idx2] = counts32[idx2];
-        }
-        __CFBasicHashSetCounts(ht, counts64);
-         if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-            CFAllocatorDeallocate(allocator, counts32);
-        }
-        break;
-    }
-    case 3: {
-        HALT;
-        break;
-    }
-    }
-}
-
-static void __CFBasicHashIncSlotCount(CFBasicHashRef ht, CFIndex idx) {
-    void *counts = __CFBasicHashGetCounts(ht);
-    switch (ht->bits.counts_width) {
-    case 0: {
-        uint8_t *counts08 = (uint8_t *)counts;
-        uint8_t val = counts08[idx];
-        if (val < INT8_MAX) {
-            counts08[idx] = val + 1;
-            return;
-        }
-        __CFBasicHashBumpCounts(ht);
-        __CFBasicHashIncSlotCount(ht, idx);
-        break;
-    }
-    case 1: {
-        uint16_t *counts16 = (uint16_t *)counts;
-        uint16_t val = counts16[idx];
-        if (val < INT16_MAX) {
-            counts16[idx] = val + 1;
-            return;
-        }
-        __CFBasicHashBumpCounts(ht);
-        __CFBasicHashIncSlotCount(ht, idx);
-        break;
-    }
-    case 2: {
-        uint32_t *counts32 = (uint32_t *)counts;
-        uint32_t val = counts32[idx];
-        if (val < INT32_MAX) {
-            counts32[idx] = val + 1;
-            return;
-        }
-        __CFBasicHashBumpCounts(ht);
-        __CFBasicHashIncSlotCount(ht, idx);
-        break;
-    }
-    case 3: {
-        uint64_t *counts64 = (uint64_t *)counts;
-        uint64_t val = counts64[idx];
-        if (val < INT64_MAX) {
-            counts64[idx] = val + 1;
-            return;
-        }
-        __CFBasicHashBumpCounts(ht);
-        __CFBasicHashIncSlotCount(ht, idx);
-        break;
-    }
-    }
-}
-
-CF_INLINE void __CFBasicHashDecSlotCount(CFBasicHashRef ht, CFIndex idx) {
-    void *counts = __CFBasicHashGetCounts(ht);
-    switch (ht->bits.counts_width) {
-    case 0: ((uint8_t  *)counts)[idx]--; return;
-    case 1: ((uint16_t *)counts)[idx]--; return;
-    case 2: ((uint32_t *)counts)[idx]--; return;
-    case 3: ((uint64_t *)counts)[idx]--; return;
-    }
-}
-
-CF_INLINE uintptr_t *__CFBasicHashGetHashes(CFConstBasicHashRef ht) {
-    return (uintptr_t *)ht->pointers[ht->bits.hashes_offset];
-}
-
-CF_INLINE void __CFBasicHashSetHashes(CFBasicHashRef ht, uintptr_t *ptr) {
-    __AssignWithWriteBarrier(&ht->pointers[ht->bits.hashes_offset], ptr);
-}
-
-
-// to expose the load factor, expose this function to customization
-CF_INLINE CFIndex __CFBasicHashGetCapacityForNumBuckets(CFConstBasicHashRef ht, CFIndex num_buckets_idx) {
-    return __CFBasicHashTableCapacities[num_buckets_idx];
-}
-
-CF_INLINE CFIndex __CFBasicHashGetNumBucketsIndexForCapacity(CFConstBasicHashRef ht, CFIndex capacity) {
-    for (CFIndex idx = 0; idx < 64; idx++) {
-        if (capacity <= __CFBasicHashGetCapacityForNumBuckets(ht, idx)) return idx;
-    }
-    HALT;
-    return 0;
-}
-
-__private_extern__ CFIndex CFBasicHashGetNumBuckets(CFConstBasicHashRef ht) {
-    return __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-}
-
-__private_extern__ CFIndex CFBasicHashGetCapacity(CFConstBasicHashRef ht) {
-    return __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx);
-}
-
-// In returned struct, .count is zero if the bucket is empty or deleted,
-// and the .weak_key field indicates which. .idx is either the index of
-// 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) {
-    CFBasicHashBucket result;
-    result.idx = idx;
-    if (__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
-        result.count = 0;
-        result.weak_value = 0;
-        result.weak_key = 0;
-    } else {
-        result.count = (ht->bits.counts_offset) ? __CFBasicHashGetSlotCount(ht, idx) : 1;
-        result.weak_value = __CFBasicHashGetValue(ht, idx);
-        result.weak_key = __CFBasicHashGetKey(ht, idx);
-    }
-    return result;
-}
-
-#if defined(__arm__)
-static uintptr_t __CFBasicHashFold(uintptr_t dividend, uint8_t idx) {
-    switch (idx) {
-    case 1: return dividend % 3;
-    case 2: return dividend % 7;
-    case 3: return dividend % 13;
-    case 4: return dividend % 23;
-    case 5: return dividend % 41;
-    case 6: return dividend % 71;
-    case 7: return dividend % 127;
-    case 8: return dividend % 191;
-    case 9: return dividend % 251;
-    case 10: return dividend % 383;
-    case 11: return dividend % 631;
-    case 12: return dividend % 1087;
-    case 13: return dividend % 1723;
-    case 14: return dividend % 2803;
-    case 15: return dividend % 4523;
-    case 16: return dividend % 7351;
-    case 17: return dividend % 11959;
-    case 18: return dividend % 19447;
-    case 19: return dividend % 31231;
-    case 20: return dividend % 50683;
-    case 21: return dividend % 81919;
-    case 22: return dividend % 132607;
-    case 23: return dividend % 214519;
-    case 24: return dividend % 346607;
-    case 25: return dividend % 561109;
-    case 26: return dividend % 907759;
-    case 27: return dividend % 1468927;
-    case 28: return dividend % 2376191;
-    case 29: return dividend % 3845119;
-    case 30: return dividend % 6221311;
-    case 31: return dividend % 10066421;
-    case 32: return dividend % 16287743;
-    case 33: return dividend % 26354171;
-    case 34: return dividend % 42641881;
-    case 35: return dividend % 68996069;
-    case 36: return dividend % 111638519;
-    case 37: return dividend % 180634607;
-    case 38: return dividend % 292272623;
-    case 39: return dividend % 472907251;
-    }
-    HALT;
-    return ~0;
-}
-#endif
-
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear
-#define FIND_BUCKET_HASH_STYLE         1
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_NoCollision
-#define FIND_BUCKET_HASH_STYLE         1
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_Indirect
-#define FIND_BUCKET_HASH_STYLE         1
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Linear_Indirect_NoCollision
-#define FIND_BUCKET_HASH_STYLE         1
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double
-#define FIND_BUCKET_HASH_STYLE         2
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_NoCollision
-#define FIND_BUCKET_HASH_STYLE         2
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_Indirect
-#define FIND_BUCKET_HASH_STYLE         2
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Double_Indirect_NoCollision
-#define FIND_BUCKET_HASH_STYLE         2
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential
-#define FIND_BUCKET_HASH_STYLE         3
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_NoCollision
-#define FIND_BUCKET_HASH_STYLE         3
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   0
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_Indirect
-#define FIND_BUCKET_HASH_STYLE         3
-#define FIND_BUCKET_FOR_REHASH         0
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-#define FIND_BUCKET_NAME               ___CFBasicHashFindBucket_Exponential_Indirect_NoCollision
-#define FIND_BUCKET_HASH_STYLE         3
-#define FIND_BUCKET_FOR_REHASH         1
-#define FIND_BUCKET_FOR_INDIRECT_KEY   1
-#include "CFBasicHashFindBucket.m"
-
-
-CF_INLINE CFBasicHashBucket __CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (0 == ht->bits.num_buckets_idx) {
-        CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
-        return result;
-    }
-    if (ht->bits.indirect_keys) {
-        switch (ht->bits.hash_style) {
-        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_Indirect(ht, stack_key);
-        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_Indirect(ht, stack_key);
-        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_Indirect(ht, stack_key);
-        }
-    } else {
-        switch (ht->bits.hash_style) {
-        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear(ht, stack_key);
-        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double(ht, stack_key);
-        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential(ht, stack_key);
-        }
-    }
-    HALT;
-    CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
-    return result;
-}
-
-CF_INLINE CFIndex __CFBasicHashFindBucket_NoCollision(CFConstBasicHashRef ht, uintptr_t stack_key, uintptr_t key_hash) {
-    if (0 == ht->bits.num_buckets_idx) {
-        return kCFNotFound;
-    }
-    if (ht->bits.indirect_keys) {
-        switch (ht->bits.hash_style) {
-        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_Indirect_NoCollision(ht, stack_key, key_hash);
-        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_Indirect_NoCollision(ht, stack_key, key_hash);
-        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_Indirect_NoCollision(ht, stack_key, key_hash);
-        }
-    } else {
-        switch (ht->bits.hash_style) {
-        case __kCFBasicHashLinearHashingValue: return ___CFBasicHashFindBucket_Linear_NoCollision(ht, stack_key, key_hash);
-        case __kCFBasicHashDoubleHashingValue: return ___CFBasicHashFindBucket_Double_NoCollision(ht, stack_key, key_hash);
-        case __kCFBasicHashExponentialHashingValue: return ___CFBasicHashFindBucket_Exponential_NoCollision(ht, stack_key, key_hash);
-        }
-    }
-    HALT;
-    return kCFNotFound;
-}
-
-__private_extern__ CFBasicHashBucket CFBasicHashFindBucket(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
-        CFBasicHashBucket result = {kCFNotFound, 0UL, 0UL, 0};
-        return result;
-    }
-    return __CFBasicHashFindBucket(ht, stack_key);
-}
-
-__private_extern__ uint16_t CFBasicHashGetSpecialBits(CFConstBasicHashRef ht) {
-    return ht->bits.special_bits;
-}
-
-__private_extern__ uint16_t CFBasicHashSetSpecialBits(CFBasicHashRef ht, uint16_t bits) {
-    uint16_t old =  ht->bits.special_bits;
-    ht->bits.special_bits = bits;
-    return old;
-}
-
-__private_extern__ 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;
-    if (__CFBasicHashHasHashCache(ht)) flags |= kCFBasicHashHasHashCache;
-    return flags;
-}
-
-__private_extern__ const CFBasicHashCallbacks *CFBasicHashGetCallbacks(CFConstBasicHashRef ht) {
-    return ht->callbacks;
-}
-
-__private_extern__ CFIndex CFBasicHashGetCount(CFConstBasicHashRef ht) {
-    if (ht->bits.counts_offset) {
-        CFIndex total = 0L;
-        CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        for (CFIndex idx = 0; idx < cnt; idx++) {
-            total += __CFBasicHashGetSlotCount(ht, idx);
-        }
-        return total;
-    }
-    return (CFIndex)ht->bits.used_buckets;
-}
-
-__private_extern__ CFIndex CFBasicHashGetCountOfKey(CFConstBasicHashRef ht, uintptr_t stack_key) {
-    if (__CFBasicHashSubABZero == stack_key || __CFBasicHashSubABOne == stack_key) {
-        return 0L;
-    }
-    if (0L == ht->bits.used_buckets) {
-        return 0L;
-    }
-    return __CFBasicHashFindBucket(ht, stack_key).count;
-}
-
-__private_extern__ CFIndex CFBasicHashGetCountOfValue(CFConstBasicHashRef ht, uintptr_t stack_value) {
-    if (__CFBasicHashSubABZero == stack_value) {
-        return 0L;
-    }
-    if (0L == ht->bits.used_buckets) {
-        return 0L;
-    }
-    if (!(ht->bits.keys_offset)) {
-        return __CFBasicHashFindBucket(ht, stack_value).count;
-    }
-    __block CFIndex total = 0L;
-    CFBasicHashApply(ht, ^(CFBasicHashBucket bkt) {
-            if ((stack_value == bkt.weak_value) || __CFBasicHashTestEqualValue(ht, bkt.weak_value, stack_value)) total += bkt.count;
-            return (Boolean)true;
-        });
-    return total;
-}
-
-__private_extern__ Boolean CFBasicHashesAreEqual(CFConstBasicHashRef ht1, CFConstBasicHashRef ht2) {
-    CFIndex cnt1 = CFBasicHashGetCount(ht1);
-    if (cnt1 != CFBasicHashGetCount(ht2)) return false;
-    if (0 == cnt1) return true;
-    __block Boolean equal = true;
-    CFBasicHashApply(ht1, ^(CFBasicHashBucket bkt1) {
-            CFBasicHashBucket bkt2 = __CFBasicHashFindBucket(ht2, bkt1.weak_key);
-            if (bkt1.count != bkt2.count) {
-                equal = false;
-                return (Boolean)false;
-            }
-            if ((ht1->bits.keys_offset) && (bkt1.weak_value != bkt2.weak_value) && !__CFBasicHashTestEqualValue(ht1, bkt1.weak_value, bkt2.weak_value)) {
-                equal = false;
-                return (Boolean)false;
-            }
-            return (Boolean)true;
-        });
-    return equal;
-}
-
-__private_extern__ 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);
-        if (0 < bkt.count) {
-            if (!block(bkt)) {
-                return;
-            }
-            used--;
-        }
-    }
-}
-
-__private_extern__ 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];
-    if (cnt < range.location + range.length) HALT;
-    for (CFIndex idx = 0; idx < range.length; idx++) {
-        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, range.location + idx);
-        if (0 < bkt.count) {
-            if (!block(bkt)) {
-                return;
-            }
-        }
-    }
-}
-
-__private_extern__ 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++) {
-        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
-        if (0 < bkt.count) {
-            used--;
-            for (CFIndex cnt = bkt.count; cnt-- && offset < bufferslen;) {
-                if (weak_values) { weak_values[offset] = bkt.weak_value; }
-                if (weak_keys) { weak_keys[offset] = bkt.weak_key; }
-                offset++;
-            }
-        }
-    }
-}
-
-__private_extern__ 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->itemsPtr = (unsigned long *)stackbuffer;
-    CFIndex cntx = 0;
-    CFIndex used = (CFIndex)ht->bits.used_buckets, cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-    for (CFIndex idx = (CFIndex)state->state; 0 < used && idx < cnt && cntx < (CFIndex)count; idx++) {
-        CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
-        if (0 < bkt.count) {
-            state->itemsPtr[cntx++] = (unsigned long)bkt.weak_key;
-            used--;
-        }
-        state->state++;
-    }
-    return cntx;
-}
-
-#if ENABLE_MEMORY_COUNTERS
-static volatile int64_t __CFBasicHashTotalCount = 0ULL;
-static volatile int64_t __CFBasicHashTotalSize = 0ULL;
-static volatile int64_t __CFBasicHashPeakCount = 0ULL;
-static volatile int64_t __CFBasicHashPeakSize = 0ULL;
-static volatile int32_t __CFBasicHashSizes[64] = {0};
-#endif
-
-static void __CFBasicHashDrain(CFBasicHashRef ht, Boolean forFinalization) {
-#if ENABLE_MEMORY_COUNTERS
-    OSAtomicAdd64Barrier(-1 * (int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-#endif
-
-    CFIndex old_num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-
-    CFAllocatorRef allocator = CFGetAllocator(ht);
-    Boolean nullify = (!forFinalization || !CF_IS_COLLECTABLE_ALLOCATOR(allocator));
-
-    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
-    void *old_counts = NULL;
-    uintptr_t *old_hashes = NULL;
-
-    old_values = __CFBasicHashGetValues(ht);
-    if (nullify) __CFBasicHashSetValues(ht, NULL);
-    if (ht->bits.keys_offset) {
-        old_keys = __CFBasicHashGetKeys(ht);
-        if (nullify) __CFBasicHashSetKeys(ht, NULL);
-    }
-    if (ht->bits.counts_offset) {
-        old_counts = __CFBasicHashGetCounts(ht);
-        if (nullify) __CFBasicHashSetCounts(ht, NULL);
-    }
-    if (__CFBasicHashHasHashCache(ht)) {
-        old_hashes = __CFBasicHashGetHashes(ht);
-        if (nullify) __CFBasicHashSetHashes(ht, NULL);
-    }
-
-    if (nullify) {
-        ht->bits.mutations++;
-        ht->bits.num_buckets_idx = 0;
-        ht->bits.used_buckets = 0;
-        ht->bits.deleted = 0;
-    }
-    
-        for (CFIndex idx = 0; idx < old_num_buckets; idx++) {
-            uintptr_t stack_value = old_values[idx].neutral;
-            if (stack_value != 0UL && stack_value != ~0UL) {
-                uintptr_t old_value = stack_value;
-                if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
-                if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
-                __CFBasicHashEjectValue(ht, old_value);
-                if (old_keys) {
-                    uintptr_t old_key = old_keys[idx].neutral;
-                    if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
-                    if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
-                    __CFBasicHashEjectKey(ht, old_key);
-                }
-            }
-        }
-
-    if (forFinalization) {
-        ht->callbacks->freeCallbacks(ht, allocator, ht->callbacks);
-    }
-
-    if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        CFAllocatorDeallocate(allocator, old_values);
-        CFAllocatorDeallocate(allocator, old_keys);
-        CFAllocatorDeallocate(allocator, old_counts);
-        CFAllocatorDeallocate(allocator, old_hashes);
-    }
-
-#if ENABLE_MEMORY_COUNTERS
-    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
-#endif
-}
-
-static void __CFBasicHashRehash(CFBasicHashRef ht, CFIndex newItemCount) {
-#if ENABLE_MEMORY_COUNTERS
-    OSAtomicAdd64Barrier(-1 * (int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-    OSAtomicAdd32Barrier(-1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-
-    if (COCOA_HASHTABLE_REHASH_START_ENABLED()) COCOA_HASHTABLE_REHASH_START(ht, CFBasicHashGetNumBuckets(ht), CFBasicHashGetSize(ht, true));
-
-    CFIndex new_num_buckets_idx = ht->bits.num_buckets_idx;
-    if (0 != newItemCount) {
-        if (newItemCount < 0) newItemCount = 0;
-        CFIndex new_capacity_req = ht->bits.used_buckets + newItemCount;
-        new_num_buckets_idx = __CFBasicHashGetNumBucketsIndexForCapacity(ht, new_capacity_req);
-        if (1 == newItemCount && ht->bits.fast_grow) {
-            new_num_buckets_idx++;
-        }
-    }
-
-    CFIndex new_num_buckets = __CFBasicHashTableSizes[new_num_buckets_idx];
-    CFIndex old_num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-
-    CFBasicHashValue *new_values = NULL, *new_keys = NULL;
-    void *new_counts = NULL;
-    uintptr_t *new_hashes = NULL;
-
-    if (0 < new_num_buckets) {
-        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), __CFBasicHashHasCompactableValues(ht));
-        __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));
-            __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)");
-            memset(new_keys, 0, new_num_buckets * sizeof(CFBasicHashValue));
-        }
-        if (ht->bits.counts_offset) {
-            new_counts = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, (1 << ht->bits.counts_width), false, false);
-            __SetLastAllocationEventName(new_counts, "CFBasicHash (count-store)");
-            memset(new_counts, 0, new_num_buckets * (1 << ht->bits.counts_width));
-        }
-        if (__CFBasicHashHasHashCache(ht)) {
-            new_hashes = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(uintptr_t), false, false);
-            __SetLastAllocationEventName(new_hashes, "CFBasicHash (hash-store)");
-            memset(new_hashes, 0, new_num_buckets * sizeof(uintptr_t));
-        }
-    }
-
-    ht->bits.num_buckets_idx = new_num_buckets_idx;
-    ht->bits.deleted = 0;
-
-    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
-    void *old_counts = NULL;
-    uintptr_t *old_hashes = NULL;
-
-    old_values = __CFBasicHashGetValues(ht);
-    __CFBasicHashSetValues(ht, new_values);
-    if (ht->bits.keys_offset) {
-        old_keys = __CFBasicHashGetKeys(ht);
-        __CFBasicHashSetKeys(ht, new_keys);
-    }
-    if (ht->bits.counts_offset) {
-        old_counts = __CFBasicHashGetCounts(ht);
-        __CFBasicHashSetCounts(ht, new_counts);
-    }
-    if (__CFBasicHashHasHashCache(ht)) {
-        old_hashes = __CFBasicHashGetHashes(ht);
-        __CFBasicHashSetHashes(ht, new_hashes);
-    }
-
-    if (0 < old_num_buckets) {
-        for (CFIndex idx = 0; idx < old_num_buckets; idx++) {
-            uintptr_t stack_value = old_values[idx].neutral;
-            if (stack_value != 0UL && stack_value != ~0UL) {
-                if (__CFBasicHashSubABZero == stack_value) stack_value = 0UL;
-                if (__CFBasicHashSubABOne == stack_value) stack_value = ~0UL;
-                uintptr_t stack_key = stack_value;
-                if (ht->bits.keys_offset) {
-                    stack_key = old_keys[idx].neutral;
-                    if (__CFBasicHashSubABZero == stack_key) stack_key = 0UL;
-                    if (__CFBasicHashSubABOne == stack_key) stack_key = ~0UL;
-                }
-                if (ht->bits.indirect_keys) {
-                    stack_key = ht->callbacks->getIndirectKey(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);
-                if (old_keys) {
-                    __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
-                }
-                if (old_counts) {
-                    switch (ht->bits.counts_width) {
-                    case 0: ((uint8_t *)new_counts)[bkt_idx] = ((uint8_t *)old_counts)[idx]; break;
-                    case 1: ((uint16_t *)new_counts)[bkt_idx] = ((uint16_t *)old_counts)[idx]; break;
-                    case 2: ((uint32_t *)new_counts)[bkt_idx] = ((uint32_t *)old_counts)[idx]; break;
-                    case 3: ((uint64_t *)new_counts)[bkt_idx] = ((uint64_t *)old_counts)[idx]; break;
-                    }
-                }
-                if (old_hashes) {
-                    new_hashes[bkt_idx] = old_hashes[idx];
-                }
-            }
-        }
-    }
-
-    CFAllocatorRef allocator = CFGetAllocator(ht);
-    if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        CFAllocatorDeallocate(allocator, old_values);
-        CFAllocatorDeallocate(allocator, old_keys);
-        CFAllocatorDeallocate(allocator, old_counts);
-        CFAllocatorDeallocate(allocator, old_hashes);
-    }
-
-    if (COCOA_HASHTABLE_REHASH_END_ENABLED()) COCOA_HASHTABLE_REHASH_END(ht, CFBasicHashGetNumBuckets(ht), CFBasicHashGetSize(ht, true));
-
-#if ENABLE_MEMORY_COUNTERS
-    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), &__CFBasicHashTotalSize);
-    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
-    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-}
-
-__private_extern__ void CFBasicHashSetCapacity(CFBasicHashRef ht, CFIndex capacity) {
-    if (!CFBasicHashIsMutable(ht)) HALT;
-    if (ht->bits.used_buckets < capacity) {
-        ht->bits.mutations++;
-        __CFBasicHashRehash(ht, capacity - ht->bits.used_buckets);
-    }
-}
-
-static void __CFBasicHashAddValue(CFBasicHashRef ht, CFIndex bkt_idx, uintptr_t stack_key, uintptr_t stack_value) {
-    ht->bits.mutations++;
-    if (CFBasicHashGetCapacity(ht) < ht->bits.used_buckets + 1) {
-        __CFBasicHashRehash(ht, 1);
-        bkt_idx = __CFBasicHashFindBucket_NoCollision(ht, stack_key, 0);
-    } else if (__CFBasicHashIsDeleted(ht, bkt_idx)) {
-        ht->bits.deleted--;
-    }
-    uintptr_t key_hash = 0;
-    if (__CFBasicHashHasHashCache(ht)) {
-        key_hash = __CFBasicHashHashKey(ht, stack_key);
-    }
-    stack_value = __CFBasicHashImportValue(ht, stack_value);
-    if (ht->bits.keys_offset) {
-        stack_key = __CFBasicHashImportKey(ht, stack_key);
-    }
-    __CFBasicHashSetValue(ht, bkt_idx, stack_value, false, false);
-    if (ht->bits.keys_offset) {
-        __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
-    }
-    if (ht->bits.counts_offset) {
-        __CFBasicHashIncSlotCount(ht, bkt_idx);
-    }
-    if (__CFBasicHashHasHashCache(ht)) {
-        __CFBasicHashGetHashes(ht)[bkt_idx] = key_hash;
-    }
-    ht->bits.used_buckets++;
-}
-
-static void __CFBasicHashReplaceValue(CFBasicHashRef ht, CFIndex bkt_idx, uintptr_t stack_key, uintptr_t stack_value) {
-    ht->bits.mutations++;
-    stack_value = __CFBasicHashImportValue(ht, stack_value);
-    if (ht->bits.keys_offset) {
-        stack_key = __CFBasicHashImportKey(ht, stack_key);
-    }
-    __CFBasicHashSetValue(ht, bkt_idx, stack_value, false, false);
-    if (ht->bits.keys_offset) {
-        __CFBasicHashSetKey(ht, bkt_idx, stack_key, false, false);
-    }
-}
-
-static void __CFBasicHashRemoveValue(CFBasicHashRef ht, CFIndex bkt_idx) {
-    ht->bits.mutations++;
-    __CFBasicHashSetValue(ht, bkt_idx, ~0UL, false, true);
-    if (ht->bits.keys_offset) {
-        __CFBasicHashSetKey(ht, bkt_idx, ~0UL, false, true);
-    }
-    if (ht->bits.counts_offset) {
-        __CFBasicHashDecSlotCount(ht, bkt_idx);
-    }
-    if (__CFBasicHashHasHashCache(ht)) {
-        __CFBasicHashGetHashes(ht)[bkt_idx] = 0;
-    }
-    ht->bits.used_buckets--;
-    ht->bits.deleted++;
-    Boolean do_shrink = false;
-    if (ht->bits.fast_grow) { // == slow shrink
-        do_shrink = (5 < ht->bits.num_buckets_idx && ht->bits.used_buckets < __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx - 5));
-    } else {
-        do_shrink = (2 < ht->bits.num_buckets_idx && ht->bits.used_buckets < __CFBasicHashGetCapacityForNumBuckets(ht, ht->bits.num_buckets_idx - 2));
-    }
-    if (do_shrink) {
-        __CFBasicHashRehash(ht, -1);
-        return;
-    }
-    do_shrink = (0 == ht->bits.deleted); // .deleted roll-over
-    CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-    do_shrink = do_shrink || ((20 <= num_buckets) && (num_buckets / 4 <= ht->bits.deleted));
-    if (do_shrink) {
-        __CFBasicHashRehash(ht, 0);
-    }
-}
-
-__private_extern__ 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;
-    if (__CFBasicHashSubABZero == stack_value) HALT;
-    if (__CFBasicHashSubABOne == stack_value) HALT;
-    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
-    if (0 < bkt.count) {
-        ht->bits.mutations++;
-        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not yet as large as a CFIndex can be... otherwise clamp and do nothing
-            __CFBasicHashIncSlotCount(ht, bkt.idx);
-            return true;
-        }
-    } else {
-        __CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
-        return true;
-    }
-    return false;
-}
-
-__private_extern__ 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;
-    if (__CFBasicHashSubABZero == stack_value) HALT;
-    if (__CFBasicHashSubABOne == stack_value) HALT;
-    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
-    if (0 < bkt.count) {
-        __CFBasicHashReplaceValue(ht, bkt.idx, stack_key, stack_value);
-    }
-}
-
-__private_extern__ 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;
-    if (__CFBasicHashSubABZero == stack_value) HALT;
-    if (__CFBasicHashSubABOne == stack_value) HALT;
-    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
-    if (0 < bkt.count) {
-        __CFBasicHashReplaceValue(ht, bkt.idx, stack_key, stack_value);
-    } else {
-        __CFBasicHashAddValue(ht, bkt.idx, stack_key, stack_value);
-    }
-}
-
-__private_extern__ 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);
-    if (1 < bkt.count) {
-        ht->bits.mutations++;
-        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not as large as a CFIndex can be... otherwise clamp and do nothing
-            __CFBasicHashDecSlotCount(ht, bkt.idx);
-        }
-    } else if (0 < bkt.count) {
-        __CFBasicHashRemoveValue(ht, bkt.idx);
-    }
-    return bkt.count;
-}
-
-__private_extern__ CFIndex CFBasicHashRemoveValueAtIndex(CFBasicHashRef ht, CFIndex idx) {
-    if (!CFBasicHashIsMutable(ht)) HALT;
-    CFBasicHashBucket bkt = CFBasicHashGetBucket(ht, idx);
-    if (1 < bkt.count) {
-        ht->bits.mutations++;
-        if (ht->bits.counts_offset && bkt.count < LONG_MAX) { // if not as large as a CFIndex can be... otherwise clamp and do nothing
-            __CFBasicHashDecSlotCount(ht, bkt.idx);
-        }
-    } else if (0 < bkt.count) {
-        __CFBasicHashRemoveValue(ht, bkt.idx);
-    }
-    return bkt.count;
-}
-
-__private_extern__ 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) {
-    if (!CFBasicHashIsMutable(ht)) HALT;
-    if (__CFBasicHashSubABZero == stack_key) HALT;
-    if (__CFBasicHashSubABOne == stack_key) HALT;
-    if (__CFBasicHashSubABZero == int_value) HALT;
-    if (__CFBasicHashSubABOne == int_value) HALT;
-    CFBasicHashBucket bkt = __CFBasicHashFindBucket(ht, stack_key);
-    if (0 < bkt.count) {
-        ht->bits.mutations++;
-    } else {
-        // must rehash before renumbering
-        if (CFBasicHashGetCapacity(ht) < ht->bits.used_buckets + 1) {
-            __CFBasicHashRehash(ht, 1);
-            bkt.idx = __CFBasicHashFindBucket_NoCollision(ht, stack_key, 0);
-        }
-        CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        for (CFIndex idx = 0; idx < cnt; idx++) {
-            if (!__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
-                uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
-                if (int_value <= stack_value) {
-                    stack_value++;
-                    __CFBasicHashSetValue(ht, idx, stack_value, true, false);
-                    ht->bits.mutations++;
-                }
-            }
-        }
-        __CFBasicHashAddValue(ht, bkt.idx, stack_key, int_value);
-        return true;
-    }
-    return false;
-}
-
-void CFBasicHashRemoveIntValueAndDec(CFBasicHashRef ht, uintptr_t int_value) {
-    if (!CFBasicHashIsMutable(ht)) HALT;
-    if (__CFBasicHashSubABZero == int_value) HALT;
-    if (__CFBasicHashSubABOne == int_value) HALT;
-    uintptr_t bkt_idx = ~0UL;
-    CFIndex cnt = (CFIndex)__CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-    for (CFIndex idx = 0; idx < cnt; idx++) {
-        if (!__CFBasicHashIsEmptyOrDeleted(ht, idx)) {
-            uintptr_t stack_value = __CFBasicHashGetValue(ht, idx);
-            if (int_value == stack_value) {
-                bkt_idx = idx;
-            }
-            if (int_value < stack_value) {
-                stack_value--;
-                __CFBasicHashSetValue(ht, idx, stack_value, true, false);
-                ht->bits.mutations++;
-            }
-        }
-    }
-    __CFBasicHashRemoveValue(ht, bkt_idx);
-}
-
-__private_extern__ 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 *);
-    if (__CFBasicHashHasHashCache(ht)) size += sizeof(uintptr_t *);
-    if (total) {
-        CFIndex num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-        if (0 < num_buckets) {
-            size += malloc_size(__CFBasicHashGetValues(ht));
-            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) {
-    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("%@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("%@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);
-    CFBasicHashApply(ht, ^(CFBasicHashBucket bkt) {
-            CFStringRef vDesc = NULL, kDesc = NULL;
-            if (!describeElements) {
-                vDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)bkt.weak_value);
-                if (ht->bits.keys_offset) {
-                    kDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)bkt.weak_key);
-                }
-            } else {
-                vDesc = ht->callbacks->copyValueDescription(ht, bkt.weak_value);
-                if (ht->bits.keys_offset) {
-                    kDesc = ht->callbacks->copyKeyDescription(ht, bkt.weak_key);
-                }
-            }
-            if (ht->bits.keys_offset && ht->bits.counts_offset) {
-                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ = %@ (%ld)\n"), entryPrefix, bkt.idx, kDesc, vDesc, bkt.count);
-            } else if (ht->bits.keys_offset) {
-                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ = %@\n"), entryPrefix, bkt.idx, kDesc, vDesc);
-            } else if (ht->bits.counts_offset) {
-                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@ (%ld)\n"), entryPrefix, bkt.idx, vDesc, bkt.count);
-            } else {
-                CFStringAppendFormat(result, NULL, CFSTR("%@%ld : %@\n"), entryPrefix, bkt.idx, vDesc);
-            }
-            if (kDesc) CFRelease(kDesc);
-            if (vDesc) CFRelease(vDesc);
-            return (Boolean)true;
-        });
-    CFStringAppendFormat(result, NULL, CFSTR("%@}\n"), prefix);
-    return result;
-}
-
-__private_extern__ 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) {
-    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) {
-    CFBasicHashRef ht = (CFBasicHashRef)cf;
-    return CFBasicHashGetCount(ht);
-}
-
-__private_extern__ 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);
-    CFRelease(desc);
-    return result;
-}
-
-__private_extern__ void __CFBasicHashDeallocate(CFTypeRef cf) {
-    CFBasicHashRef ht = (CFBasicHashRef)cf;
-    if (ht->bits.finalized) HALT;
-    ht->bits.finalized = 1;
-    __CFBasicHashDrain(ht, true);
-#if ENABLE_MEMORY_COUNTERS
-    OSAtomicAdd64Barrier(-1, &__CFBasicHashTotalCount);
-    OSAtomicAdd32Barrier(-1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-}
-
-static CFTypeID __kCFBasicHashTypeID = _kCFRuntimeNotATypeID;
-
-static const CFRuntimeClass __CFBasicHashClass = {
-    _kCFRuntimeScannedObject,
-    "CFBasicHash",
-    NULL,        // init
-    NULL,        // copy
-    __CFBasicHashDeallocate,
-    __CFBasicHashEqual,
-    __CFBasicHashHash,
-    NULL,        //
-    __CFBasicHashCopyDescription
-};
-
-__private_extern__ CFTypeID CFBasicHashGetTypeID(void) {
-    if (_kCFRuntimeNotATypeID == __kCFBasicHashTypeID) __kCFBasicHashTypeID = _CFRuntimeRegisterClass(&__CFBasicHashClass);
-    return __kCFBasicHashTypeID;
-}
-
-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
-    if (flags & kCFBasicHashHasHashCache) size += sizeof(uintptr_t *); // hashes
-    CFBasicHashRef ht = (CFBasicHashRef)_CFRuntimeCreateInstance(allocator, CFBasicHashGetTypeID(), size, NULL);
-    if (NULL == ht) HALT;
-
-    ht->bits.finalized = 0;
-    ht->bits.hash_style = (flags >> 13) & 0x3;
-    ht->bits.fast_grow = (flags & kCFBasicHashAggressiveGrowth) ? 1 : 0;
-    ht->bits.counts_width = 0;
-    ht->bits.strong_values = (flags & kCFBasicHashStrongValues) ? 1 : 0;
-    ht->bits.strong_keys = (flags & kCFBasicHashStrongKeys) ? 1 : 0;
-    ht->bits.weak_values = (flags & kCFBasicHashWeakValues) ? 1 : 0;
-    ht->bits.weak_keys = (flags & kCFBasicHashWeakKeys) ? 1 : 0;
-    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;
-    ht->bits.mutations = 1;
-
-    if (ht->bits.strong_values && ht->bits.weak_values) HALT;
-    if (ht->bits.strong_values && ht->bits.int_values) HALT;
-    if (ht->bits.strong_keys && ht->bits.weak_keys) HALT;
-    if (ht->bits.strong_keys && ht->bits.int_keys) HALT;
-    if (ht->bits.weak_values && ht->bits.int_values) HALT;
-    if (ht->bits.weak_keys && ht->bits.int_keys) HALT;
-    if (ht->bits.indirect_keys && ht->bits.strong_keys) HALT;
-    if (ht->bits.indirect_keys && ht->bits.weak_keys) HALT;
-    if (ht->bits.indirect_keys && ht->bits.int_keys) HALT;
-
-    uint64_t offset = 1;
-    ht->bits.keys_offset = (flags & kCFBasicHashHasKeys) ? offset++ : 0;
-    ht->bits.counts_offset = (flags & kCFBasicHashHasCounts) ? offset++ : 0;
-    ht->bits.hashes_offset = (flags & kCFBasicHashHasHashCache) ? offset++ : 0;
-
-#if defined(__arm__)
-    ht->bits.hashes_offset = 0;
-    ht->bits.strong_values = 0;
-    ht->bits.strong_keys = 0;
-    ht->bits.weak_values = 0;
-    ht->bits.weak_keys = 0;
-#endif
-
-    __AssignWithWriteBarrier(&ht->callbacks, cb);
-    for (CFIndex idx = 0; idx < offset; idx++) {
-        ht->pointers[idx] = NULL;
-    }
-
-#if ENABLE_MEMORY_COUNTERS
-    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
-    int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
-    while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
-    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-
-    return ht;
-}
-
-CFBasicHashRef CFBasicHashCreateCopy(CFAllocatorRef allocator, CFConstBasicHashRef src_ht) {
-    size_t size = CFBasicHashGetSize(src_ht, false) - sizeof(CFRuntimeBase);
-    CFBasicHashRef ht = (CFBasicHashRef)_CFRuntimeCreateInstance(allocator, CFBasicHashGetTypeID(), size, NULL);
-    if (NULL == ht) HALT;
-
-    memmove((uint8_t *)ht + sizeof(CFRuntimeBase), (uint8_t *)src_ht + sizeof(CFRuntimeBase), sizeof(ht->bits));
-    if (kCFUseCollectableAllocator && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
-        ht->bits.strong_values = 0;
-        ht->bits.strong_keys = 0;
-        ht->bits.weak_values = 0;
-        ht->bits.weak_keys = 0;
-    }
-    ht->bits.finalized = 0;
-    ht->bits.mutations = 1;
-    CFBasicHashCallbacks *newcb = src_ht->callbacks->copyCallbacks(src_ht, allocator, src_ht->callbacks);
-    if (NULL == newcb) HALT;
-    __AssignWithWriteBarrier(&ht->callbacks, newcb);
-
-    CFIndex new_num_buckets = __CFBasicHashTableSizes[ht->bits.num_buckets_idx];
-    if (0 == new_num_buckets) {
-#if ENABLE_MEMORY_COUNTERS
-        int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-        while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
-        int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
-        while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
-        OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-        return ht;
-    }
-
-    CFBasicHashValue *new_values = NULL, *new_keys = NULL;
-    void *new_counts = NULL;
-    uintptr_t *new_hashes = NULL;
-
-    if (0 < new_num_buckets) {
-        new_values = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongValues(ht), __CFBasicHashHasCompactableValues(ht));
-        __SetLastAllocationEventName(new_values, "CFBasicHash (value-store)");
-        if (ht->bits.keys_offset) {
-            new_keys = (CFBasicHashValue *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(CFBasicHashValue), CFBasicHashHasStrongKeys(ht), false);
-            __SetLastAllocationEventName(new_keys, "CFBasicHash (key-store)");
-        }
-        if (ht->bits.counts_offset) {
-            new_counts = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, (1 << ht->bits.counts_width), false, false);
-            __SetLastAllocationEventName(new_counts, "CFBasicHash (count-store)");
-        }
-        if (__CFBasicHashHasHashCache(ht)) {
-            new_hashes = (uintptr_t *)__CFBasicHashAllocateMemory(ht, new_num_buckets, sizeof(uintptr_t), false, false);
-            __SetLastAllocationEventName(new_hashes, "CFBasicHash (hash-store)");
-        }
-    }
-
-    CFBasicHashValue *old_values = NULL, *old_keys = NULL;
-    void *old_counts = NULL;
-    uintptr_t *old_hashes = NULL;
-
-    old_values = __CFBasicHashGetValues(src_ht);
-    if (src_ht->bits.keys_offset) {
-        old_keys = __CFBasicHashGetKeys(src_ht);
-    }
-    if (src_ht->bits.counts_offset) {
-        old_counts = __CFBasicHashGetCounts(src_ht);
-    }
-    if (__CFBasicHashHasHashCache(src_ht)) {
-        old_hashes = __CFBasicHashGetHashes(src_ht);
-    }
-
-    __CFBasicHashSetValues(ht, new_values);
-    if (new_keys) {
-        __CFBasicHashSetKeys(ht, new_keys);
-    }
-    if (new_counts) {
-        __CFBasicHashSetCounts(ht, new_counts);
-    }
-    if (new_hashes) {
-        __CFBasicHashSetHashes(ht, new_hashes);
-    }
-
-    for (CFIndex idx = 0; idx < new_num_buckets; idx++) {
-        uintptr_t stack_value = old_values[idx].neutral;
-        if (stack_value != 0UL && stack_value != ~0UL) {
-            uintptr_t old_value = stack_value;
-            if (__CFBasicHashSubABZero == old_value) old_value = 0UL;
-            if (__CFBasicHashSubABOne == old_value) old_value = ~0UL;
-            __CFBasicHashSetValue(ht, idx, __CFBasicHashImportValue(ht, old_value), true, false);
-            if (new_keys) {
-                uintptr_t old_key = old_keys[idx].neutral;
-                if (__CFBasicHashSubABZero == old_key) old_key = 0UL;
-                if (__CFBasicHashSubABOne == old_key) old_key = ~0UL;
-                __CFBasicHashSetKey(ht, idx, __CFBasicHashImportKey(ht, old_key), true, false);
-            }
-        } else {
-            __CFBasicHashSetValue(ht, idx, stack_value, true, true);
-            if (new_keys) {
-                __CFBasicHashSetKey(ht, idx, stack_value, true, true);
-            }
-        }
-    }
-    if (new_counts) memmove(new_counts, old_counts, new_num_buckets * (1 << ht->bits.counts_width));
-    if (new_hashes) memmove(new_hashes, old_hashes, new_num_buckets * sizeof(uintptr_t));
-
-#if ENABLE_MEMORY_COUNTERS
-    int64_t size_now = OSAtomicAdd64Barrier((int64_t) CFBasicHashGetSize(ht, true), & __CFBasicHashTotalSize);
-    while (__CFBasicHashPeakSize < size_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakSize, size_now, & __CFBasicHashPeakSize));
-    int64_t count_now = OSAtomicAdd64Barrier(1, & __CFBasicHashTotalCount);
-    while (__CFBasicHashPeakCount < count_now && !OSAtomicCompareAndSwap64Barrier(__CFBasicHashPeakCount, count_now, & __CFBasicHashPeakCount));
-    OSAtomicAdd32Barrier(1, &__CFBasicHashSizes[ht->bits.num_buckets_idx]);
-#endif
-
-    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 ecd4e2b7b01d5779bb90f09cca1b4804797970ba..ccbcb69431e26d35ae6f73b91b36e41a8274eaca 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBasicHashFindBucket.m
-       Copyright (c) 2009-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2009-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
diff --git a/CFBigNumber.c b/CFBigNumber.c
new file mode 100644 (file)
index 0000000..62ea129
--- /dev/null
@@ -0,0 +1,564 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*     CFBigNumber.c
+       Copyright (c) 2012-2012, Apple Inc. All rights reserved.
+       Responsibility: Christopher Kane
+       Original author: Zhi Feng Huang
+*/
+
+#include <CoreFoundation/CFBigNumber.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include "CFInternal.h"
+
+
+#define kCFNumberSInt128Type 17
+
+#if __LP64__
+
+#ifndef _INT128_T
+#define _INT128_T
+typedef __int128_t  int128_t;
+#endif
+
+#ifndef _UINT128_T
+#define _UINT128_T
+typedef __uint128_t uint128_t;
+#endif
+
+#ifndef INT128_MIN
+#define INT128_MIN  ((__int128_t)0 - ((__int128_t)1 << 126) - ((__int128_t)1 << 126))
+#endif
+
+#ifndef INT128_MAX
+#define INT128_MAX  ((__int128_t)-1 + ((__int128_t)1 << 126) + ((__int128_t)1 << 126))
+#endif
+
+#ifndef UINT128_MAX
+#define UINT128_MAX (((__uint128_t)1 << 127) - (__uint128_t)1 + ((__uint128_t)1 << 127))
+#endif
+
+#endif
+
+
+#define BIG_DIGITS_LIMIT    1000000000L
+#define BIG_DIGITS_LIMIT_2  ((uint64_t)BIG_DIGITS_LIMIT * (uint64_t)BIG_DIGITS_LIMIT)
+#define BIG_DIGITS_LIMIT_3  ((__uint128_t)BIG_DIGITS_LIMIT_2 * (__uint128_t)BIG_DIGITS_LIMIT)
+#define BIG_DIGITS_LIMIT_4  ((__uint128_t)BIG_DIGITS_LIMIT_3 * (__uint128_t)BIG_DIGITS_LIMIT)
+
+#define GET_FIFTH_DIGIT(A)  (A / BIG_DIGITS_LIMIT_4)
+#define GET_FOURTH_DIGIT(A) (A / BIG_DIGITS_LIMIT_3)
+#define GET_THIRD_DIGIT(A)  (A / BIG_DIGITS_LIMIT_2)
+#define GET_SECOND_DIGIT(A) (A / BIG_DIGITS_LIMIT)
+
+#define GET_REMAINDER_FIFTH_DIGIT(A,B)  (A - B * BIG_DIGITS_LIMIT_4)
+#define GET_REMAINDER_FOURTH_DIGIT(A,B) (A - B * BIG_DIGITS_LIMIT_3)
+#define GET_REMAINDER_THIRD_DIGIT(A,B)  (A - B * BIG_DIGITS_LIMIT_2)
+#define GET_REMAINDER_SECOND_DIGIT(A,B) (A - B * BIG_DIGITS_LIMIT)
+
+
+void _CFBigNumInitWithInt8(_CFBigNum *r, int8_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint8_t unsignInNum = inNum;
+    if (inNum < 0) {
+        r->sign = -1;
+        unsignInNum = -1 * inNum;
+    }
+    r->digits[0] = unsignInNum;
+}
+
+void _CFBigNumInitWithInt16(_CFBigNum *r, int16_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint16_t unsignInNum = inNum;
+    if (inNum < 0) {
+        r->sign = -1;
+        unsignInNum = -1 * inNum;
+    }
+    r->digits[0] = unsignInNum;
+}
+
+void _CFBigNumInitWithInt32(_CFBigNum *r, int32_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint32_t unsignInNum = inNum;
+    if (inNum < 0) {
+        r->sign = -1;
+        unsignInNum = -1 * inNum;
+    }
+    uint32_t dig0 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, dig0);
+    r->digits[1] = dig0;
+}
+
+void _CFBigNumInitWithInt64(_CFBigNum *r, int64_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint64_t unsignInNum = inNum;
+    if (inNum < 0) {
+        r->sign = -1;
+        unsignInNum = -1 * inNum;
+    }
+    uint32_t dig2 = GET_THIRD_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_THIRD_DIGIT(unsignInNum, (uint64_t)dig2);
+    uint32_t dig1 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, (uint64_t)dig1);
+    r->digits[1] = dig1;
+    r->digits[2] = dig2;
+}
+
+#ifdef __LP64__
+void _CFBigNumInitWithInt128(_CFBigNum *r, __int128_t inNum) {
+    memset(r, 0, sizeof(*r));
+    __uint128_t unsignInNum = inNum;
+    if (inNum < 0) {
+        r->sign = -1;
+        unsignInNum = -1 * inNum;
+    }
+    uint32_t dig4 = GET_FIFTH_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_FIFTH_DIGIT(unsignInNum, (__uint128_t)dig4);
+    uint32_t dig3 = GET_FOURTH_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_FOURTH_DIGIT(unsignInNum, (__uint128_t)dig3);
+    uint32_t dig2 = GET_THIRD_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_THIRD_DIGIT(unsignInNum, (__uint128_t)dig2);
+    uint32_t dig1 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, (__uint128_t)dig1);
+    r->digits[1] = dig1;
+    r->digits[2] = dig2;
+    r->digits[3] = dig3;
+    r->digits[4] = dig4;
+}
+#endif
+
+void _CFBigNumInitWithUInt8(_CFBigNum *r, uint8_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint8_t unsignInNum = inNum;
+    r->digits[0] = unsignInNum;
+}
+
+void _CFBigNumInitWithUInt16(_CFBigNum *r, uint16_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint16_t unsignInNum = inNum;
+    r->digits[0] = unsignInNum;
+}
+
+void _CFBigNumInitWithUInt32(_CFBigNum *r, uint32_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint32_t unsignInNum = inNum;
+    uint32_t dig0 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, dig0);
+    r->digits[1] = dig0;
+}
+
+void _CFBigNumInitWithUInt64(_CFBigNum *r, uint64_t inNum) {
+    memset(r, 0, sizeof(*r));
+    uint64_t unsignInNum = inNum;
+    uint32_t dig2 = GET_THIRD_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_THIRD_DIGIT(unsignInNum, (uint64_t)dig2);
+    uint32_t dig1 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, (uint64_t)dig1);
+    r->digits[1] = dig1;
+    r->digits[2] = dig2;
+}
+
+#ifdef __LP64__
+void _CFBigNumInitWithUInt128(_CFBigNum *r, __uint128_t inNum) {
+    memset(r, 0, sizeof(*r));
+    __uint128_t unsignInNum = inNum;
+    uint32_t dig4 = GET_FIFTH_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_FIFTH_DIGIT(unsignInNum, (__uint128_t)dig4);
+    uint32_t dig3 = GET_FOURTH_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_FOURTH_DIGIT(unsignInNum, (__uint128_t)dig3);
+    uint32_t dig2 = GET_THIRD_DIGIT(unsignInNum);
+    unsignInNum = GET_REMAINDER_THIRD_DIGIT(unsignInNum, (__uint128_t)dig2);
+    uint32_t dig1 = GET_SECOND_DIGIT(unsignInNum);
+    r->digits[0] = GET_REMAINDER_SECOND_DIGIT(unsignInNum, (__uint128_t)dig1);
+    r->digits[1] = dig1;
+    r->digits[2] = dig2;
+    r->digits[3] = dig3;
+    r->digits[4] = dig4;
+}
+#endif
+
+
+int8_t _CFBigNumGetInt8(const _CFBigNum *num) {
+    int8_t result = num->digits[0];
+    if (num->sign < 0) {
+        result = -1 * result;
+    }
+    return result;
+}
+
+int16_t _CFBigNumGetInt16(const _CFBigNum *num) {
+    int16_t result = num->digits[0];
+    if (num->sign < 0) {
+        result = -1 * result;
+    }
+    return result;
+}
+
+int32_t _CFBigNumGetInt32(const _CFBigNum *num) {
+    int32_t result = num->digits[0];
+    result += num->digits[1] * BIG_DIGITS_LIMIT;
+    if (num->sign < 0) {
+        result = -1 * result;
+    }
+    return result;
+}
+
+int64_t _CFBigNumGetInt64(const _CFBigNum *num) {
+    int64_t result = num->digits[0];
+    result += (int64_t)num->digits[1] * BIG_DIGITS_LIMIT;
+    result += (int64_t)num->digits[2] * BIG_DIGITS_LIMIT_2;
+    if (num->sign < 0) {
+        result = -1 * result;
+    }
+    return result;
+}
+
+#if __LP64__
+__int128_t _CFBigNumGetInt128(const _CFBigNum *num) {
+    __int128_t result = num->digits[0];
+    result += (__int128_t)num->digits[1] * BIG_DIGITS_LIMIT;
+    result += (__int128_t)num->digits[2] * BIG_DIGITS_LIMIT_2;
+    result += (__int128_t)num->digits[3] * BIG_DIGITS_LIMIT_3;
+    result += (__int128_t)num->digits[4] * BIG_DIGITS_LIMIT_4;
+    if (num->sign < 0) {
+        result = -1 * result;
+    }
+    return result;
+}
+#endif
+
+uint8_t _CFBigNumGetUInt8(const _CFBigNum *num) {
+    uint8_t result = num->digits[0];
+    return result;
+}
+
+uint16_t _CFBigNumGetUInt16(const _CFBigNum *num) {
+    uint16_t result = num->digits[0];
+    return result;
+}
+
+uint32_t _CFBigNumGetUInt32(const _CFBigNum *num) {
+    uint32_t result = num->digits[0];
+    result += num->digits[1] * BIG_DIGITS_LIMIT;
+    return result;
+}
+
+uint64_t _CFBigNumGetUInt64(const _CFBigNum *num) {
+    uint64_t result = num->digits[0];
+    result += (uint64_t)num->digits[1] * BIG_DIGITS_LIMIT;
+    result += (uint64_t)num->digits[2] * BIG_DIGITS_LIMIT_2;
+    return result;
+}
+
+#if __LP64__
+__uint128_t _CFBigNumGetUInt128(const _CFBigNum *num) {
+    __uint128_t result = num->digits[0];
+    result += (__uint128_t)num->digits[1] * BIG_DIGITS_LIMIT;
+    result += (__uint128_t)num->digits[2] * BIG_DIGITS_LIMIT_2;
+    result += (__uint128_t)num->digits[3] * BIG_DIGITS_LIMIT_3;
+    result += (__uint128_t)num->digits[4] * BIG_DIGITS_LIMIT_4;
+    return result;
+}
+#endif
+
+
+void _CFBigNumInitWithCFNumber(_CFBigNum *r, CFNumberRef inNum) {
+    uint8_t bytes[128];
+    memset(bytes, 0, sizeof(bytes));
+    CFNumberType type = CFNumberGetType(inNum);
+    CFNumberGetValue(inNum, type, (void *)bytes);
+    _CFBigNumInitWithBytes(r, (const void *)bytes, type);
+}
+
+void _CFBigNumInitWithBytes(_CFBigNum *r, const void *bytes, CFNumberType type) {
+    switch (type) {
+    case kCFNumberSInt8Type:
+        _CFBigNumInitWithInt8(r, *(int8_t *)bytes);
+        return;
+    case kCFNumberSInt16Type:
+        _CFBigNumInitWithInt16(r, *(int16_t *)bytes);
+        return;
+    case kCFNumberSInt32Type:
+        _CFBigNumInitWithInt32(r, *(int32_t *)bytes);
+        return;
+    case kCFNumberSInt64Type:
+        _CFBigNumInitWithInt64(r, *(int64_t *)bytes);
+        return;
+    case kCFNumberCharType:
+        _CFBigNumInitWithInt8(r, *(int8_t *)bytes);
+        return;
+    case kCFNumberShortType:
+        _CFBigNumInitWithInt16(r, *(int16_t *)bytes);
+        return;
+    case kCFNumberIntType:
+        _CFBigNumInitWithInt32(r, *(int32_t *)bytes);
+        return;
+    case kCFNumberLongType:
+        if (sizeof(long) == 8) {
+            _CFBigNumInitWithInt64(r, *(int64_t *)bytes);
+        } else {
+            _CFBigNumInitWithInt32(r, *(int32_t *)bytes);
+        }
+        return;
+    case kCFNumberLongLongType:
+        _CFBigNumInitWithInt64(r, *(int64_t *)bytes);
+        return;
+    case kCFNumberCFIndexType:
+        if (sizeof(CFIndex) == 8) {
+            _CFBigNumInitWithInt64(r, *(int64_t *)bytes);
+        } else {
+            _CFBigNumInitWithInt32(r, *(int32_t *)bytes);
+        }
+        return;
+    case kCFNumberNSIntegerType:
+        if (sizeof(long) == 8) { // NSInteger follows long
+            _CFBigNumInitWithInt64(r, *(int64_t *)bytes);
+        } else {
+            _CFBigNumInitWithInt32(r, *(int32_t *)bytes);
+        }
+        return;
+#if __LP64__
+    case kCFNumberSInt128Type:
+        _CFBigNumInitWithInt128(r, *(__int128_t *)bytes);
+        return;
+#endif
+    default:
+        return;
+    }
+}
+
+CFNumberRef _CFNumberCreateWithBigNum(const _CFBigNum *input) {
+    if (0 == input->digits[4] && 0 == input->digits[3] && 0 == input->digits[2] && 0 == input->digits[1]) {
+        // This bumps up the size of the most negative n-bit value to the next larger size; oh well
+        if (input->digits[0] <= INT8_MAX) {
+            int8_t num = _CFBigNumGetInt8(input);
+            CFNumberRef result = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt8Type, (const void *)&num);
+            return result;
+        } else if (input->digits[0] <= INT16_MAX) {
+            int16_t num = _CFBigNumGetInt16(input);
+            CFNumberRef result = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt16Type, (const void *)&num);
+            return result;
+        }
+    }    
+    _CFBigNum maxlimit, minlimit;
+    if (0 == input->digits[4] && 0 == input->digits[3] && 0 == input->digits[2]) {
+        _CFBigNumInitWithInt32(&maxlimit, INT32_MAX);
+        _CFBigNumInitWithInt32(&minlimit, INT32_MIN);
+        CFComparisonResult cr = _CFBigNumCompare(input, &maxlimit);
+        CFComparisonResult crn = _CFBigNumCompare(input, &minlimit);
+        if ((kCFCompareLessThan == cr || kCFCompareEqualTo == cr) && (kCFCompareLessThan != crn)) {
+            int32_t num = _CFBigNumGetInt32(input);
+            CFNumberRef result = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt32Type, (const void *)&num);
+            return result;
+        }
+    }
+    if (0 == input->digits[4] && 0 == input->digits[3]) {
+        _CFBigNumInitWithInt64(&maxlimit, INT64_MAX);
+        _CFBigNumInitWithInt64(&minlimit, INT64_MIN);
+        CFComparisonResult cr = _CFBigNumCompare(input, &maxlimit);
+        CFComparisonResult crn = _CFBigNumCompare(input, &minlimit);
+        if ((kCFCompareLessThan == cr || kCFCompareEqualTo == cr) && (kCFCompareLessThan != crn)) {
+            int64_t num = _CFBigNumGetInt64(input);
+            CFNumberRef result = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt64Type, (const void *)&num);
+            return result;
+        }
+    }
+#if __LP64__
+    _CFBigNumInitWithInt128(&maxlimit, INT128_MAX);
+    _CFBigNumInitWithInt128(&minlimit, INT128_MIN);
+    CFComparisonResult cr = _CFBigNumCompare(input, &maxlimit);
+    CFComparisonResult crn = _CFBigNumCompare(input, &minlimit);
+    if ((kCFCompareLessThan == cr || kCFCompareEqualTo == cr) && (kCFCompareLessThan != crn)) {
+        __int128_t num = _CFBigNumGetInt128(input);
+        CFNumberRef result = CFNumberCreate(kCFAllocatorSystemDefault, kCFNumberSInt128Type, (const void *)&num);
+        return result;
+    }
+#endif
+    return NULL;
+}
+
+CFComparisonResult _CFBigNumCompare(const _CFBigNum *a, const _CFBigNum *b) {
+    Boolean sameSign = a->sign == b->sign;
+    if (sameSign) {
+        Boolean negative = a->sign < 0;
+        for (CFIndex i = sizeof(a->digits) / sizeof(a->digits[0]); i--;) {
+            if (a->digits[i] < b->digits[i]) {
+                return !negative ? kCFCompareLessThan : kCFCompareGreaterThan;
+            }
+            if (a->digits[i] > b->digits[i]) {
+                return negative ? kCFCompareLessThan : kCFCompareGreaterThan;
+            }
+        }
+        return kCFCompareEqualTo;
+    }
+    return (a->sign < b->sign) ? kCFCompareLessThan : kCFCompareGreaterThan;
+}
+
+// abs(a) < abs(b)
+// do not care about the sign
+static Boolean _CFBigNumAbsoluteLessThan(const _CFBigNum *a, const _CFBigNum *b) {
+    for (CFIndex i = sizeof(a->digits) / sizeof(a->digits[0]); i--;) {
+        if (a->digits[i] < b->digits[i]) {
+            return true;
+        }
+        if (a->digits[i] > b->digits[i]) {
+            return false;
+        }
+    }
+    return false;
+}
+
+// r = a * -1
+void _CFBigNumNeg(_CFBigNum *r, const _CFBigNum *a) {
+    memmove(r, a, sizeof(*a));
+    Boolean aIsZero = true;
+    for (CFIndex i = 0; i < sizeof(a->digits) / sizeof(a->digits[0]); i++) {
+        if (a->digits[i] != 0) {
+            aIsZero = false;
+            break;
+        }
+    }
+    // if a is zero, we do not flip the sign
+    if (!aIsZero) {
+        // 0  -> -1
+        // -1 -> 0
+        r->sign = r->sign * r->sign - 1;
+    }
+}
+
+uint8_t _CFBigNumAdd(_CFBigNum *r, const _CFBigNum *a, const _CFBigNum *b) {
+    uint8_t carry = 0;
+    Boolean sameSign = a->sign == b->sign;
+    if (sameSign) {
+        for (CFIndex i = 0; i < sizeof(a->digits) / sizeof(a->digits[0]); i++) {
+            uint32_t result = a->digits[i] + b->digits[i] + carry;
+            if (result > BIG_DIGITS_LIMIT) {
+                carry = 1;
+                result -= BIG_DIGITS_LIMIT;
+            } else {
+                carry = 0;
+            }
+            r->digits[i] = result;
+        }
+        r->sign = a->sign;
+        return carry;
+    } else {
+        // the algorithm here is to find the larger one and do the subtraction and then neg the result if necessary
+        const _CFBigNum *bigNum = NULL;
+        const _CFBigNum *smallNum = NULL;
+        if (_CFBigNumAbsoluteLessThan(a, b)) {
+            bigNum = b;
+            smallNum = a;
+        } else {
+            bigNum = a;
+            smallNum = b;
+        }
+        for (int i = 0; i < sizeof(a->digits) / sizeof(a->digits[0]); i++) {
+            int64_t result = (int64_t)bigNum->digits[i] - (int64_t)smallNum->digits[i] - carry;
+            if (result < 0) {
+                carry = 1;
+                result += BIG_DIGITS_LIMIT;
+            } else {
+                carry = 0;
+            }
+            r->digits[i] = result;
+        }
+        if (bigNum->sign < 0) {
+            r->sign = -1;
+        } else {
+            r->sign = 0;
+        }
+        return carry;
+    }
+}
+
+uint8_t _CFBigNumSub(_CFBigNum *r, const _CFBigNum *a, const _CFBigNum *b) {
+    _CFBigNum nb;
+    _CFBigNumNeg(&nb, b);
+    return _CFBigNumAdd(r, a, &nb);
+}
+
+
+void _CFBigNumToCString(const _CFBigNum *vp, Boolean leading_zeros, Boolean leading_plus, char *buffer, size_t buflen) {
+    if (vp->sign < 0) {
+        *buffer++ = '-';
+        buflen--;
+    } else if (leading_plus) {
+        *buffer++ = '+';
+        buflen--;
+    }
+    char tmp[46];
+    snprintf(tmp, sizeof(tmp), "%09u%09u%09u%09u%09u", vp->digits[4], vp->digits[3], vp->digits[2], vp->digits[1], vp->digits[0]);
+    if (leading_zeros) {
+        memset(buffer, '0', buflen);
+        uint32_t tocopy = __CFMin(sizeof(tmp), buflen);
+        memmove(buffer + buflen - tocopy, tmp + sizeof(tmp) - tocopy, tocopy); // copies trailing nul from tmp to nul-terminate
+    } else {
+        char *s = tmp;
+        while (*s == '0') s++;
+        if (*s == 0) s--; // if tmp is all zeros, copy out at least one zero
+        strlcpy(buffer, s, buflen);
+    }
+}
+
+void _CFBigNumFromCString(_CFBigNum *r, const char *string) {
+    memset(r, 0, sizeof(*r));
+    char *copy = (char *)calloc(strlen(string)+1, sizeof(char));
+    memcpy(copy, string, strlen(string)+1);
+    char *working = copy;
+    if (*working == '-') {
+        r->sign = -1;
+        working++;
+    } else if (*working == '+') {
+        working++;
+    }
+    while (*working == '0') {
+        working++;
+    }
+
+    size_t length = strlen(working);
+    if (length == 0) { // the number is zero
+        return;
+    }
+    int curDigit = 0;
+    while (curDigit + 1 < sizeof(r->digits) / sizeof(r->digits[0]) && 9 < length) {
+        uint32_t digit = atol(working+length-9);
+        r->digits[curDigit] = digit;
+        *(working+length-9) = 0;
+        length -= 9;
+        curDigit++;
+    }
+    uint32_t digit = atol(working);
+    r->digits[curDigit] = digit;
+    free(copy);
+}
+
+char *_CFBigNumCopyDescription(const _CFBigNum *num) {
+    char *result = (char *)calloc(1024, sizeof(char));
+    sprintf(result, "sign:%s 1st:%u 2nd:%u 3rd:%u 4th:%u 5th:%u", num->sign < 0 ? "-" : "+", num->digits[0], num->digits[1], num->digits[2], num->digits[3], num->digits[4]);
+    return result;
+}
+
diff --git a/CFBigNumber.h b/CFBigNumber.h
new file mode 100644 (file)
index 0000000..7fc0a89
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*     CFBigNumber.h
+       Copyright (c) 2012-2012, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFBIGNUMBER__)
+#define __COREFOUNDATION_CFBIGNUMBER__ 1
+
+#include <CoreFoundation/CFBase.h>
+#include <CoreFoundation/CFNumber.h>
+
+
+// Base 1 billion number: each digit represents 0 to 999999999
+typedef struct {
+    uint32_t digits[5];
+    int32_t sign:8;
+    uint32_t __:24;
+} _CFBigNum;
+
+void _CFBigNumInitWithInt8(_CFBigNum *r, int8_t inNum);
+void _CFBigNumInitWithInt16(_CFBigNum *r, int16_t inNum);
+void _CFBigNumInitWithInt32(_CFBigNum *r, int32_t inNum);
+void _CFBigNumInitWithInt64(_CFBigNum *r, int64_t inNum);
+#ifdef __LP64__
+void _CFBigNumInitWithInt128(_CFBigNum *r, __int128_t inNum);
+#endif
+
+void _CFBigNumInitWithUInt8(_CFBigNum *r, uint8_t inNum);
+void _CFBigNumInitWithUInt16(_CFBigNum *r, uint16_t inNum);
+void _CFBigNumInitWithUInt32(_CFBigNum *r, uint32_t inNum);
+void _CFBigNumInitWithUInt64(_CFBigNum *r, uint64_t inNum);
+#ifdef __LP64__
+void _CFBigNumInitWithUInt128(_CFBigNum *r, __uint128_t inNum);
+#endif
+
+int8_t  _CFBigNumGetInt8(const _CFBigNum *num);
+int16_t _CFBigNumGetInt16(const _CFBigNum *num);
+int32_t _CFBigNumGetInt32(const _CFBigNum *num);
+int64_t _CFBigNumGetInt64(const _CFBigNum *num);
+#ifdef __LP64__
+__int128_t _CFBigNumGetInt128(const _CFBigNum *num);
+#endif
+
+uint8_t  _CFBigNumGetUInt8(const _CFBigNum *num);
+uint16_t _CFBigNumGetUInt16(const _CFBigNum *num);
+uint32_t _CFBigNumGetUInt32(const _CFBigNum *num);
+uint64_t _CFBigNumGetUInt64(const _CFBigNum *num);
+#ifdef __LP64__
+__uint128_t _CFBigNumGetUInt128(const _CFBigNum *num);
+#endif
+
+void _CFBigNumInitWithCFNumber(_CFBigNum *r, CFNumberRef input);
+void _CFBigNumInitWithBytes(_CFBigNum *r, const void *bytes, CFNumberType type);
+CFNumberRef _CFNumberCreateWithBigNum(const _CFBigNum *input);
+
+
+CFComparisonResult _CFBigNumCompare(const _CFBigNum *a, const _CFBigNum *b);
+
+void _CFBigNumNeg(_CFBigNum *r, const _CFBigNum *a);
+uint8_t _CFBigNumAdd(_CFBigNum *r, const _CFBigNum *a, const _CFBigNum *b);
+uint8_t _CFBigNumSub(_CFBigNum *r, const _CFBigNum *a, const _CFBigNum *b);
+
+
+void _CFBigNumToCString(const _CFBigNum *vp, Boolean leading_zeros, Boolean leading_plus, char *buffer, size_t buflen);
+void _CFBigNumFromCString(_CFBigNum *r, const char *string);
+
+char *_CFBigNumCopyDescription(const _CFBigNum *num); // caller must free() returned ptr
+
+
+#endif /* ! __COREFOUNDATION_CFBIGNUMBER__ */
+
index 77bf232a435fcd01fcdb2bb8e87584e60a95f5dd..f711b8f9db8cb3e98bde76e01d112f354d3cd6f7 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryHeap.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
index 8d3ab23318bf5691d13b7b758d26e6ef102aba45..da94e9adbfebae8b96e32f04d792129b3d5e26d3 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryHeap.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 /*!
         @header CFBinaryHeap
@@ -36,6 +36,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef struct {
@@ -305,6 +306,7 @@ CF_EXPORT void              CFBinaryHeapRemoveMinimumValue(CFBinaryHeapRef heap);
 CF_EXPORT void         CFBinaryHeapRemoveAllValues(CFBinaryHeapRef heap);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFBINARYHEAP__ */
 
index 36742eab3be23cf9cc5cfd4e6deac3307a57cc4d..ed1a8546a4fcc5c4144cee8367b578a3e05e83d2 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBinaryPList.c
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -38,6 +38,7 @@
 #include <CoreFoundation/CFPropertyList.h>
 #include <CoreFoundation/CFByteOrder.h>
 #include <CoreFoundation/CFRuntime.h>
+#include <CoreFoundation/CFUUID.h>
 #include <stdio.h>
 #include <limits.h>
 #include <string.h>
@@ -55,9 +56,6 @@ enum {
     kCFNumberSInt128Type = 17
 };
 
-CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);
-__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
-
 enum {
        CF_NO_ERROR = 0,
        CF_OVERFLOW_ERROR = (1 << 0),
@@ -98,6 +96,8 @@ CF_INLINE uint64_t __check_uint64_mul_unsigned_unsigned(uint64_t x, uint64_t y,
 #define check_size_t_mul(b, a, err)    (size_t)__check_uint32_mul_unsigned_unsigned((size_t)b, (size_t)a, err)
 #endif
 
+#pragma mark -
+#pragma mark Keyed Archiver UID
 
 struct __CFKeyedArchiverUID {
     CFRuntimeBase _base;
@@ -151,6 +151,10 @@ uint32_t _CFKeyedArchiverUIDGetValue(CFKeyedArchiverUIDRef uid) {
     return uid->_value;
 }
 
+#pragma mark -
+#pragma mark Writing
+
+__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
 
 typedef struct {
     CFTypeRef stream;
@@ -217,17 +221,23 @@ static void bufferFlush(__CFBinaryPlistWriteBuffer *buf) {
 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]
 
 OBJECT TABLE
        variable-sized objects
 
        Object Formats (marker byte followed by additional info in some cases)
-       null    0000 0000
+       null    0000 0000                       // null object [v1+ 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]
        fill    0000 1111                       // fill byte
-       int     0001 nnnn       ...             // # of bytes is 2^nnnn, big-endian bytes
-       real    0010 nnnn       ...             // # of bytes is 2^nnnn, big-endian bytes
+       int     0001 0nnn       ...             // # of bytes is 2^nnn, big-endian bytes
+       real    0010 0nnn       ...             // # of bytes is 2^nnn, big-endian bytes
        date    0011 0011       ...             // 8 byte float follows, big-endian bytes
        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
@@ -236,8 +246,8 @@ OBJECT TABLE
        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
-               1011 xxxx                       // unused
-       set     1100 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]
        dict    1101 nnnn       [int]   keyref* objref* // nnnn is count, unless '1111', then int count follows
                1110 xxxx                       // unused
                1111 xxxx                       // unused
@@ -254,11 +264,17 @@ 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.
+
 */
 
 
 static CFTypeID stringtype = -1, datatype = -1, numbertype = -1, datetype = -1;
-static CFTypeID booltype = -1, nulltype = -1, dicttype = -1, arraytype = -1, settype = -1;
+static CFTypeID booltype = -1, nulltype = -1, dicttype = -1, arraytype = -1;
+static CFTypeID uuidtype = -1, urltype = -1, osettype = -1, settype = -1;
 
 static void initStatics() {
     if ((CFTypeID)-1 == stringtype) {
@@ -288,6 +304,15 @@ static void initStatics() {
     if ((CFTypeID)-1 == nulltype) {
         nulltype = CFNullGetTypeID();
     }
+    if ((CFTypeID)-1 == uuidtype) {
+        uuidtype = CFUUIDGetTypeID();
+    }
+    if ((CFTypeID)-1 == urltype) {
+        urltype = CFURLGetTypeID();
+    }
+    if ((CFTypeID)-1 == osettype) {
+        osettype = -1;
+    }
 }
 
 static void _appendInt(__CFBinaryPlistWriteBuffer *buf, uint64_t bigint) {
@@ -334,6 +359,228 @@ static void _appendUID(__CFBinaryPlistWriteBuffer *buf, CFKeyedArchiverUIDRef ui
     bufferWrite(buf, bytes, nbytes);
 }
 
+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);
+    // 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);
+    if (ret == count) {
+        uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerASCIIString | (needed < 15 ? needed : 0xf));
+        bufferWrite(buf, &marker, 1);
+        if (15 <= needed) {
+           _appendInt(buf, (uint64_t)needed);
+        }
+        bufferWrite(buf, bytes, needed);
+    } else {
+        UniChar *chars;
+        uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerUnicode16String | (count < 15 ? count : 0xf));
+        bufferWrite(buf, &marker, 1);
+        if (15 <= count) {
+           _appendInt(buf, (uint64_t)count);
+        }
+        chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 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);
+    }
+    if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, bytes);
+}
+
+CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number);
+
+static void _appendNumber(__CFBinaryPlistWriteBuffer *buf, CFNumberRef num) {
+    uint8_t marker;
+    uint64_t bigint;
+    uint8_t *bytes;
+    CFIndex nbytes;
+    if (CFNumberIsFloatType(num)) {
+        CFSwappedFloat64 swapped64;
+        CFSwappedFloat32 swapped32;
+        if (CFNumberGetByteSize(num) <= (CFIndex)sizeof(float)) {
+           float v;
+           CFNumberGetValue(num, kCFNumberFloat32Type, &v);
+           swapped32 = CFConvertFloat32HostToSwapped(v);
+           bytes = (uint8_t *)&swapped32;
+           nbytes = sizeof(float);
+           marker = kCFBinaryPlistMarkerReal | 2;
+        } else {
+           double v;
+           CFNumberGetValue(num, kCFNumberFloat64Type, &v);
+           swapped64 = CFConvertFloat64HostToSwapped(v);
+           bytes = (uint8_t *)&swapped64;
+           nbytes = sizeof(double);
+           marker = kCFBinaryPlistMarkerReal | 3;
+        }
+        bufferWrite(buf, &marker, 1);
+        bufferWrite(buf, bytes, nbytes);
+    } else {
+        CFNumberType type = _CFNumberGetType2(num);
+        if (kCFNumberSInt128Type == type) {
+           CFSInt128Struct s;
+           CFNumberGetValue(num, kCFNumberSInt128Type, &s);
+           struct {
+               int64_t high;
+               uint64_t low;
+           } storage;
+           storage.high = CFSwapInt64HostToBig(s.high);
+           storage.low = CFSwapInt64HostToBig(s.low);
+           uint8_t *bytes = (uint8_t *)&storage;
+           uint8_t marker = kCFBinaryPlistMarkerInt | 4;
+           CFIndex nbytes = 16;
+           bufferWrite(buf, &marker, 1);
+           bufferWrite(buf, bytes, nbytes);
+        } else {
+           CFNumberGetValue(num, kCFNumberSInt64Type, &bigint);
+           _appendInt(buf, bigint);
+        }
+    }
+}
+
+// 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;
+    CFTypeID type = CFGetTypeID(obj);
+       if (stringtype == type) {
+           _appendString(buf, (CFStringRef)obj);
+       } else if (numbertype == type) {
+           _appendNumber(buf, (CFNumberRef)obj);
+       } 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));
+           bufferWrite(buf, &marker, 1);
+           if (15 <= count) {
+               _appendInt(buf, (uint64_t)count);
+           }
+           bufferWrite(buf, CFDataGetBytePtr((CFDataRef)obj), count);
+       } else if (datetype == type) {
+           CFSwappedFloat64 swapped;
+           uint8_t marker = kCFBinaryPlistMarkerDate;
+           bufferWrite(buf, &marker, 1);
+           swapped = CFConvertFloat64HostToSwapped(CFDateGetAbsoluteTime((CFDateRef)obj));
+           bufferWrite(buf, (uint8_t *)&swapped, sizeof(swapped));
+       } else if (dicttype == type) {
+            CFIndex count = CFDictionaryGetCount((CFDictionaryRef)obj);
+            uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerDict | (count < 15 ? count : 0xf));
+            bufferWrite(buf, &marker, 1);
+            if (15 <= count) {
+                _appendInt(buf, (uint64_t)count);
+            }
+            CFPropertyListRef *list, buffer[512];
+            list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
+            CFDictionaryGetKeysAndValues((CFDictionaryRef)obj, list, list + count);
+            for (idx2 = 0; idx2 < 2 * 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 (arraytype == type) {
+           CFIndex count = CFArrayGetCount((CFArrayRef)obj);
+           CFPropertyListRef *list, buffer[256];
+           uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerArray | (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);
+           CFArrayGetValues((CFArrayRef)obj, CFRangeMake(0, count), 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 && 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) {
+           _appendUID(buf, (CFKeyedArchiverUIDRef)obj);
+       } else {
+           return false;
+       }
+    return true;
+}
+
 static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CFMutableDictionaryRef objtable, CFMutableSetRef uniquingset) {
     CFPropertyListRef unique;
     uint32_t refnum;
@@ -384,33 +631,31 @@ static void _flattenPlist(CFPropertyListRef plist, CFMutableArrayRef objlist, CF
 CF_INLINE uint8_t _byteCount(uint64_t count) {
     uint64_t mask = ~(uint64_t)0;
     uint8_t size = 0;
-    
+
     // Find something big enough to hold 'count'
     while (count & mask) {
         size++;
         mask = mask << 8;
     }
-    
+
     // Ensure that 'count' is a power of 2
     // For sizes bigger than 8, just use the required count
     while ((size != 1 && size != 2 && size != 4 && size != 8) && size <= 8) {
         size++;
     }
-    
+
     return size;
 }
 
-
 // stream can be a CFWriteStreamRef (on supported platforms) or a CFMutableDataRef
 /* Write a property list to a stream, in binary format. plist is the property list to write (one of the basic property list types), stream is the destination of the property list, and estimate is a best-guess at the total number of objects in the property list. The estimate parameter is for efficiency in pre-allocating memory for the uniquing step. Pass in a 0 if no estimate is available. The options flag specifies sort options. If the error parameter is non-NULL and an error occurs, it will be used to return a CFError explaining the problem. It is the callers responsibility to release the error. */
 CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate, CFOptionFlags options, CFErrorRef *error) {
-    CFMutableDictionaryRef objtable;
-    CFMutableArrayRef objlist;
-    CFMutableSetRef uniquingset;
+    CFMutableDictionaryRef objtable = NULL;
+    CFMutableArrayRef objlist = NULL;
+    CFMutableSetRef uniquingset = NULL;
     CFBinaryPlistTrailer trailer;
     uint64_t *offsets, length_so_far;
-    uint64_t refnum;
-    int64_t idx, idx2, cnt;
+    int64_t idx, cnt;
     __CFBinaryPlistWriteBuffer *buf;
     
     initStatics();
@@ -451,147 +696,10 @@ CFIndex __CFBinaryPlistWrite(CFPropertyListRef plist, CFTypeRef stream, uint64_t
     trailer._topObject = 0;    // true for this implementation
     trailer._objectRefSize = _byteCount(cnt);    
     for (idx = 0; idx < cnt; idx++) {
-       CFPropertyListRef obj = CFArrayGetValueAtIndex(objlist, (CFIndex)idx);
-       CFTypeID type = CFGetTypeID(obj);
        offsets[idx] = buf->written + buf->used;
-       if (stringtype == type) {
-           CFIndex ret, count = CFStringGetLength((CFStringRef)obj);
-           CFIndex needed;
-           uint8_t *bytes, buffer[1024];
-           bytes = (count <= 1024) ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 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((CFStringRef)obj, CFRangeMake(0, count), kCFStringEncodingASCII, 0, false, bytes, count, &needed);
-           if (ret == count) {
-               uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerASCIIString | (needed < 15 ? needed : 0xf));
-               bufferWrite(buf, &marker, 1);
-               if (15 <= needed) {
-                   _appendInt(buf, (uint64_t)needed);
-               }
-               bufferWrite(buf, bytes, needed);
-           } else {
-               UniChar *chars;
-               uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerUnicode16String | (count < 15 ? count : 0xf));
-               bufferWrite(buf, &marker, 1);
-               if (15 <= count) {
-                   _appendInt(buf, (uint64_t)count);
-               }
-               chars = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, count * sizeof(UniChar), 0);
-               CFStringGetCharacters((CFStringRef)obj, 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);
-           }
-           if (bytes != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, bytes);
-       } else if (numbertype == type) {
-           uint8_t marker;
-           uint64_t bigint;
-           uint8_t *bytes;
-           CFIndex nbytes;
-           if (CFNumberIsFloatType((CFNumberRef)obj)) {
-               CFSwappedFloat64 swapped64;
-               CFSwappedFloat32 swapped32;
-               if (CFNumberGetByteSize((CFNumberRef)obj) <= (CFIndex)sizeof(float)) {
-                   float v;
-                   CFNumberGetValue((CFNumberRef)obj, kCFNumberFloat32Type, &v);
-                   swapped32 = CFConvertFloat32HostToSwapped(v);
-                   bytes = (uint8_t *)&swapped32;
-                   nbytes = sizeof(float);
-                   marker = kCFBinaryPlistMarkerReal | 2;
-               } else {
-                   double v;
-                   CFNumberGetValue((CFNumberRef)obj, kCFNumberFloat64Type, &v);
-                   swapped64 = CFConvertFloat64HostToSwapped(v);
-                   bytes = (uint8_t *)&swapped64;
-                   nbytes = sizeof(double);
-                   marker = kCFBinaryPlistMarkerReal | 3;
-               }
-               bufferWrite(buf, &marker, 1);
-               bufferWrite(buf, bytes, nbytes);
-           } else {
-               CFNumberType type = _CFNumberGetType2((CFNumberRef)obj);
-               if (kCFNumberSInt128Type == type) {
-                   CFSInt128Struct s;
-                   CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt128Type, &s);
-                   struct {
-                       int64_t high;
-                       uint64_t low;
-                   } storage;
-                   storage.high = CFSwapInt64HostToBig(s.high);
-                   storage.low = CFSwapInt64HostToBig(s.low);
-                   uint8_t *bytes = (uint8_t *)&storage;
-                   uint8_t marker = kCFBinaryPlistMarkerInt | 4;
-                   CFIndex nbytes = 16;
-                   bufferWrite(buf, &marker, 1);
-                   bufferWrite(buf, bytes, nbytes);
-               } else {
-                   CFNumberGetValue((CFNumberRef)obj, kCFNumberSInt64Type, &bigint);
-                   _appendInt(buf, bigint);
-               }
-           }
-       } else if (_CFKeyedArchiverUIDGetTypeID() == type) {
-           _appendUID(buf, (CFKeyedArchiverUIDRef)obj);
-       } else if (booltype == type) {
-           uint8_t marker = CFBooleanGetValue((CFBooleanRef)obj) ? kCFBinaryPlistMarkerTrue : kCFBinaryPlistMarkerFalse;
-           bufferWrite(buf, &marker, 1);
-       } else if (datatype == type) {
-           CFIndex count = CFDataGetLength((CFDataRef)obj);
-           uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerData | (count < 15 ? count : 0xf));
-           bufferWrite(buf, &marker, 1);
-           if (15 <= count) {
-               _appendInt(buf, (uint64_t)count);
-           }
-           bufferWrite(buf, CFDataGetBytePtr((CFDataRef)obj), count);
-       } else if (datetype == type) {
-           CFSwappedFloat64 swapped;
-           uint8_t marker = kCFBinaryPlistMarkerDate;
-           bufferWrite(buf, &marker, 1);
-           swapped = CFConvertFloat64HostToSwapped(CFDateGetAbsoluteTime((CFDateRef)obj));
-           bufferWrite(buf, (uint8_t *)&swapped, sizeof(swapped));
-       } else if (dicttype == type) {
-            CFIndex count = CFDictionaryGetCount((CFDictionaryRef)obj);
-
-            uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerDict | (count < 15 ? count : 0xf));
-            bufferWrite(buf, &marker, 1);
-            if (15 <= count) {
-                _appendInt(buf, (uint64_t)count);
-            }
-            
-            CFPropertyListRef *list, buffer[512];
-
-            list = (count <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, 2 * count * sizeof(CFTypeRef), __kCFAllocatorGCScannedMemory);
-            CFDictionaryGetKeysAndValues((CFDictionaryRef)obj, list, list + count);
-            for (idx2 = 0; idx2 < 2 * count; idx2++) {
-                CFPropertyListRef value = list[idx2];
-                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) - trailer._objectRefSize, trailer._objectRefSize);
-            }
-            if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-       } else if (arraytype == type) {
-           CFIndex count = CFArrayGetCount((CFArrayRef)obj);
-           CFPropertyListRef *list, buffer[256];
-           uint8_t marker = (uint8_t)(kCFBinaryPlistMarkerArray | (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);
-           CFArrayGetValues((CFArrayRef)obj, CFRangeMake(0, count), list);
-           for (idx2 = 0; idx2 < count; idx2++) {
-               CFPropertyListRef value = list[idx2];
-               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) - trailer._objectRefSize, trailer._objectRefSize);
-           }
-           if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-       } else {
+       CFPropertyListRef obj = CFArrayGetValueAtIndex(objlist, (CFIndex)idx);
+       Boolean success = _appendObject(buf, obj, objtable, trailer._objectRefSize);
+       if (!success) {
            CFRelease(objtable);
            CFRelease(objlist);
            if (error && buf->error) {
@@ -653,9 +761,52 @@ 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
+
 #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);
+
 /* Grab a valSize-bytes integer out of the buffer pointed at by data and return it.
  */
 CF_INLINE uint64_t _getSizedInt(const uint8_t *data, uint8_t valSize) {
@@ -776,7 +927,7 @@ bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t datalen,
 
 CF_INLINE Boolean _plistIsPrimitive(CFPropertyListRef pl) {
     CFTypeID type = CFGetTypeID(pl);
-    if (dicttype == type || arraytype == type || settype == type) FAIL_FALSE;
+    if (dicttype == type || arraytype == type || settype == type || osettype == type) FAIL_FALSE;
     return true;
 }
 
@@ -840,11 +991,6 @@ bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64
     return true;
 }
 
-// Compatibility method, to be removed soon
-CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromDictionary2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *koffset, uint64_t *voffset, CFMutableDictionaryRef objects) {
-    return __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, startOffset, trailer, key, koffset, voffset, false, objects);
-}
-
 /* Get the offset for a value in a dictionary in a binary property list.
  @param databytes A pointer to the start of the binary property list data.
  @param datalen The length of the data.
@@ -962,10 +1108,10 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u
            }
        } else {
             // temp object not saved in 'objects', because we don't know what allocator to use
-            // (what allocator __CFBinaryPlistCreateObject2() or __CFBinaryPlistCreateObject()
+            // (what allocator __CFBinaryPlistCreateObjectFiltered() or __CFBinaryPlistCreateObject()
             //  will eventually be called with which results in that object)
            keyInData = NULL;
-           if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, NULL /*objects*/, NULL, 0, &keyInData) || !_plistIsPrimitive(keyInData)) {
+           if (!__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, kCFAllocatorSystemDefault, kCFPropertyListImmutable, NULL /*objects*/, NULL, 0, NULL, &keyInData) || !_plistIsPrimitive(keyInData)) {
                if (keyInData) CFRelease(keyInData);
                return false;
            }
@@ -989,8 +1135,9 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u
 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_EXPORT bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFPropertyListRef *plist) {
+__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) {
 
     if (objects) {
        *plist = CFDictionaryGetValue(objects, (const void *)(uintptr_t)startOffset);
@@ -1236,83 +1383,133 @@ CF_EXPORT bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t d
        int32_t err = CF_NO_ERROR;
        ptr = check_ptr_add(ptr, 1, &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
+       CFIndex arrayCount = marker & 0x0f;
+       if (0xf == arrayCount) {
            uint64_t bigint = 0;
            if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
            if (LONG_MAX < bigint) FAIL_FALSE;
-           cnt = (CFIndex)bigint;
+           arrayCount = (CFIndex)bigint;
        }
-       size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+       size_t byte_cnt = check_size_t_mul(arrayCount, trailer->_objectRefSize, &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
        const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
        if (CF_NO_ERROR != err) FAIL_FALSE;
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
-       byte_cnt = check_size_t_mul(cnt, sizeof(CFPropertyListRef), &err);
+       byte_cnt = check_size_t_mul(arrayCount, sizeof(CFPropertyListRef), &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       list = (cnt <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
+       list = (arrayCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
        if (!list) FAIL_FALSE;
        Boolean madeSet = false;
        if (!set && 15 < curDepth) {
            set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
            madeSet = set ? true : false;
        }
-       if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
-       for (CFIndex idx = 0; idx < cnt; idx++) {
-           CFPropertyListRef pl;
-           off = _getOffsetOfRefAt(databytes, ptr, trailer);
-           if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, &pl)) {
-               while (idx--) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-               }           
-               if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-               FAIL_FALSE;
-           }
-            __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
-           ptr += trailer->_objectRefSize;
-       }
-       if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
-       if (madeSet) {
-           CFRelease(set);
-           set = NULL;
-       }
-       if ((marker & 0xf0) == kCFBinaryPlistMarkerArray) {
-           if (mutabilityOption != kCFPropertyListImmutable) {
-               *plist = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
-               CFArrayReplaceValues((CFMutableArrayRef)*plist, CFRangeMake(0, 0), list, cnt);
-               for (CFIndex idx = 0; idx < cnt; idx++) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-               }
-           } else {
-               if (!kCFUseCollectableAllocator) {
-                   *plist = __CFArrayCreateTransfer(allocator, list, cnt);
-               } else {
-                   *plist = CFArrayCreate(allocator, list, cnt, &kCFTypeArrayCallBacks);
-                   for (CFIndex idx = 0; idx < cnt; idx++) {
-                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+        
+        if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
+        if ((marker & 0xf0) == kCFBinaryPlistMarkerArray && keyPaths) {
+            // Only get a subset of this array
+            CFSetRef theseKeys, nextKeys;
+            __CFPropertyListCreateSplitKeypaths(kCFAllocatorSystemDefault, keyPaths, &theseKeys, &nextKeys);
+                        
+            Boolean success = true;
+            CFMutableArrayRef array = CFArrayCreateMutable(allocator, CFSetGetCount(theseKeys), &kCFTypeArrayCallBacks);
+            if (theseKeys) {
+                CFTypeRef *keys = (CFTypeRef *)malloc(CFSetGetCount(theseKeys) * sizeof(CFTypeRef));
+                CFSetGetValues(theseKeys, keys);
+                for (CFIndex i = 0; i < CFSetGetCount(theseKeys); i++) {
+                    CFStringRef key = (CFStringRef)keys[i];
+                    SInt32 intValue = CFStringGetIntValue(key);
+                    if ((intValue == 0 && CFStringCompare(CFSTR("0"), key, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN || intValue < 0) {
+                        // skip, doesn't appear to be a proper integer
+                    } else {
+                        uint64_t valueOffset;
+                        Boolean found = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, startOffset, trailer, (CFIndex)intValue, &valueOffset, objects);
+                        if (found) {
+                            CFPropertyListRef result;
+                            success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, &result);
+                            if (success) {
+                                CFArrayAppendValue(array, result);
+                                CFRelease(result);
+                            } else {
+                                break;
+                            }
+                        }
                     }
                 }
-           }
-       } else {
-           if (mutabilityOption != kCFPropertyListImmutable) {
-               *plist = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
-               for (CFIndex idx = 0; idx < cnt; idx++) {
-                   CFSetAddValue((CFMutableSetRef)*plist, list[idx]);
-               }
-               for (CFIndex idx = 0; idx < cnt; idx++) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-               }
-           } else {
-               if (!kCFUseCollectableAllocator) {
-                   *plist = __CFSetCreateTransfer(allocator, list, cnt);
+                
+                free(keys);
+                CFRelease(theseKeys);
+            }
+            if (nextKeys) CFRelease(nextKeys);
+            
+            if (success) {
+                if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) {
+                    // make immutable
+                    *plist = CFArrayCreateCopy(allocator, array);
+                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(array);
                 } else {
-                   *plist = CFSetCreate(allocator, list, cnt, &kCFTypeSetCallBacks);
-                   for (CFIndex idx = 0; idx < cnt; idx++) {
+                    *plist = array;
+                }
+            } else if (array) {
+                if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(array);
+            }
+        } else {            
+            for (CFIndex idx = 0; idx < arrayCount; idx++) {            
+                CFPropertyListRef pl;
+                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]);
+                    }      
+                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                    FAIL_FALSE;
+                }
+                __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
+                ptr += trailer->_objectRefSize;
+            }            
+            if ((marker & 0xf0) == kCFBinaryPlistMarkerArray) {
+                if (mutabilityOption != kCFPropertyListImmutable) {
+                    *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]);
+                    }
+                } else {
+                    if (!kCFUseCollectableAllocator) {
+                        *plist = __CFArrayCreateTransfer(allocator, list, arrayCount);
+                    } else {
+                        *plist = CFArrayCreate(allocator, list, arrayCount, &kCFTypeArrayCallBacks);
+                        for (CFIndex idx = 0; idx < arrayCount; idx++) {
+                            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        }
                     }
                 }
-           }
-       }
+            } else {
+                if (mutabilityOption != kCFPropertyListImmutable) {
+                    *plist = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
+                    for (CFIndex idx = 0; idx < arrayCount; idx++) {
+                        CFSetAddValue((CFMutableSetRef)*plist, list[idx]);
+                    }
+                    for (CFIndex idx = 0; idx < arrayCount; idx++) {
+                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                    }
+                } else {
+                    if (!kCFUseCollectableAllocator) {
+                        *plist = __CFSetCreateTransfer(allocator, list, arrayCount);
+                    } else {
+                        *plist = CFSetCreate(allocator, list, arrayCount, &kCFTypeSetCallBacks);
+                        for (CFIndex idx = 0; idx < arrayCount; idx++) {
+                            if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                        }
+                    }
+                }
+            }
+        }
+        if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
+        if (madeSet) {
+            CFRelease(set);
+            set = NULL;
+        }
        if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
            CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
        }
@@ -1324,67 +1521,112 @@ CF_EXPORT bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t d
        int32_t err = CF_NO_ERROR;
        ptr = check_ptr_add(ptr, 1, &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       CFIndex cnt = marker & 0x0f;
-       if (0xf == cnt) {
+       CFIndex dictionaryCount = marker & 0x0f;
+       if (0xf == dictionaryCount) {
            uint64_t bigint = 0;
            if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE;
            if (LONG_MAX < bigint) FAIL_FALSE;
-           cnt = (CFIndex)bigint;
+           dictionaryCount = (CFIndex)bigint;
        }
-       cnt = check_size_t_mul(cnt, 2, &err);
+       dictionaryCount = check_size_t_mul(dictionaryCount, 2, &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       size_t byte_cnt = check_size_t_mul(cnt, trailer->_objectRefSize, &err);
+       size_t byte_cnt = check_size_t_mul(dictionaryCount, trailer->_objectRefSize, &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
        const uint8_t *extent = check_ptr_add(ptr, byte_cnt, &err) - 1;
        if (CF_NO_ERROR != err) FAIL_FALSE;
        if (databytes + objectsRangeEnd < extent) FAIL_FALSE;
-       byte_cnt = check_size_t_mul(cnt, sizeof(CFPropertyListRef), &err);
+       byte_cnt = check_size_t_mul(dictionaryCount, sizeof(CFPropertyListRef), &err);
        if (CF_NO_ERROR != err) FAIL_FALSE;
-       list = (cnt <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
+       list = (dictionaryCount <= 256) ? buffer : (CFPropertyListRef *)CFAllocatorAllocate(kCFAllocatorSystemDefaultGCRefZero, byte_cnt, __kCFAllocatorGCScannedMemory);
        if (!list) FAIL_FALSE;
        Boolean madeSet = false;
        if (!set && 15 < curDepth) {
            set = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, NULL);
            madeSet = set ? true : false;
        }
-       if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
-       for (CFIndex idx = 0; idx < cnt; idx++) {
-           CFPropertyListRef pl = NULL;
-           off = _getOffsetOfRefAt(databytes, ptr, trailer);
-           if (!__CFBinaryPlistCreateObject2(databytes, datalen, off, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, &pl) || (idx < cnt / 2 && !_plistIsPrimitive(pl))) {
-                if (pl && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(pl);
-               while (idx--) {
+        
+        if (set) CFSetAddValue(set, (const void *)(uintptr_t)startOffset);
+        if (keyPaths) {
+            // Only get a subset of this dictionary
+            CFSetRef theseKeys, nextKeys;
+            __CFPropertyListCreateSplitKeypaths(kCFAllocatorSystemDefault, keyPaths, &theseKeys, &nextKeys);
+            
+            Boolean success = true;
+            CFMutableDictionaryRef dict = CFDictionaryCreateMutable(allocator, CFSetGetCount(theseKeys), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+            if (theseKeys) {
+                CFTypeRef *keys = (CFTypeRef *)malloc(CFSetGetCount(theseKeys) * sizeof(CFTypeRef));
+                CFSetGetValues(theseKeys, keys);
+                for (CFIndex i = 0; i < CFSetGetCount(theseKeys); i++) {
+                    CFStringRef key = (CFStringRef)keys[i];
+                    uint64_t keyOffset, valueOffset;
+                    Boolean found = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, startOffset, trailer, key, &keyOffset, &valueOffset, false, objects);
+                    if (found) {
+                        CFPropertyListRef result;
+                        success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, trailer, allocator, mutabilityOption, objects, set, curDepth + 1, nextKeys, &result);
+                        if (success) {
+                            CFDictionarySetValue(dict, key, result);
+                            CFRelease(result);
+                        } else {
+                            break;
+                        }
+                    }
+                }
+                
+                free(keys);
+                CFRelease(theseKeys);
+            }
+            if (nextKeys) CFRelease(nextKeys);
+            
+            if (success) {
+                if (!(mutabilityOption == kCFPropertyListMutableContainers || mutabilityOption == kCFPropertyListMutableContainersAndLeaves)) {
+                    // make immutable
+                    *plist = CFDictionaryCreateCopy(allocator, dict);
+                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(dict);
+                } else {
+                    *plist = dict;
+                }
+            } else if (dict) {
+                if (!_CFAllocatorIsGCRefZero(allocator)) 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);
+                    while (idx--) {
+                        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
+                    }
+                    if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
+                    FAIL_FALSE;
+                }
+                __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
+                ptr += trailer->_objectRefSize;
+            }            
+            if (mutabilityOption != kCFPropertyListImmutable) {
+                *plist = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                for (CFIndex idx = 0; idx < dictionaryCount / 2; idx++) {
+                    CFDictionaryAddValue((CFMutableDictionaryRef)*plist, list[idx], list[idx + dictionaryCount / 2]);
+                }
+                for (CFIndex idx = 0; idx < dictionaryCount; idx++) {
                     if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-               }
-               if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefaultGCRefZero, list);
-               FAIL_FALSE;
-           }
-            __CFAssignWithWriteBarrier((void **)list + idx, (void *)pl);
-           ptr += trailer->_objectRefSize;
-       }
-       if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
-       if (madeSet) {
-           CFRelease(set);
-           set = NULL;
-       }
-       if (mutabilityOption != kCFPropertyListImmutable) {
-           *plist = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-           for (CFIndex idx = 0; idx < cnt / 2; idx++) {
-               CFDictionaryAddValue((CFMutableDictionaryRef)*plist, list[idx], list[idx + cnt / 2]);
-           }
-           for (CFIndex idx = 0; idx < cnt; idx++) {
-                if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-           }
-       } else {
-            if (!kCFUseCollectableAllocator) {
-               *plist = __CFDictionaryCreateTransfer(allocator, list, list + cnt / 2, cnt / 2);
+                }
             } else {
-               *plist = CFDictionaryCreate(allocator, list, list + cnt / 2, cnt / 2, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-               for (CFIndex idx = 0; idx < cnt; idx++) {
-                    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(list[idx]);
-               }
-           }
-       }
+                if (!kCFUseCollectableAllocator) {
+                    *plist = __CFDictionaryCreateTransfer(allocator, list, list + dictionaryCount / 2, dictionaryCount / 2);
+                } 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]);
+                    }
+                }
+            }
+        }
+        if (set) CFSetRemoveValue(set, (const void *)(uintptr_t)startOffset);
+        if (madeSet) {
+            CFRelease(set);
+            set = NULL;
+        }
        if (objects && *plist && (mutabilityOption == kCFPropertyListImmutable)) {
            CFDictionarySetValue(objects, (const void *)(uintptr_t)startOffset, *plist);
        }
@@ -1397,7 +1639,7 @@ CF_EXPORT bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t d
 
 bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFPropertyListRef *plist) {
        // for compatibility with Foundation's use, need to leave this here
-    return __CFBinaryPlistCreateObject2(databytes, datalen, startOffset, trailer, allocator, mutabilityOption, objects, NULL, 0, plist);
+    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) {
@@ -1417,14 +1659,282 @@ __private_extern__ bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFData
        CFMutableDictionaryRef objects = CFDictionaryCreateMutable(kCFAllocatorSystemDefaultGCRefZero, 0, NULL, &kCFTypeDictionaryValueCallBacks);
        _CFDictionarySetCapacity(objects, trailer._numObjects);
        CFPropertyListRef pl = NULL;
-        if (__CFBinaryPlistCreateObject2(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, &pl)) {
+        bool result = true;
+        if (__CFBinaryPlistCreateObjectFiltered(databytes, datalen, offset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl)) {
            if (plist) *plist = pl;
         } else {
            if (plist) *plist = NULL;
             if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("binary data is corrupt"));
+            result = false;
        }
         if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(objects);
-        return true;
+        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;
+}
+
index fab7ce389b6e07ad89a212b4b58e46656974f378..6043b9f1dd48bb30da429925547712fa64e491b0 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBitVector.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
    to right (bit 0 is the most significant) */
 typedef uint8_t __CFBitVectorBucket;
 
+#define __CFBITVECTORBUCKET_SIZE 8
+#define __CF_BITS_PER_BYTE 8
+
 enum {
-    __CF_BITS_PER_BYTE = 8,
     __CF_BITS_PER_BYTE_MASK = 0x07
 };
 
@@ -388,7 +390,11 @@ static __CFBitVectorBucket __CFBitVectorGetBits(__CFBitVectorBucket bucketValue,
        context->curByte++;
        context->totalBits -= context->initBits;
        nBits -= __CF_BITS_PER_BYTE;
+#if __CFBITVECTORBUCKET_SIZE > __CF_BITS_PER_BYTE
        val <<= __CF_BITS_PER_BYTE;
+#else
+        val = 0;
+#endif
     }
     /* ... then remaining bits go in *curByte */
     if (0 < nBits) {
index 502bac54268307ea26e87fdf4ee72e3ac03ce68b..4b44927891849741121f6f1f4766162bc9dc2d36 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBitVector.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBITVECTOR__)
@@ -30,6 +30,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef UInt32 CFBit;
@@ -60,6 +61,7 @@ CF_EXPORT void                CFBitVectorSetBits(CFMutableBitVectorRef bv, CFRange range, CFBi
 CF_EXPORT void         CFBitVectorSetAllBits(CFMutableBitVectorRef bv, CFBit value);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFBITVECTOR__ */
 
index c754227622eedb82fb12c98e4f09929f5f75135a..279f0634116e0e15bf1a5aa1e5d984975e2c02ff 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBuiltinConverters.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -38,7 +38,7 @@
 static int8_t __CFMapsParagraphSeparator = -1;
 
 CF_INLINE bool __CFIsParagraphSeparator(UTF16Char character) {
-    if (-1 == __CFMapsParagraphSeparator) __CFMapsParagraphSeparator = (_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard) ? false : true);
+    if (-1 == __CFMapsParagraphSeparator) __CFMapsParagraphSeparator = (1 ? false : true);
 
     return ((__CFMapsParagraphSeparator && (ParagraphSeparator == character)) ? true : false);
 }
index 5ea739cad9d525db627408312ac4a3f7951a94ca..254fd923e16eca2128e36db5378ff0464a227172 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 /*      CFBundle.c
-        Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
 #include "CFBundle_Internal.h"
 #include <sys/stat.h>
 #include <stdlib.h>
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
+#else
+#error Unknown deployment target
+#endif
+
 #define AVOID_WEAK_COLLECTIONS 1
 
-#if !defined(AVOID_WEAK_COLLECTIONS)
+#if !AVOID_WEAK_COLLECTIONS
 #include "CFHashTable.h"
 #include "CFMapTable.h"
 #include "CFPointerArray.h"
@@ -69,7 +74,7 @@
 #include <dlfcn.h>
 #endif /* BINARY_SUPPORT_DLFCN */
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <fcntl.h>
 #elif DEPLOYMENT_TARGET_WINDOWS
 #include <fcntl.h>
 
 #define open _NS_open
 #define stat(x,y) _NS_stat(x,y)
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#define statinfo _stat
+
+// Windows isspace implementation limits the input chars to < 256 in the ASCII range.  It will
+// assert in debug builds.  This is annoying.  We merrily grok chars > 256.
+static inline BOOL isspace(char c) {
+    return (c == ' ' || c == '\t' || c == '\n' || c == '\r'|| c == '\v' || c == '\f');
+}
 
 #else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+#define statinfo stat
 #endif
 
-extern void _processInfoDictionary(CFMutableDictionaryRef dict, CFStringRef platformSuffix, CFStringRef productSuffix);
-extern CFStringRef _CFGetProductName(void);
-extern CFStringRef _CFGetPlatformName(void);
-extern CFStringRef _CFGetAlternatePlatformName(void);
+__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);
 
@@ -199,18 +214,24 @@ struct __CFBundle {
 
     _CFPlugInData _plugInData;
 
-    CFSpinLock_t _bundleLoadingLock;
+    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 CFSpinLock_t CFBundleGlobalDataLock = CFSpinLockInit;
+static pthread_mutex_t CFBundleGlobalDataLock = PTHREAD_MUTEX_INITIALIZER;
 
 static CFMutableDictionaryRef _bundlesByIdentifier = NULL;
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
 static CFMutableDictionaryRef _bundlesByURL = NULL;
 static CFMutableArrayRef _allBundles = NULL;
 static CFMutableSetRef _bundlesToUnload = NULL;
@@ -230,7 +251,6 @@ static CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url,
 static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle);
 static void _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(CFStringRef hint);
 static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void);
-static void _CFBundleCheckWorkarounds(CFBundleRef bundle);
 static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath);
 static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths);
 #if defined(BINARY_SUPPORT_DYLD)
@@ -249,12 +269,12 @@ static CFStringRef _CFBundleDlfcnCopyLoadedImagePathForPointer(void *p);
 #endif /* BINARY_SUPPORT_DLFCN */
 
 
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
 
 static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) {
     CFStringRef bundleID = CFBundleGetIdentifier(bundle);
 
-    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
     
     // Add to the _allBundles list
     if (!_allBundles) {
@@ -302,11 +322,11 @@ static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) {
             CFRelease(bundlesWithThisID);
         }
     }
-    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef bundleID) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     // Remove from the various lists
     if (_allBundles) {
         CFIndex i = CFArrayGetFirstIndexOfValue(_allBundles, CFRangeMake(0, CFArrayGetCount(_allBundles)), bundle);
@@ -328,19 +348,19 @@ static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CF
             if (0 == CFArrayGetCount(bundlesWithThisID)) CFDictionaryRemoveValue(_bundlesByIdentifier, bundleID);
         }
     }
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 static CFBundleRef _CFBundleCopyBundleForURL(CFURLRef url, Boolean alreadyLocked) {
     CFBundleRef result = NULL;
-    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesByURL) result = (CFBundleRef)CFDictionaryGetValue(_bundlesByURL, url);
     if (result && !result->_url) {
         result = NULL;
         CFDictionaryRemoveValue(_bundlesByURL, url);
     }
     if (result) CFRetain(result);
-    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
     return result;
 }
 
@@ -419,7 +439,7 @@ static CFBundleRef _getFromBundlesByURL(CFURLRef key) {
 static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) {
     CFStringRef bundleID = CFBundleGetIdentifier(bundle);
 
-    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
     
     // Add to the _allBundles list
     if (!_allBundles) _allBundles = [[__CFHashTable alloc] initWithOptions:CFPointerFunctionsZeroingWeakMemory capacity:0];
@@ -458,11 +478,11 @@ static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) {
             [bundlesWithThisID release];
         }
     }
-    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef bundleID) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     // Remove from the various lists
     if (_allBundles && [_allBundles member:(id)bundle]) [_allBundles removeObject:(id)bundle];
 
@@ -481,19 +501,19 @@ static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CF
             if (0 == [bundlesWithThisID count]) CFDictionaryRemoveValue(_bundlesByIdentifier, bundleID);
         }
     }
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 static CFBundleRef _CFBundleCopyBundleForURL(CFURLRef url, Boolean alreadyLocked) {
     CFBundleRef result = NULL;
-    if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
     result = _getFromBundlesByURL(url);
     if (result && !result->_url) {
         result = NULL;
         _removeFromBundlesByURL(url);
     }
     if (result) CFRetain(result);
-    if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
     return result;
 }
 
@@ -526,11 +546,6 @@ static CFBundleRef _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(CFStri
 
 #endif /* AVOID_WEAK_COLLECTIONS */
 
-#if   DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
-
 static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
     //!!! need to handle frameworks, NT; need to integrate with NSBundle - drd
     UniChar buff[CFMaxPathSize];
@@ -542,7 +557,7 @@ static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
     if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize;
     CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff);
 
-#if   DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
     // Is this a .dll or .exe?
     if (buffLen >= 5 && (_wcsnicmp((wchar_t *)&(buff[buffLen-4]), L".dll", 4) == 0 || _wcsnicmp((wchar_t *)&(buff[buffLen-4]), L".exe", 4) == 0)) {
         CFIndex extensionLength = CFStringGetLength(_CFBundleWindowsResourceDirectoryExtension);
@@ -560,15 +575,11 @@ static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
             CFRelease(outstr);
         }
     }
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
     if (!url) {
         buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);  // Remove exe name
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
         if (buffLen > 0) {
             // See if this is a new bundle.  If it is, we have to remove more path components.
             CFIndex startOfLastDir = _CFStartOfLastPathComponent(buff, buffLen);
@@ -593,18 +604,11 @@ static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) {
                     if (buffLen > 0) {
                         // Remove support files folder
                         buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
                     }
                 }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
                 CFRelease(lastDirName);
             }
         }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
 
         if (buffLen > 0) {
             outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull);
@@ -891,9 +895,9 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean
     }
     if (bundle == _mainBundle) {
         CFStringRef executablePath = oldInfoDict ? (CFStringRef)CFDictionaryGetValue(oldInfoDict, _kCFBundleExecutablePathKey) : NULL;
-        if (!alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+        if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
         _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(executablePath);
-        if (!alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+        if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
     } else {
         CFBundleGetInfoDictionary(bundle);
     }
@@ -962,11 +966,10 @@ static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) {
                 _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(str);
                 // Perform delayed final processing steps.
                 // This must be done after _isLoaded has been set, for security reasons (3624341).
-                _CFBundleCheckWorkarounds(_mainBundle);
                 if (_CFBundleNeedsInitPlugIn(_mainBundle)) {
-                    __CFSpinUnlock(&CFBundleGlobalDataLock);
+                    pthread_mutex_unlock(&CFBundleGlobalDataLock);
                     _CFBundleInitPlugIn(_mainBundle);
-                    __CFSpinLock(&CFBundleGlobalDataLock);
+                    pthread_mutex_lock(&CFBundleGlobalDataLock);
                 }
             }
         }
@@ -979,19 +982,19 @@ static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) {
 
 CFBundleRef CFBundleGetMainBundle(void) {
     CFBundleRef mainBundle;
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     mainBundle = _CFBundleGetMainBundleAlreadyLocked();
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
     return mainBundle;
 }
 
 CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) {
     CFBundleRef result = NULL;
     if (bundleID) {
-        __CFSpinLock(&CFBundleGlobalDataLock);
+        pthread_mutex_lock(&CFBundleGlobalDataLock);
         (void)_CFBundleGetMainBundleAlreadyLocked();
         result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         if (!result) {
             // Try to create the bundle for the caller and try again
             void *p = __builtin_return_address(0);
@@ -1009,9 +1012,6 @@ CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) {
                 result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID);
             }
         }
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
         if (!result) {
             // Try to guess the bundle from the identifier and try again
@@ -1023,7 +1023,7 @@ CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) {
             _CFBundleEnsureAllBundlesUpToDateAlreadyLocked();
             result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID);
         }
-        __CFSpinUnlock(&CFBundleGlobalDataLock);
+        pthread_mutex_unlock(&CFBundleGlobalDataLock);
     }
     return result;
 }
@@ -1094,6 +1094,12 @@ static void __CFBundleDeallocate(CFTypeRef cf) {
         CFRelease(bundle->_glueDict);
     }
     if (bundle->_resourceData._stringTableCache) CFRelease(bundle->_resourceData._stringTableCache);
+    
+    // ZFH
+    if (bundle->_bundleBasePath) CFRelease(bundle->_bundleBasePath);
+    if (bundle->_queryTable) CFRelease(bundle->_queryTable);
+    
+    pthread_mutex_destroy(&(bundle->_bundleLoadingLock));
 }
 
 static const CFRuntimeClass __CFBundleClass = {
@@ -1109,7 +1115,7 @@ static const CFRuntimeClass __CFBundleClass = {
 };
 
 // From CFBundle_Resources.c
-void _CFBundleResourcesInitialize();
+__private_extern__ void _CFBundleResourcesInitialize();
 
 __private_extern__ void __CFBundleInitialize(void) {
     __kCFBundleTypeID = _CFRuntimeRegisterClass(&__CFBundleClass);
@@ -1212,13 +1218,10 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL,
     bundle->_isLoaded = false;
     bundle->_sharesStringsFiles = false;
     
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (!__CFgetenv("CFBundleDisableStringsSharing") && 
         (strncmp(buff, "/System/Library/Frameworks", 26) == 0) && 
         (strncmp(buff + strlen(buff) - 10, ".framework", 10) == 0)) bundle->_sharesStringsFiles = true;
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
     bundle->_connectionCookie = NULL;
@@ -1238,18 +1241,32 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL,
     bundle->_plugInData._instanceCount = 0;
     bundle->_plugInData._factories = NULL;
 
-    bundle->_bundleLoadingLock = CFSpinLockInit;
+    pthread_mutexattr_t mattr;
+    pthread_mutexattr_init(&mattr);
+    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_DEFAULT);
+    int32_t mret = pthread_mutex_init(&(bundle->_bundleLoadingLock), &mattr);
+    pthread_mutexattr_destroy(&mattr);
+    if (0 != mret) {
+        CFLog(4, CFSTR("%s: failed to initialize bundle loading lock for bundle %@."), __PRETTY_FUNCTION__, bundle);
+    }
+    
+    // ZFH
+    /* resource fast look up */
+    bundle->_queryLock = CFSpinLockInit;
+    bundle->_queryTable = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFURLRef absoURL = CFURLCopyAbsoluteURL(bundle->_url);
+    bundle->_bundleBasePath = CFURLCopyFileSystemPath(absoURL, PLATFORM_PATH_STYLE);
+    CFRelease(absoURL);
     
     CFBundleGetInfoDictionary(bundle);
     
     _CFBundleAddToTables(bundle, alreadyLocked);
 
     if (doFinalProcessing) {
-        _CFBundleCheckWorkarounds(bundle);
         if (_CFBundleNeedsInitPlugIn(bundle)) {
-            if (alreadyLocked) __CFSpinUnlock(&CFBundleGlobalDataLock);
+            if (alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock);
             _CFBundleInitPlugIn(bundle);
-            if (alreadyLocked) __CFSpinLock(&CFBundleGlobalDataLock);
+            if (alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock);
         }
     }
     
@@ -1362,7 +1379,7 @@ CFDictionaryRef _CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
 }
 
 CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
-    static CFSpinLock_t CFBundleLocalInfoLock = CFSpinLockInit;
+    static pthread_mutex_t CFBundleLocalInfoLock = PTHREAD_MUTEX_INITIALIZER;
     CFDictionaryRef localInfoDict = bundle->_localInfoDict;
     if (!localInfoDict) {
         CFURLRef url = CFBundleCopyResourceURL(bundle, _CFBundleLocalInfoName, _CFBundleStringTableType, NULL);
@@ -1383,14 +1400,14 @@ CFDictionaryRef CFBundleGetLocalInfoDictionary(CFBundleRef bundle) {
             CFRelease(url);
         }
         if (localInfoDict) _processInfoDictionary((CFMutableDictionaryRef)localInfoDict, _CFGetPlatformName(), _CFGetProductName());
-        __CFSpinLock(&CFBundleLocalInfoLock);
+        pthread_mutex_lock(&CFBundleLocalInfoLock);
         if (!bundle->_localInfoDict) {
             bundle->_localInfoDict = localInfoDict;
         } else {
             if (localInfoDict && !_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(localInfoDict);
             localInfoDict = bundle->_localInfoDict;
         }
-        __CFSpinUnlock(&CFBundleLocalInfoLock);
+        pthread_mutex_unlock(&CFBundleLocalInfoLock);
     }
     return localInfoDict;
 }
@@ -1692,7 +1709,7 @@ static Boolean _urlExists(CFURLRef url) {
 // See <rdar://problem/6956670>
 static Boolean _binaryLoadable(CFURLRef url) {
     Boolean loadable = _urlExists(url);
-#if DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (!loadable) {
        uint8_t path[PATH_MAX];
        if (url && CFURLGetFileSystemRepresentation(url, true, path, sizeof(path))) {
@@ -1764,7 +1781,7 @@ static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeN
     CFURLRef executableURL = NULL;
     if (!urlPath || !exeName) return NULL;
     
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     const uint8_t *image_suffix = (uint8_t *)__CFgetenv("DYLD_IMAGE_SUFFIX");
     if (image_suffix) {
         CFStringRef newExeName, imageSuffix;
@@ -1831,8 +1848,6 @@ static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeN
             CFRelease(newExeName);
         }
     }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     return executableURL;
 }
@@ -1878,15 +1893,66 @@ 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 = CFBundleCopyResourceURL(bundle, executableName, CFSTR("rsrc"), NULL);
+            resourceForkURL = (CFURLRef) _CFBundleCopyFindResourcesWithNoBlock(bundle, NULL, NULL, executableName, type, NULL, NULL, NO, NO);            
         } else {
-            resourceForkURL = CFBundleCopyResourceURLForLocalization(bundle, executableName, CFSTR("rsrc"), NULL, NULL);
+            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);
     }
     
@@ -1920,12 +1986,10 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
         if (executablePath) CFRetain(executablePath);
         __CFSpinUnlock(&CFBundleExecutablePathLock);
         if (executablePath) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif 
             if (executableURL) {
                 foundIt = true;
@@ -1941,14 +2005,14 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
     if (!foundIt) {
         if (lookupMainExe) executableName = _CFBundleCopyExecutableName(bundle, url, infoDict);
         if (executableName) {
-#if DEPLOYMENT_TARGET_EMBEDDED
+#if (DEPLOYMENT_TARGET_EMBEDDED && !TARGET_IPHONE_SIMULATOR)
             Boolean doExecSearch = false;
 #else
             Boolean doExecSearch = true;
 #endif
             // Now, look for the executable inside the bundle.
             if (doExecSearch && 0 != version) {
-                CFURLRef exeDirURL;
+                CFURLRef exeDirURL = NULL;
                 CFURLRef exeSubdirURL;
 
                 if (1 == version) {
@@ -1964,10 +2028,8 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                     } else {
                         exeDirURL = (CFURLRef)CFRetain(url);
                     }
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                     exeDirURL = (CFURLRef)CFRetain(url);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
                 }
                 CFStringRef platformSubDir = useOtherPlatform ? _CFBundleGetOtherPlatformExecutablesSubdirectoryName() : _CFBundleGetPlatformExecutablesSubdirectoryName();
@@ -2007,9 +2069,6 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                 executableURL = _CFBundleCopyExecutableURLRaw(exeDirURL, executableName);
                 CFRelease(exeDirURL);
             }
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
             if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && infoDict && executableURL) {
@@ -2017,10 +2076,8 @@ static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURL
                 CFURLRef absURL = CFURLCopyAbsoluteURL(executableURL);
 #if DEPLOYMENT_TARGET_WINDOWS
                 executablePath = CFURLCopyFileSystemPath(absURL, kCFURLWindowsPathStyle);
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                 executablePath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
                 CFRelease(absURL);
                 __CFSpinLock(&CFBundleExecutablePathLock);
@@ -2289,7 +2346,7 @@ static Boolean _CFBundleGrokX11FromFile(int fd, const void *bytes, CFIndex lengt
     
 // returns zero-ref dictionary under GC
 static CFDictionaryRef _CFBundleGrokInfoDictFromFile(int fd, const void *bytes, CFIndex length, uint32_t offset, Boolean swapped, Boolean sixtyFour) {
-    struct stat statBuf;
+    struct statinfo statBuf;
     off_t fileLength = 0;
     char *maploc = NULL;
     const char *loc;
@@ -2598,6 +2655,15 @@ static Boolean _CFBundleGrokFileTypeForZipMimeType(const unsigned char *bytes, C
     } else if (bytes < data && data + 41 <= bytes + length && 8 == CFSwapInt16HostToLittle(*((UInt16 *)(bytes + 8))) && 0x4b2c28c8 == CFSwapInt32HostToBig(*((UInt32 *)data)) && 0xc94c4e2c == CFSwapInt32HostToBig(*((UInt32 *)(data + 4)))) {
         // AbiWord compressed mimetype odt
         if (ext) *ext = "odt";
+        // almost certainly this should set i to 0 but I don't want to upset the apple cart now
+    } else if (bytes < data && data + 29 <= bytes + length && (0 == ustrncasecmp(data, "application/oebps-package+xml", 29))) {
+        // epub, official epub 3 mime type
+        if (ext) *ext = "epub";
+        i = 0;
+    } else if (bytes < data && data + 20 <= bytes + length && (0 == ustrncasecmp(data, "application/epub+zip", 20))) {
+        // epub, unofficial epub 2 mime type
+        if (ext) *ext = "epub";
+        i = 0;
     }
     return (i >= 0);
 }
@@ -2732,14 +2798,6 @@ static const char *_CFBundleGrokFileTypeForOLEFile(int fd, const void *bytes, CF
     return ext;
 }
 
-#if DEPLOYMENT_TARGET_WINDOWS
-// Windows isspace implementation limits the input chars to < 256 in the ASCII range.  It will
-// assert in debug builds.  This is annoying.  We merrily grok chars > 256.
-static inline BOOL isspace(char c) {
-    return (c == ' ' || c == '\t' || c == '\n' || c == '\r'|| c == '\v' || c == '\f');
-}
-#endif
-
 // 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;
@@ -2766,13 +2824,7 @@ static Boolean _CFBundleGrokFileType(CFURLRef url, CFDataRef data, CFStringRef *
         Boolean gotPath = FALSE;
         char path[CFMaxPathSize];
         gotPath = CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-        struct stat statBuf;
-#elif DEPLOYMENT_TARGET_WINDOWS
-        struct _stat statBuf;
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
+        struct statinfo statBuf;
         if (gotPath && stat(path, &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG && (fd = open(path, O_RDONLY | CF_OPENFLGS, 0777)) >= 0) {
             length = read(fd, buffer, MAGIC_BYTES_TO_READ);
             fileLength = statBuf.st_size;
@@ -3161,7 +3213,7 @@ Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceG
     CFErrorRef localError = NULL, *subError = (error ? &localError : NULL);
     CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
 
-    __CFSpinLock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_lock(&(bundle->_bundleLoadingLock));
     if (!executableURL) bundle->_binaryType = __CFBundleNoBinary;
     // make sure we know whether bundle is already loaded or not
 #if defined(BINARY_SUPPORT_DLFCN)
@@ -3179,38 +3231,38 @@ Boolean _CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, Boolean forceG
     if (executableURL) CFRelease(executableURL);
     
     if (bundle->_isLoaded) {
-        __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
         // Remove from the scheduled unload set if we are there.
-        __CFSpinLock(&CFBundleGlobalDataLock);
-#if defined(AVOID_WEAK_COLLECTIONS)
+        pthread_mutex_lock(&CFBundleGlobalDataLock);
+#if AVOID_WEAK_COLLECTIONS
         if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle);
 #else /* AVOID_WEAK_COLLECTIONS */
         if (_bundlesToUnload) [_bundlesToUnload removeObject:(id)bundle];
 #endif /* AVOID_WEAK_COLLECTIONS */
-        __CFSpinUnlock(&CFBundleGlobalDataLock);
+        pthread_mutex_unlock(&CFBundleGlobalDataLock);
         return true;
     }
 
     // Unload bundles scheduled for unloading
     if (!_scheduledBundlesAreUnloading) {
-        __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
         _CFBundleUnloadScheduledBundles();
-        __CFSpinLock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_lock(&(bundle->_bundleLoadingLock));
     }
     
     if (bundle->_isLoaded) {
-        __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
         // Remove from the scheduled unload set if we are there.
-        __CFSpinLock(&CFBundleGlobalDataLock);
-#if defined(AVOID_WEAK_COLLECTIONS)
+        pthread_mutex_lock(&CFBundleGlobalDataLock);
+#if AVOID_WEAK_COLLECTIONS
         if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle);
 #else /* AVOID_WEAK_COLLECTIONS */
         if (_bundlesToUnload) [_bundlesToUnload removeObject:(id)bundle];
 #endif /* AVOID_WEAK_COLLECTIONS */
-        __CFSpinUnlock(&CFBundleGlobalDataLock);
+        pthread_mutex_unlock(&CFBundleGlobalDataLock);
         return true;
     }
-    __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
 
     switch (bundle->_binaryType) {
 #if defined(BINARY_SUPPORT_DLFCN)
@@ -3288,7 +3340,7 @@ Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) {
 #endif
     CFURLRef executableURL = CFBundleCopyExecutableURL(bundle);
 
-    __CFSpinLock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_lock(&(bundle->_bundleLoadingLock));
     if (!executableURL) bundle->_binaryType = __CFBundleNoBinary;
     // make sure we know whether bundle is already loaded or not
 #if defined(BINARY_SUPPORT_DLFCN)
@@ -3306,10 +3358,10 @@ Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) {
     if (executableURL) CFRelease(executableURL);
     
     if (bundle->_isLoaded) {
-        __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
         return true;
     }
-    __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
     
     switch (bundle->_binaryType) {
 #if defined(BINARY_SUPPORT_DLFCN)
@@ -3388,23 +3440,23 @@ void CFBundleUnloadExecutable(CFBundleRef bundle) {
     if (!bundle->_isLoaded) return;
 
     // Remove from the scheduled unload set if we are there.
-    if (!_scheduledBundlesAreUnloading) __CFSpinLock(&CFBundleGlobalDataLock);
-#if defined(AVOID_WEAK_COLLECTIONS)
+    if (!_scheduledBundlesAreUnloading) pthread_mutex_lock(&CFBundleGlobalDataLock);
+#if AVOID_WEAK_COLLECTIONS
     if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle);
 #else /* AVOID_WEAK_COLLECTIONS */
     if (_bundlesToUnload) [_bundlesToUnload removeObject:(id)bundle];
 #endif /* AVOID_WEAK_COLLECTIONS */
-    if (!_scheduledBundlesAreUnloading) __CFSpinUnlock(&CFBundleGlobalDataLock);
+    if (!_scheduledBundlesAreUnloading) pthread_mutex_unlock(&CFBundleGlobalDataLock);
     
     // Give the plugIn code a chance to realize this...
     _CFPlugInWillUnload(bundle);
 
-    __CFSpinLock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_lock(&(bundle->_bundleLoadingLock));
     if (!bundle->_isLoaded) {
-        __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+        pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
         return;
     }
-    __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+    pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
 
     switch (bundle->_binaryType) {
 #if defined(BINARY_SUPPORT_DYLD)
@@ -3439,10 +3491,10 @@ void CFBundleUnloadExecutable(CFBundleRef bundle) {
     }
 }
 
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
 
 __private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (!_bundlesToUnload) {
         CFSetCallBacks nonRetainingCallbacks = kCFTypeSetCallBacks;
         nonRetainingCallbacks.retain = NULL;
@@ -3450,17 +3502,17 @@ __private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
         _bundlesToUnload = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &nonRetainingCallbacks);
     }
     CFSetAddValue(_bundlesToUnload, bundle);
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 __private_extern__ void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) CFSetRemoveValue(_bundlesToUnload, bundle);
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 __private_extern__ void _CFBundleUnloadScheduledBundles(void) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) {
         CFIndex i, c = CFSetGetCount(_bundlesToUnload);
         if (c > 0) {
@@ -3475,26 +3527,26 @@ __private_extern__ void _CFBundleUnloadScheduledBundles(void) {
             CFAllocatorDeallocate(kCFAllocatorSystemDefault, unloadThese);
         }
     }
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 #else /* AVOID_WEAK_COLLECTIONS */
 
 __private_extern__ void _CFBundleScheduleForUnloading(CFBundleRef bundle) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (!_bundlesToUnload) _bundlesToUnload = [[__CFHashTable alloc] initWithOptions:CFPointerFunctionsZeroingWeakMemory capacity:0];
     [_bundlesToUnload addObject:(id)bundle];
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 __private_extern__ void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload) [_bundlesToUnload removeObject:(id)bundle];
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 __private_extern__ void _CFBundleUnloadScheduledBundles(void) {
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     if (_bundlesToUnload && [_bundlesToUnload count] > 0) {
         CFIndex i, c;
         CFMutableArrayRef unloadThese = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
@@ -3510,7 +3562,7 @@ __private_extern__ void _CFBundleUnloadScheduledBundles(void) {
         }
         CFRelease(unloadThese);
     }
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
 }
 
 #endif /* AVOID_WEAK_COLLECTIONS */
@@ -3660,13 +3712,10 @@ __private_extern__ Boolean _CFBundleCouldBeBundle(CFURLRef url) {
 //If 'permissive' is set, we will maintain the historical behavior of returning frameworks with names that don't match, and frameworks for executables in Resources/
 static CFURLRef __CFBundleCopyFrameworkURLForExecutablePath(CFStringRef executablePath, Boolean permissive) {
     // MF:!!! Implement me.  We need to be able to find the bundle from the exe, dealing with old vs. new as well as the Executables dir business on Windows.
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
     UniChar executablesToFrameworksPathBuff[] = {'.', '.', '\\', 'F', 'r', 'a', 'm', 'e', 'w', 'o', 'r', 'k', 's'};
     UniChar executablesToPrivateFrameworksPathBuff[] = {'.', '.', '\\', 'P', 'r', 'i', 'v', 'a', 't', 'e', 'F', 'r', 'a', 'm', 'e', 'w', 'o', 'r', 'k', 's'};
     UniChar frameworksExtension[] = {'f', 'r', 'a', 'm', 'e', 'w', 'o', 'r', 'k'};
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     UniChar pathBuff[CFMaxPathSize] = {0};
     UniChar nameBuff[CFMaxPathSize] = {0};
@@ -3710,10 +3759,6 @@ static CFURLRef __CFBundleCopyFrameworkURLForExecutablePath(CFStringRef executab
             }
         }
     }
-            
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     // * Finally check the executable inside the framework case.
     if (!bundleURL) {        
@@ -3783,7 +3828,7 @@ static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath) {
             createdBundle = true;
         }
         if (bundle) {
-            __CFSpinLock(&(bundle->_bundleLoadingLock));
+            pthread_mutex_lock(&(bundle->_bundleLoadingLock));
             if (!bundle->_isLoaded) {
                 // make sure that these bundles listed as loaded, and mark them frameworks (we probably can't see anything else here, and we cannot unload them)
     #if defined(BINARY_SUPPORT_DLFCN)
@@ -3800,15 +3845,14 @@ static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath) {
     #endif /* LOG_BUNDLE_LOAD */
                 bundle->_isLoaded = true;
             }
-            __CFSpinUnlock(&(bundle->_bundleLoadingLock));
+            pthread_mutex_unlock(&(bundle->_bundleLoadingLock));
             if (createdBundle) {
                 // Perform delayed final processing steps.
                 // This must be done after _isLoaded has been set, for security reasons (3624341).
-                _CFBundleCheckWorkarounds(bundle);
                 if (_CFBundleNeedsInitPlugIn(bundle)) {
-                    __CFSpinUnlock(&CFBundleGlobalDataLock);
+                    pthread_mutex_unlock(&CFBundleGlobalDataLock);
                     _CFBundleInitPlugIn(bundle);
-                    __CFSpinLock(&CFBundleGlobalDataLock);
+                    pthread_mutex_lock(&CFBundleGlobalDataLock);
                 }
             } else {
                 // Release the bundle if we did not create it here
@@ -3860,13 +3904,13 @@ static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void) {
 
 CFArrayRef CFBundleGetAllBundles(void) {
     // To answer this properly, we have to have created the static bundles!
-#if !defined(AVOID_WEAK_COLLECTIONS)
+#if !AVOID_WEAK_COLLECTIONS
     static CFMutableArrayRef externalAllBundles = NULL;
 #endif /* AVOID_WEAK_COLLECTIONS */
     CFArrayRef bundles;
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     _CFBundleEnsureAllBundlesUpToDateAlreadyLocked();
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
     bundles = _allBundles;
 #else /* AVOID_WEAK_COLLECTIONS */
     if (!externalAllBundles) {
@@ -3879,21 +3923,21 @@ CFArrayRef CFBundleGetAllBundles(void) {
     for (id value in _allBundles) CFArrayAppendValue(externalAllBundles, value);
     bundles = externalAllBundles;
 #endif /* AVOID_WEAK_COLLECTIONS */
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
     return bundles;
 }
         
 CF_EXPORT CFArrayRef _CFBundleCopyAllBundles(void) {
     // To answer this properly, we have to have created the static bundles!
-    __CFSpinLock(&CFBundleGlobalDataLock);
+    pthread_mutex_lock(&CFBundleGlobalDataLock);
     _CFBundleEnsureAllBundlesUpToDateAlreadyLocked();
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
     CFArrayRef bundles = CFArrayCreateCopy(kCFAllocatorSystemDefault, _allBundles);
 #else /* AVOID_WEAK_COLLECTIONS */
     CFMutableArrayRef bundles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     for (id value in _allBundles) CFArrayAppendValue(bundles, value);
 #endif /* AVOID_WEAK_COLLECTIONS */
-    __CFSpinUnlock(&CFBundleGlobalDataLock);
+    pthread_mutex_unlock(&CFBundleGlobalDataLock);
     return bundles;
 }
 
@@ -3901,13 +3945,113 @@ uint8_t _CFBundleLayoutVersion(CFBundleRef bundle) {
     return bundle->_version;
 }
 
+static void __addPlatformAndProductNamesToKeys(const void *value, void *context) {
+    CFMutableSetRef newKeys = (CFMutableSetRef)context;
+    CFStringRef key = (CFStringRef)value;
+    CFStringRef firstPartOfKey = NULL;
+    CFStringRef restOfKey = NULL;
+    
+    // Find the first ':'
+    CFRange range;
+    Boolean success = CFStringFindWithOptions(key, CFSTR(":"), CFRangeMake(0, CFStringGetLength(key)), 0, &range);
+    if (success) {
+        firstPartOfKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, key, CFRangeMake(0, range.location));
+        restOfKey = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, key, CFRangeMake(range.location + 1, CFStringGetLength(key) - range.location - 1));
+    } else {
+        firstPartOfKey = (CFStringRef)CFRetain(key);
+    }
+    
+    // only apply product and platform to top-level key
+    CFStringRef newKeyWithPlatform = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@-%@%@%@"), firstPartOfKey, _CFGetPlatformName(), restOfKey ? CFSTR(":") : CFSTR(""), restOfKey ? restOfKey : CFSTR(""));
+    CFStringRef newKeyWithProduct = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@~%@%@%@"), firstPartOfKey, _CFGetProductName(), restOfKey ? CFSTR(":") : CFSTR(""), restOfKey ? restOfKey : CFSTR(""));
+    CFStringRef newKeyWithProductAndPlatform = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@-%@~%@%@%@"), firstPartOfKey, _CFGetPlatformName(), _CFGetProductName(), restOfKey ? CFSTR(":") : CFSTR(""), restOfKey ? restOfKey : CFSTR(""));
+    
+    CFSetAddValue(newKeys, key);
+    CFSetAddValue(newKeys, newKeyWithPlatform);
+    CFSetAddValue(newKeys, newKeyWithProduct);
+    CFSetAddValue(newKeys, newKeyWithProductAndPlatform);
+    
+    if (firstPartOfKey) CFRelease(firstPartOfKey);
+    if (restOfKey) CFRelease(restOfKey);
+    CFRelease(newKeyWithPlatform);
+    CFRelease(newKeyWithProduct);
+    CFRelease(newKeyWithProductAndPlatform);
+}
+
+// from CFUtilities.c
+__private_extern__ 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) {
+    CFPropertyListRef result = NULL;
+
+    if (!infoPlistURL) return CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    CFURLRef absoluteURL = CFURLCopyAbsoluteURL(infoPlistURL);
+    CFStringRef filePath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+    CFRelease(absoluteURL);
+
+    if (!filePath) return CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    void *bytes = NULL;
+    CFIndex length = 0;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    Boolean mapped = options & _CFBundleFilteredPlistMemoryMapped ? true : false;
+#else
+    Boolean mapped = false;
+#endif
+    Boolean success = _CFReadMappedFromFile(filePath, mapped, false, &bytes, &length, NULL);
+    CFRelease(filePath);
+    if (!success) return CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+
+    CFDataRef infoPlistData = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, (const UInt8 *)bytes, length, kCFAllocatorNull);
+    // We need to include all possible variants of the platform/product combo as possible keys.
+    CFMutableSetRef newKeyPaths = CFSetCreateMutable(kCFAllocatorSystemDefault, CFSetGetCount(keyPaths), &kCFTypeSetCallBacks);
+    CFSetApplyFunction(keyPaths, __addPlatformAndProductNamesToKeys, newKeyPaths);
+    
+    success = _CFPropertyListCreateFiltered(kCFAllocatorSystemDefault, infoPlistData, kCFPropertyListMutableContainers, newKeyPaths, &result, NULL);
+    
+    if (!success) {
+        result = CFDictionaryCreate(kCFAllocatorSystemDefault, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    } else {
+        _processInfoDictionary((CFMutableDictionaryRef)result, _CFGetPlatformName(), _CFGetProductName());
+    }
+    
+    CFRelease(newKeyPaths);
+    CFRelease(infoPlistData);
+    if (mapped) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+        munmap(bytes, length);
+#endif
+    } else {
+        free(bytes);
+    }
+    
+    return result;
+}
+
+// Returns a subset of the bundle's 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. If the Info.plist does not exist or could not be parsed, you will get back an empty dictionary.
+CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) {
+    CFURLRef infoPlistURL = _CFBundleCopyInfoPlistURL(bundle);
+    CFPropertyListRef result = _CFBundleCreateFilteredInfoPlistWithURL(infoPlistURL, keyPaths, options);
+    if (infoPlistURL) CFRelease(infoPlistURL);
+    return result;
+}
+
+CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredLocalizedInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, CFStringRef localizationName, _CFBundleFilteredPlistOptions options) {
+    CFURLRef infoPlistURL = CFBundleCopyResourceURLForLocalization(bundle, _CFBundleLocalInfoName, _CFBundleStringTableType, NULL, localizationName);
+    CFPropertyListRef result = _CFBundleCreateFilteredInfoPlistWithURL(infoPlistURL, keyPaths, options);
+    if (infoPlistURL) CFRelease(infoPlistURL);
+    return result;
+}
+
 CF_EXPORT CFURLRef _CFBundleCopyInfoPlistURL(CFBundleRef bundle) {
     CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
     CFURLRef url = (CFURLRef)CFDictionaryGetValue(infoDict, _kCFBundleInfoPlistURLKey);
     if (!url) url = (CFURLRef)CFDictionaryGetValue(infoDict, _kCFBundleRawInfoPlistURLKey);
     return (url ? (CFURLRef)CFRetain(url) : NULL);
 }
-
+        
 CF_EXPORT CFURLRef _CFBundleCopyPrivateFrameworksURL(CFBundleRef bundle) {
     return CFBundleCopyPrivateFrameworksURL(bundle);
 }
@@ -4443,9 +4587,12 @@ CF_EXPORT Boolean _CFBundleDlfcnPreflight(CFBundleRef bundle, CFErrorRef *error)
                     }
 #if defined(BINARY_SUPPORT_DYLD)
                     if (hasSuitableArch) {
-                        uint32_t mainFlags = 0, bundleFlags = 0;
+                        uint32_t mainFlags = 0;
                         if (_CFBundleGrokObjCImageInfoFromMainExecutable(NULL, &mainFlags) && (mainFlags & 0x2) != 0) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+                            uint32_t bundleFlags = 0;
                             if (_CFBundleGetObjCImageInfo(bundle, NULL, &bundleFlags) && (bundleFlags & 0x2) == 0) hasRuntimeMismatch = true;
+#endif
                         }
                     }
 #endif /* BINARY_SUPPORT_DYLD */
@@ -4683,7 +4830,51 @@ __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;
+}
 
-static void _CFBundleCheckWorkarounds(CFBundleRef bundle) {
+// 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 7797987c374fae035bfb3141d0bd040b288c59ed..304ab6a1f9d45e3c0b640f3d9c38065fc21c31f5 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE__)
@@ -261,14 +261,12 @@ CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) CF_AVAILABLE(
 CF_EXPORT
 CFURLRef CFBundleCopyExecutableURL(CFBundleRef bundle);
 
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
 enum {
     kCFBundleExecutableArchitectureI386     = 0x00000007,
     kCFBundleExecutableArchitecturePPC      = 0x00000012,
     kCFBundleExecutableArchitectureX86_64   = 0x01000007,
     kCFBundleExecutableArchitecturePPC64    = 0x01000012
-};
-#endif /* MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED */
+} CF_ENUM_AVAILABLE(10_5, 2_0);
 
 CF_EXPORT
 CFArrayRef CFBundleCopyExecutableArchitectures(CFBundleRef bundle) CF_AVAILABLE(10_5, 2_0);
index a78efcbfbe7ce1eb70dd1b3b654ece56059ea8eb..97b5402e4db42f37009b4583cbf44a2c8abf641b 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundlePriv.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLEPRIV__)
index 49d8f63954fef23c6b6c0e9bbf38a43762b89b3e..a85bae679ee9b5189cd4f37559e79c7acd0f3bdc 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle_BinaryTypes.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE_BINARYTYPES__)
@@ -34,12 +34,10 @@ CF_EXTERN_C_BEGIN
 #define BINARY_SUPPORT_DYLD 1
 #define BINARY_SUPPORT_DLFCN 1
 #define USE_DYLD_PRIV 1
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define BINARY_SUPPORT_DYLD 1
 #define BINARY_SUPPORT_DLFCN 1
-#if !defined(TARGET_IPHONE_SIMULATOR)
 #define USE_DYLD_PRIV 1
-#endif
 #elif DEPLOYMENT_TARGET_WINDOWS
 #define BINARY_SUPPORT_DLL 1
 #else
index 9da42d5f35de2b7c1ff3542eeeb907052801e653..b612fd9eacdcf5e301789393cdb74fe926d699f4 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFBundle_Internal.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBUNDLE_INTERNAL__)
@@ -41,12 +41,10 @@ CF_EXTERN_C_BEGIN
 #define __kCFLogBundle       3
 #define __kCFLogPlugIn       3
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#define PLATFORM_PATH_STYLE kCFURLPOSIXPathStyle
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
 #define PLATFORM_PATH_STYLE kCFURLWindowsPathStyle
 #else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+#define PLATFORM_PATH_STYLE kCFURLPOSIXPathStyle
 #endif
 
 #define CFBundleExecutableNotFoundError             4
@@ -56,6 +54,12 @@ 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
+
 typedef struct __CFResourceData {
     CFMutableDictionaryRef _stringTableCache;
     Boolean _executableLacksResourceFork;
@@ -90,7 +94,9 @@ extern CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL
 extern Boolean _CFBundleCouldBeBundle(CFURLRef url);
 extern CFURLRef _CFBundleCopyResourceForkURLMayBeLocal(CFBundleRef bundle, Boolean mayBeLocal);
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInResourceForkWithAllocator(CFAllocatorRef alloc, CFURLRef url);
-extern CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBundleRef bundle);
+#if DEPLOYMENT_TARGET_MACOSX
+__private_extern__ CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBundleRef bundle);
+#endif
 extern CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url);
 extern CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url);
 
@@ -108,6 +114,13 @@ 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);
 
 #if defined(BINARY_SUPPORT_DYLD)
 // DYLD API
@@ -152,8 +165,8 @@ extern void _CFPlugInWillUnload(CFPlugInRef plugIn);
 extern void _CFPlugInAddPlugInInstance(CFPlugInRef plugIn);
 extern void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn);
 
-extern void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactory *factory);
-extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactory *factory);
+extern void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory);
+extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory);
 
 
 /* Strings for parsing bundle structure */
@@ -205,6 +218,11 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactory *factory);
 
 #define _CFBundleLprojExtension CFSTR("lproj")
 #define _CFBundleLprojExtensionWithDot CFSTR(".lproj")
+#define _CFBundleDot CFSTR(".")
+#define _CFBundleAllFiles CFSTR("_CFBAF_")
+#define _CFBundleTypeIndicator CFSTR("_CFBT_")
+// This directory contains resources (especially nibs) that may look up localized resources or may fall back to the development language resources
+#define _CFBundleBaseDirectory CFSTR("Base")
 
 #define _CFBundleMacOSXPlatformName CFSTR("macos")
 #define _CFBundleAlternateMacOSXPlatformName CFSTR("macosx")
@@ -226,9 +244,7 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactory *factory);
 
 #define _CFBundleLocalizedResourceForkFileName CFSTR("Localized")
 
-#if DEPLOYMENT_TARGET_WINDOWS
 #define _CFBundleWindowsResourceDirectoryExtension CFSTR("resources")
-#endif
 
 /* Old platform names (no longer used) */
 #define _CFBundleMacOSXPlatformName_OLD CFSTR("macintosh")
index a985bd267b7dface29d7f8d5efcd5acdc1600199..ec36901ef04347209c12684c95de7a3e9fc1a03f 100644 (file)
  */
 
 /*      CFBundle_Resources.c
-        Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
-#if DEPLOYMENT_TARGET_MACOSX
-#define READ_DIRECTORIES 1
-#elif DEPLOYMENT_TARGET_EMBEDDED
-#define READ_DIRECTORIES 1
-#elif DEPLOYMENT_TARGET_WINDOWS
-#define READ_DIRECTORIES 0
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
-
 #define READ_DIRECTORIES_CACHE_CAPACITY 128
 
 #include "CFBundle_Internal.h"
 #include <ctype.h>
 #include <errno.h>
 #include <sys/types.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
+#include <unistd.h>
 #include <sys/sysctl.h>
+#include <sys/stat.h>
+#include <dirent.h>
 #endif
 
 #if DEPLOYMENT_TARGET_MACOSX
-#include <unistd.h>
-#elif DEPLOYMENT_TARGET_EMBEDDED
-#include <unistd.h>
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+
 #endif
 
-#if READ_DIRECTORIES
-#include <dirent.h>
-#endif /* READ_DIRECTORIES */
+#if DEPLOYMENT_TARGET_WINDOWS
+#include <io.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <errno.h>
+
+#define close _close
+#define write _write
+#define read _read
+#define open _NS_open
+#define stat _NS_stat
+#define fstat _fstat
+#define mkdir(a,b) _NS_mkdir(a)
+#define rmdir _NS_rmdir
+#define unlink _NS_unlink
+
+#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));
@@ -80,13 +85,13 @@ static inline Boolean _CFBundleSortedArrayContains(CFArrayRef arr, CFStringRef t
     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 Windows
-// This is here to make sure it gets updated when _CFGetPlatformName does
+// 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" };
 
-// This is here to make sure it gets updated when _CFGetProductName does
 #define _CFBundleNumberOfProducts 3
 static CFStringRef _CFBundleSupportedProducts[_CFBundleNumberOfProducts] = { NULL, NULL, NULL };
 static const char *_CFBundleSupportedProductStrings[_CFBundleNumberOfProducts] = { "iphone", "ipod", "ipad" };
@@ -95,7 +100,7 @@ static const char *_CFBundleSupportedProductStrings[_CFBundleNumberOfProducts] =
 static CFStringRef _CFBundleSupportediPhoneOSPlatformProducts[_CFBundleNumberOfiPhoneOSPlatformProducts] = { NULL, NULL, NULL };
 static const char *_CFBundleSupportediPhoneOSPlatformProductStrings[_CFBundleNumberOfiPhoneOSPlatformProducts] = { "iphone", "ipod", "ipad" };
 
-void _CFBundleResourcesInitialize() {
+__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);
@@ -103,6 +108,27 @@ void _CFBundleResourcesInitialize() {
     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) {
@@ -115,8 +141,8 @@ void _CFSetProductName(CFStringRef str) {
     // shouldn't be screwing around with this value casually.
 }
 
-CFStringRef _CFGetProductName(void) {
-#if DEPLOYMENT_TARGET_EMBEDDED
+CF_EXPORT CFStringRef _CFGetProductName(void) {
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
    if (!platform) {
       char buffer[256];
       memset(buffer, 0, sizeof(buffer));
@@ -152,10 +178,10 @@ CFStringRef _CFGetProductName(void) {
 }
 
 // All new-style bundles will have these extensions.
-__private_extern__ CFStringRef _CFGetPlatformName(void) {
+CF_EXPORT CFStringRef _CFGetPlatformName(void) {
 #if DEPLOYMENT_TARGET_MACOSX 
     return _CFBundleMacOSXPlatformName;
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return _CFBundleiPhoneOSPlatformName;
 #elif DEPLOYMENT_TARGET_WINDOWS
     return _CFBundleWindowsPlatformName;
@@ -172,10 +198,10 @@ __private_extern__ CFStringRef _CFGetPlatformName(void) {
 #endif
 }
 
-__private_extern__ CFStringRef _CFGetAlternatePlatformName(void) {
+CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void) {
 #if DEPLOYMENT_TARGET_MACOSX
     return _CFBundleAlternateMacOSXPlatformName;
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return _CFBundleMacOSXPlatformName;
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("");
@@ -184,7 +210,6 @@ __private_extern__ CFStringRef _CFGetAlternatePlatformName(void) {
 #endif
 }
 
-static CFSpinLock_t CFBundleResourceGlobalDataLock = CFSpinLockInit;
 static UniChar *_AppSupportUniChars1 = NULL;
 static CFIndex _AppSupportLen1 = 0;
 static UniChar *_AppSupportUniChars2 = NULL;
@@ -197,13 +222,17 @@ 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];
@@ -218,6 +247,7 @@ static void _CFBundleInitStaticUniCharBuffers(void) {
     CFStringRef lprojStr = _CFBundleLprojExtension;
     CFStringRef globalResourcesStr = _CFBundleNonLocalizedResourcesDirectoryName;
     CFStringRef infoExtensionStr = _CFBundleInfoExtension;
+    CFStringRef baseStr = _CFBundleBaseDirectory;
 
     _AppSupportLen1 = CFStringGetLength(appSupportStr1);
     _AppSupportLen2 = CFStringGetLength(appSupportStr2);
@@ -227,8 +257,9 @@ static void _CFBundleInitStaticUniCharBuffers(void) {
     _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), 0);
+    _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;
@@ -236,7 +267,8 @@ static void _CFBundleInitStaticUniCharBuffers(void) {
     _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);
@@ -245,6 +277,7 @@ static void _CFBundleInitStaticUniCharBuffers(void) {
     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] = '-';
@@ -258,24 +291,26 @@ static void _CFBundleInitStaticUniCharBuffers(void) {
     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) {
-    __CFSpinLock(&CFBundleResourceGlobalDataLock);
-    if (!_AppSupportUniChars1) _CFBundleInitStaticUniCharBuffers();
-    __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+    static dispatch_once_t once = 0;
+    dispatch_once(&once, ^{
+        _CFBundleInitStaticUniCharBuffers();
+    });
 }
 
-#if READ_DIRECTORIES
-
-static CFMutableDictionaryRef contentsCache = NULL;
-static CFMutableDictionaryRef directoryContentsCache = NULL;
-static CFMutableDictionaryRef unknownContentsCache = NULL;
+static CFSpinLock_t _cacheLock = CFSpinLockInit;
+static CFMutableDictionaryRef _contentsCache = NULL;
+static CFMutableDictionaryRef _directoryContentsCache = NULL;
+static CFMutableDictionaryRef _unknownContentsCache = NULL;
 
 typedef enum {
     _CFBundleAllContents = 0,
@@ -288,23 +323,21 @@ extern void _CFArraySortValues(CFMutableArrayRef array, CFComparatorFunction com
 static CFArrayRef _CFBundleCopySortedDirectoryContentsAtPath(CFStringRef path, _CFBundleDirectoryContentsType contentsType) {
     CFArrayRef result = NULL;
     
-    __CFSpinLock(&CFBundleResourceGlobalDataLock);
+    __CFSpinLock(&_cacheLock);
     if (contentsType == _CFBundleUnknownContents) {
-        if (unknownContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(unknownContentsCache, path);
+        if (_unknownContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_unknownContentsCache, path);
     } else if (contentsType == _CFBundleDirectoryContents) {
-        if (directoryContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(directoryContentsCache, path);
+        if (_directoryContentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_directoryContentsCache, path);
     } else {
-        if (contentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(contentsCache, path);
+        if (_contentsCache) result = (CFMutableArrayRef)CFDictionaryGetValue(_contentsCache, path);
     }
     if (result) CFRetain(result);
-    __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+    __CFSpinUnlock(&_cacheLock);
 
     if (!result) {
         Boolean tryToOpen = false, allDots = true;
         char cpathBuff[CFMaxPathSize];
         CFIndex cpathLen = 0, idx, lastSlashIdx = 0;
-        DIR *dirp = NULL;
-        struct dirent *dent;
         CFMutableArrayRef contents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks), directoryContents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks), unknownContents = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
         CFStringRef dirName, name;
         
@@ -315,7 +348,7 @@ static CFArrayRef _CFBundleCopySortedDirectoryContentsAtPath(CFStringRef path, _
             
             // First see whether we already know that the directory doesn't exist
             for (idx = cpathLen; lastSlashIdx == 0 && idx-- > 0;) {
-                if (cpathBuff[idx] == '/') lastSlashIdx = idx;
+                if (cpathBuff[idx] == PATH_SEP) lastSlashIdx = idx;
                 else if (cpathBuff[idx] != '.') allDots = false;
             }
             if (lastSlashIdx > 0 && lastSlashIdx + 1 < cpathLen && !allDots) {
@@ -324,25 +357,70 @@ static CFArrayRef _CFBundleCopySortedDirectoryContentsAtPath(CFStringRef path, _
                 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
+                        // ??? we might like to use _directoryContentsCache rather than _contentsCache here, but we cannot unless we resolve DT_LNKs below
                         CFArrayRef dirDirContents = NULL;
                         
-                        __CFSpinLock(&CFBundleResourceGlobalDataLock);
-                        if (contentsCache) dirDirContents = (CFArrayRef)CFDictionaryGetValue(contentsCache, dirName);
+                        __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, CFArrayGetValueAtIndex(dirDirContents, dirDirIdx), kCFCompareCaseInsensitive)) foundIt = true;
+                            for (dirDirIdx = 0; !foundIt && dirDirIdx < dirDirLength; dirDirIdx++) if (kCFCompareEqualTo == CFStringCompare(name, (CFStringRef)CFArrayGetValueAtIndex(dirDirContents, dirDirIdx), kCFCompareCaseInsensitive)) foundIt = true;
                             if (!foundIt) tryToOpen = false;
                         }
-                        __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+                        __CFSpinUnlock(&_cacheLock);
                         CFRelease(name);
                     }
                     CFRelease(dirName);
                 }
-                cpathBuff[lastSlashIdx] = '/';
+                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;
@@ -363,46 +441,47 @@ static CFArrayRef _CFBundleCopySortedDirectoryContentsAtPath(CFStringRef path, _
             }
             (void)closedir(dirp);
         }
+#endif
         
         _CFArraySortValues(contents, (CFComparatorFunction)CFStringCompare, NULL);
         _CFArraySortValues(directoryContents, (CFComparatorFunction)CFStringCompare, NULL);
         _CFArraySortValues(unknownContents, (CFComparatorFunction)CFStringCompare, NULL);
         
-        __CFSpinLock(&CFBundleResourceGlobalDataLock);
-        if (!contentsCache) contentsCache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, READ_DIRECTORIES_CACHE_CAPACITY, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-        if (READ_DIRECTORIES_CACHE_CAPACITY <= CFDictionaryGetCount(contentsCache)) CFDictionaryRemoveAllValues(contentsCache);
-        CFDictionaryAddValue(contentsCache, path, contents);
+        __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 (!_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 (!_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 = CFRetain(unknownContents);
+            result = (CFArrayRef)CFRetain(unknownContents);
         } else if (contentsType == _CFBundleDirectoryContents) {
-            result = CFRetain(directoryContents);
+            result = (CFArrayRef)CFRetain(directoryContents);
         } else {
-            result = CFRetain(contents);
+            result = (CFArrayRef)CFRetain(contents);
         }
         
         CFRelease(contents);
         CFRelease(directoryContents);
         CFRelease(unknownContents);
-        __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+        __CFSpinUnlock(&_cacheLock);
     }
     return result;
 }
 
 static void _CFBundleFlushContentsCaches(void) {
-    __CFSpinLock(&CFBundleResourceGlobalDataLock);
-    if (contentsCache) CFDictionaryRemoveAllValues(contentsCache);
-    if (directoryContentsCache) CFDictionaryRemoveAllValues(directoryContentsCache);
-    if (unknownContentsCache) CFDictionaryRemoveAllValues(unknownContentsCache);
-    __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+    __CFSpinLock(&_cacheLock);
+    if (_contentsCache) CFDictionaryRemoveAllValues(_contentsCache);
+    if (_directoryContentsCache) CFDictionaryRemoveAllValues(_directoryContentsCache);
+    if (_unknownContentsCache) CFDictionaryRemoveAllValues(_unknownContentsCache);
+    __CFSpinUnlock(&_cacheLock);
 }
 
 static void _CFBundleFlushContentsCacheForPath(CFMutableDictionaryRef cache, CFStringRef path) {
@@ -417,29 +496,23 @@ static void _CFBundleFlushContentsCacheForPath(CFMutableDictionaryRef cache, CFS
 }
 
 static void _CFBundleFlushContentsCachesForPath(CFStringRef path) {
-    __CFSpinLock(&CFBundleResourceGlobalDataLock);
-    if (contentsCache) _CFBundleFlushContentsCacheForPath(contentsCache, path);
-    if (directoryContentsCache) _CFBundleFlushContentsCacheForPath(directoryContentsCache, path);
-    if (unknownContentsCache) _CFBundleFlushContentsCacheForPath(unknownContentsCache, path);
-    __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
+    __CFSpinLock(&_cacheLock);
+    if (_contentsCache) _CFBundleFlushContentsCacheForPath(_contentsCache, path);
+    if (_directoryContentsCache) _CFBundleFlushContentsCacheForPath(_directoryContentsCache, path);
+    if (_unknownContentsCache) _CFBundleFlushContentsCacheForPath(_unknownContentsCache, path);
+    __CFSpinUnlock(&_cacheLock);
 }
 
-#endif /* READ_DIRECTORIES */
-
 CF_EXPORT void _CFBundleFlushCachesForURL(CFURLRef url) {
-#if READ_DIRECTORIES
     CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
     CFStringRef path = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
     _CFBundleFlushContentsCachesForPath(path);
     CFRelease(path);
     CFRelease(absoluteURL);
-#endif /* READ_DIRECTORIES */
 }
 
 CF_EXPORT void _CFBundleFlushCaches(void) {
-#if READ_DIRECTORIES
     _CFBundleFlushContentsCaches();
-#endif /* READ_DIRECTORIES */
 }
 
 static inline Boolean _CFIsResourceCommon(char *path, Boolean *isDir) {
@@ -466,7 +539,15 @@ __private_extern__ Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir)
     return _CFIsResourceCommon(pathBuf, isDir);
 }
 
-#if READ_DIRECTORIES
+__private_extern__ void _CFBundleSetResourceDir(UniChar *buffer, CFIndex *currLen, CFIndex maxLen, uint8_t version){
+    if (1 == version) {
+        _CFAppendPathComponent(buffer, currLen, maxLen, _AppSupportUniChars1, _AppSupportLen1);
+    } 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;
@@ -482,11 +563,11 @@ static CFArrayRef _CFCopyTypesForSearchBundleDirectory(CFAllocatorRef alloc, Uni
     CFStringSetExternalCharactersNoCopy(tmpString, nameUniChars, nameLen, nameLen);
     CFStringReplaceAll(cheapStr, tmpString);
     for (i = 0; i < contentsRange.length; i++) {
-        CFStringRef content = CFArrayGetValueAtIndex(contents, i);
+        CFStringRef content = (CFStringRef)CFArrayGetValueAtIndex(contents, i);
         if (CFStringHasPrefix(content, cheapStr)) {
             //fprintf(stderr, "found ");CFShow(content);
             for (j = 0; j < numResTypes; j++) {
-                CFStringRef resType = CFArrayGetValueAtIndex(resTypes, j);
+                CFStringRef resType = (CFStringRef)CFArrayGetValueAtIndex(resTypes, j);
                 if (!CFArrayContainsValue(result, resultRange, resType) && CFStringHasSuffix(content, resType)) {
                     CFArrayAppendValue(result, resType);
                     resultRange.length = CFArrayGetCount(result);
@@ -498,9 +579,8 @@ static CFArrayRef _CFCopyTypesForSearchBundleDirectory(CFAllocatorRef alloc, Uni
     CFRelease(contents);
     return result;
 }
-#endif /* READ_DIRECTORIES */
 
-#if DEPLOYMENT_TARGET_EMBEDDED
+#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.
@@ -603,7 +683,7 @@ static void _CFSearchBundleDirectory2(CFAllocatorRef alloc, CFMutableArrayRef re
 
 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
+#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.
@@ -614,12 +694,9 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
     // URLs for found resources get added to result.
     CFIndex savedPathLen;
     Boolean appendSucceeded = true, platformGenericFound = false, platformSpecificFound = false, platformGenericIsDir = false, platformSpecificIsDir = false;
-#if READ_DIRECTORIES
     Boolean platformGenericIsUnknown = false, platformSpecificIsUnknown = false; 
-#endif
     CFStringRef platformGenericStr = NULL;
 
-#if READ_DIRECTORIES
     CFIndex dirPathLen = pathLen;
     CFArrayRef contents, directoryContents, unknownContents;
     CFRange contentsRange, directoryContentsRange, unknownContentsRange;
@@ -633,13 +710,11 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
     directoryContentsRange = CFRangeMake(0, CFArrayGetCount(directoryContents));
     unknownContents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleUnknownContents);
     unknownContentsRange = CFRangeMake(0, CFArrayGetCount(unknownContents));
-#endif /* READ_DIRECTORIES */
     
     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) {
-#if READ_DIRECTORIES
         CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + dirPathLen + 1, pathLen - dirPathLen - 1, pathLen - dirPathLen - 1);
         CFStringReplaceAll(cheapStr, tmpString);
         platformGenericFound = _CFBundleSortedArrayContains(contents, cheapStr);
@@ -652,11 +727,6 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
             (void)_CFIsResourceAtPath(cheapStr, &platformGenericIsDir);
             //if (platformGenericIsDir) fprintf(stderr, "a directory after all\n"); else fprintf(stderr, "not a directory after all\n"); 
         }
-#else /* READ_DIRECTORIES */
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        platformGenericFound = _CFIsResourceAtPath(cheapStr, &platformGenericIsDir);
-#endif /* READ_DIRECTORIES */
     }
     
     // Check for platform specific.
@@ -669,7 +739,6 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
             pathLen += _PlatformLen;
             if (appendSucceeded && typeLen > 0) appendSucceeded = _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, typeUniChars, typeLen);
             if (appendSucceeded) {
-#if READ_DIRECTORIES
                 CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars + dirPathLen + 1, pathLen - dirPathLen - 1, pathLen - dirPathLen - 1);
                 CFStringReplaceAll(cheapStr, tmpString);
                 platformSpecificFound = _CFBundleSortedArrayContains(contents, cheapStr);
@@ -682,11 +751,6 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
                     (void)_CFIsResourceAtPath(cheapStr, &platformSpecificIsDir);
                     //if (platformSpecificIsDir) fprintf(stderr, "a directory after all\n"); else fprintf(stderr, "not a directory after all\n"); 
                 }
-#else /* READ_DIRECTORIES */
-                CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-                CFStringReplaceAll(cheapStr, tmpString);
-                platformSpecificFound = _CFIsResourceAtPath(cheapStr, &platformSpecificIsDir);
-#endif /* READ_DIRECTORIES */
             }
         }
     }
@@ -700,15 +764,12 @@ static void _CFSearchBundleDirectory(CFAllocatorRef alloc, CFMutableArrayRef res
         CFRelease(url);
     }
     if (platformGenericStr) CFRelease(platformGenericStr);
-#if READ_DIRECTORIES
     CFRelease(contents);
     CFRelease(directoryContents);
     CFRelease(unknownContents);
-#endif /* READ_DIRECTORIES */
 #endif
 }
 
-#if READ_DIRECTORIES
 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.
@@ -736,7 +797,7 @@ static void _CFSearchBundleDirectoryWithPredicate(CFAllocatorRef alloc, CFMutabl
         
     // scan directory contents for matches against predicate
     for (int i = 0; i < contentsRange.length; i++) {
-        CFStringRef candidateFilename = CFArrayGetValueAtIndex(contents, 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
@@ -794,17 +855,12 @@ static void _CFSearchBundleDirectoryWithPredicate(CFAllocatorRef alloc, CFMutabl
     CFRelease(directoryContents);
     CFRelease(unknownContents);
 }
-#endif
+
 
 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) {
-#if READ_DIRECTORIES
         _CFSearchBundleDirectoryWithPredicate(alloc, result, workingUniChars, workingLen, predicate, cheapStr, tmpString, stopLooking, version);
         return;
-#else
-        CFLog(kCFLogLevelCritical, CFSTR("_CFFindBundleResourcesInRawDir: predicate blocks are not supported on this platform"));
-        HALT;
-#endif
     }
     if (nameLen > 0) {
         // If we have a resName, just call the search API.  We may have to loop over the resTypes.
@@ -814,7 +870,6 @@ static void _CFFindBundleResourcesInRawDir(CFAllocatorRef alloc, UniChar *workin
             CFArrayRef subResTypes = resTypes;
             Boolean releaseSubResTypes = false;
             CFIndex i, c = CFArrayGetCount(resTypes);
-#if READ_DIRECTORIES
             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
@@ -822,7 +877,6 @@ static void _CFFindBundleResourcesInRawDir(CFAllocatorRef alloc, UniChar *workin
                 c = CFArrayGetCount(subResTypes);
                 releaseSubResTypes = true;
             }
-#endif /* READ_DIRECTORIES */
             for (i = 0; i < c; i++) {
                 CFStringRef curType = (CFStringRef)CFArrayGetValueAtIndex(subResTypes, i);
                 CFIndex typeLen = CFStringGetLength(curType);
@@ -869,6 +923,7 @@ static void _CFFindBundleResourcesInRawDir(CFAllocatorRef alloc, UniChar *workin
     }
 }
 
+
 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
@@ -881,24 +936,68 @@ static void _CFFindBundleResourcesInResourcesDir(CFAllocatorRef alloc, UniChar *
         // 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 local resources.
+    // 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 langCount = (searchLanguages ? CFArrayGetCount(searchLanguages) : 0);
-        // MF:??? OK to hard-wire this length?
-        UniChar curLangUniChars[255];
         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;
+            }
+        }
+    }
 
-        for (CFIndex langIndex = 0; langIndex < langCount; langIndex++) {
+    // 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 = CFStringGetLength(curLangStr);
-            if (curLangLen > 255) curLangLen = 255;
+            CFIndex curLangLen = MIN(CFStringGetLength(curLangStr), 255);
             CFStringGetCharacters(curLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
             savedWorkingLen = workingLen;
             if (!_CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, curLangUniChars, curLangLen)) {
@@ -928,8 +1027,6 @@ static void _CFFindBundleResourcesInResourcesDir(CFAllocatorRef alloc, UniChar *
     }
 }
 
-extern void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len);
-
 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);
 
@@ -975,12 +1072,7 @@ CFArrayRef _CFFindBundleResources(CFBundleRef bundle, CFURLRef bundleURL, CFStri
 
         if ((workingLen = CFStringGetLength(basePath)) > 0) CFStringGetCharacters(basePath, CFRangeMake(0, workingLen), workingUniChars);
         savedWorkingLen = workingLen;
-        if (1 == version) {
-            _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, _AppSupportUniChars1, _AppSupportLen1);
-        } else if (2 == version) {
-            _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, _AppSupportUniChars2, _AppSupportLen2);
-        }
-        if (0 == version || 1 == version || 2 == version) _CFAppendPathComponent(workingUniChars, &workingLen, CFMaxPathSize, _ResourcesUniChars, _ResourcesLen);
+        _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);
@@ -989,13 +1081,6 @@ CFArrayRef _CFFindBundleResources(CFBundleRef bundle, CFURLRef bundleURL, CFStri
 
         _CFFindBundleResourcesInResourcesDir(kCFAllocatorSystemDefault, workingUniChars, workingLen, subDirUniChars, subDirLen, searchLanguages, nameUniChars, nameLen, resTypes, limit, predicate, version, cheapStr, tmpString, result);
         
-        // drd: This unfortunate hack is still necessary because of installer packages and Spotlight importers
-        if (CFArrayGetCount(result) == 0 && (0 == version || (2 == version && CFEqual(CFSTR("/Library/Spotlight"), basePath)))) {
-            // Try looking directly in the bundle path
-            workingLen = savedWorkingLen;
-            _CFFindBundleResourcesInResourcesDir(kCFAllocatorSystemDefault, workingUniChars, workingLen, subDirUniChars, subDirLen, searchLanguages, nameUniChars, nameLen, resTypes, limit, predicate, version, cheapStr, tmpString, result);
-        }
-
         CFRelease(cheapStr);
         CFRelease(tmpString);
         CFAllocatorDeallocate(kCFAllocatorSystemDefault, nameUniChars);
@@ -1005,9 +1090,16 @@ CFArrayRef _CFFindBundleResources(CFBundleRef bundle, CFURLRef bundleURL, CFStri
     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;
+    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);
@@ -1018,9 +1110,15 @@ CF_EXPORT CFURLRef CFBundleCopyResourceURL(CFBundleRef bundle, CFStringRef resou
         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?
@@ -1028,6 +1126,7 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfType(CFBundleRef bundle, CFString
     if (types) CFRelease(types);
     
     return array;
+#endif
 }
 
 CF_EXPORT CFURLRef _CFBundleCopyResourceURLForLanguage(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language) {
@@ -1035,6 +1134,11 @@ 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;
 
@@ -1048,6 +1152,7 @@ CF_EXPORT CFURLRef CFBundleCopyResourceURLForLocalization(CFBundleRef bundle, CF
     if (types) CFRelease(types);
     if (languages) CFRelease(languages);
     return result;
+#endif
 }
 
 CF_EXPORT CFArrayRef _CFBundleCopyResourceURLsOfTypeForLanguage(CFBundleRef bundle, CFStringRef resourceType, CFStringRef subDirName, CFStringRef language) {
@@ -1055,6 +1160,11 @@ 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);
@@ -1064,9 +1174,12 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeForLocalization(CFBundleRef b
     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;
@@ -1074,6 +1187,9 @@ CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRe
 
     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);
@@ -1121,7 +1237,6 @@ CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRe
 
     result = (CFStringRef)CFDictionaryGetValue(stringTable, key);
     if (!result) {
-        static int capitalize = -1;
         if (!value) {
             result = (CFStringRef)CFRetain(key);
         } else if (CFEqual(value, CFSTR(""))) {
@@ -1129,14 +1244,13 @@ CF_EXPORT CFStringRef CFBundleCopyLocalizedString(CFBundleRef bundle, CFStringRe
         } else {
             result = (CFStringRef)CFRetain(value);
         }
-        if (capitalize != 0) {
-            if (capitalize != 0) {
-                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;
-            }
+        __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);
@@ -1155,6 +1269,9 @@ CF_EXPORT CFURLRef CFBundleCopyResourceURLInDirectory(CFURLRef bundleURL, CFStri
     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);
@@ -1165,6 +1282,7 @@ CF_EXPORT CFURLRef CFBundleCopyResourceURLInDirectory(CFURLRef bundleURL, CFStri
             if (CFArrayGetCount(array) > 0) result = (CFURLRef)CFRetain(CFArrayGetValueAtIndex(array, 0));
             CFRelease(array);
         }
+#endif
     }
     if (newURL) CFRelease(newURL);
     return result;
@@ -1180,6 +1298,9 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeInDirectory(CFURLRef bundleUR
     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);
@@ -1187,6 +1308,7 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeInDirectory(CFURLRef bundleUR
         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;
@@ -1518,63 +1640,12 @@ CFStringRef CFBundleCopyLocalizationForLocalizationInfo(SInt32 languageCode, SIn
 
 extern void *__CFAppleLanguages;
 
-#if DEPLOYMENT_TARGET_WINDOWS
-
-extern CFStringRef copyLocaleLanguageName(void);
-extern CFStringRef copyLocaleCountryName(void);
-
-static CFArrayRef copyWindowsLanguagePrefsArray() {
-    CFArrayRef result;
-    CFStringRef locales[4];
-    CFStringRef languageName = copyLocaleLanguageName(), countryName = copyLocaleCountryName();
-    if (!languageName) languageName = CFSTR("en");
-    if (!countryName) countryName = CFSTR("");
-    CFIndex i, localesCount = 0;
-    if (CFStringGetLength(countryName) > 0) locales[localesCount++] = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@_%@"), languageName, countryName);
-    if (CFStringGetLength(languageName) != 0) {
-        // special-case for zh since we don't have a generic zh localization
-        if (CFStringCompare(languageName, CFSTR("zh"), kCFCompareCaseInsensitive) != 0) {
-            locales[localesCount++] = CFStringCreateCopy(kCFAllocatorSystemDefault, languageName);//languageName;
-        } else {
-            CFStringRef moreSpecificLanguageName;
-
-            // See http://intrigue-build.apple.com/changeset/14948 for the details on the change.  Copied below is the snippet of the code change.
-            // According to http://www.microsoft.com/globaldev/reference/win2k/setup/lcid.mspx, the locales that use 
-            // 126          // simplified chinese are CN (PRC) and SG (Singapore).  The rest use traditional chinese. 
-            // 127          languageName = (countryName == TEXT("CN") || countryName == TEXT("SG")) ? TEXT("zh_CN") : TEXT("zh_TW"); 
-
-            // Compare for CN or SG
-            if (CFStringCompare(countryName, CFSTR("CN"), kCFCompareCaseInsensitive) == 0 || CFStringCompare(countryName, CFSTR("SG"), kCFCompareCaseInsensitive) == 0) {
-                moreSpecificLanguageName = CFSTR("zh_CN");
-            } else {
-                moreSpecificLanguageName = CFSTR("zh_TW");
-            }
-            locales[localesCount++] = CFStringCreateCopy(kCFAllocatorSystemDefault, moreSpecificLanguageName);
-        }
-        // Don't need this now
-        if (languageName) CFRelease(languageName);
-        if (countryName) CFRelease(countryName);
-    }
-    if (localesCount == 0) locales[localesCount++] = CFStringCreateCopy(kCFAllocatorSystemDefault, CFSTR("en"));
-    result = CFArrayCreate(kCFAllocatorDefault, (const void **)locales, localesCount, &kCFTypeArrayCallBacks);
-    for (i = 0; i < localesCount; i++) CFRelease(locales[i]);
-    return result;
-}
-
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
-    
-static CFArrayRef _CFBundleUserLanguages = NULL;
 
 __private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops) {
-    CFArrayRef result = NULL;
-    static Boolean didit = false;
-    CFArrayRef preferencesArray = NULL;
-    // This is a temporary solution, until the argument domain is moved down into CFPreferences
-    __CFSpinLock(&CFBundleResourceGlobalDataLock);
-    if (!didit) {
+    static CFArrayRef _CFBundleUserLanguages = NULL;
+    static dispatch_once_t once = 0;
+    dispatch_once(&once, ^{
+        CFArrayRef preferencesArray = NULL;
         if (__CFAppleLanguages) {
             CFDataRef data;
             CFIndex length = strlen((const char *)__CFAppleLanguages);
@@ -1597,12 +1668,15 @@ __private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops) {
             CFRelease(_CFBundleUserLanguages);
             _CFBundleUserLanguages = NULL;
         }
-        didit = true;
+        if (preferencesArray) CFRelease(preferencesArray);
+    });
+    
+    if (_CFBundleUserLanguages) {
+        CFRetain(_CFBundleUserLanguages);
+        return _CFBundleUserLanguages;
+    } else {
+        return NULL;
     }
-    __CFSpinUnlock(&CFBundleResourceGlobalDataLock);
-    if (preferencesArray) CFRelease(preferencesArray);
-    if (!result && _CFBundleUserLanguages) result = (CFArrayRef)CFRetain(_CFBundleUserLanguages);
-    return result;
 }
 
 CF_EXPORT void _CFBundleGetLanguageAndRegionCodes(SInt32 *languageCode, SInt32 *regionCode) {
@@ -1651,12 +1725,8 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     CFArrayRef predefinedLocalizations = NULL;
     CFRange predefinedLocalizationsRange;
     CFMutableStringRef cheapStr, tmpString;
-#if READ_DIRECTORIES
     CFArrayRef contents;
     CFRange contentsRange;
-#else /* READ_DIRECTORIES */
-    Boolean isDir = false;
-#endif /* READ_DIRECTORIES */
 
     // both of these used for temp string operations, for slightly
     // different purposes, where each type is appropriate
@@ -1664,12 +1734,10 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     _CFStrSetDesiredCapacity(cheapStr, CFMaxPathSize);
     tmpString = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull);    
     
-#if READ_DIRECTORIES
     CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
     CFStringReplaceAll(cheapStr, tmpString);
     contents = _CFBundleCopySortedDirectoryContentsAtPath(cheapStr, _CFBundleAllContents);
     contentsRange = CFRangeMake(0, CFArrayGetCount(contents));
-#endif /* READ_DIRECTORIES */
     
     if (infoDict) {
         predefinedLocalizations = (CFArrayRef)CFDictionaryGetValue(infoDict, kCFBundleLocalizationsKey);
@@ -1684,23 +1752,15 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     CFStringGetCharacters(curLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
     savedPathLen = pathLen;
     if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-#if READ_DIRECTORIES
         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))) {
-#else /* READ_DIRECTORIES */
-        CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-        CFStringReplaceAll(cheapStr, tmpString);
-        if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, curLangStr)) || (version != 4 && _CFIsResourceAtPath(cheapStr, &isDir) && isDir)) {
-#endif /* READ_DIRECTORIES */
             if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), curLangStr)) CFArrayAppendValue(lprojNames, curLangStr);
             foundOne = true;
             if (CFStringGetLength(curLangStr) <= 2) {
                 CFRelease(cheapStr);
                 CFRelease(tmpString);
-#if READ_DIRECTORIES
                 CFRelease(contents);
-#endif /* READ_DIRECTORIES */
                 return foundOne;
             }
         }
@@ -1717,9 +1777,7 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     if (foundOne && altLangStr) {
         CFRelease(cheapStr);
         CFRelease(tmpString);
-#if READ_DIRECTORIES
         CFRelease(contents);
-#endif /* READ_DIRECTORIES */
         return foundOne;
     }
     if (altLangStr) {
@@ -1728,32 +1786,23 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
         CFStringGetCharacters(altLangStr, CFRangeMake(0, curLangLen), curLangUniChars);
         pathLen = savedPathLen;
         if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-#if READ_DIRECTORIES
             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))) {
-#else /* READ_DIRECTORIES */
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, altLangStr)) || (version != 4 && _CFIsResourceAtPath(cheapStr, &isDir) && isDir)) {
-#endif /* READ_DIRECTORIES */
                 if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), altLangStr)) CFArrayAppendValue(lprojNames, altLangStr);
                 foundOne = true;
                 CFRelease(cheapStr);
                 CFRelease(tmpString);
-#if READ_DIRECTORIES
                 CFRelease(contents);
-#endif /* READ_DIRECTORIES */
                 return foundOne;
             }
         }
     }
-#if READ_DIRECTORIES
     if (!foundOne && (!predefinedLocalizations || CFArrayGetCount(predefinedLocalizations) == 0)) {
         Boolean hasLocalizations = false;
         CFIndex idx;
         for (idx = 0; !hasLocalizations && idx < contentsRange.length; idx++) {
-            CFStringRef name = CFArrayGetValueAtIndex(contents, idx);
+            CFStringRef name = (CFStringRef)CFArrayGetValueAtIndex(contents, idx);
             if (CFStringHasSuffix(name, _CFBundleLprojExtensionWithDot)) hasLocalizations = true;
         }
         if (!hasLocalizations) {
@@ -1763,22 +1812,15 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
             return foundOne;
         }
     }
-#endif /* READ_DIRECTORIES */
     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)) {
-#if READ_DIRECTORIES
             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))) {
-#else /* READ_DIRECTORIES */
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, modifiedLangStr)) || (version != 4 && _CFIsResourceAtPath(cheapStr, &isDir) && isDir)) {
-#endif /* READ_DIRECTORIES */
                 if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), modifiedLangStr)) CFArrayAppendValue(lprojNames, modifiedLangStr);
                 foundOne = true;
             }
@@ -1790,15 +1832,9 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
         CFStringGetCharacters(languageAbbreviation, CFRangeMake(0, curLangLen), curLangUniChars);
         pathLen = savedPathLen;
         if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-#if READ_DIRECTORIES
             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))) {
-#else /* READ_DIRECTORIES */
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, languageAbbreviation)) || (version != 4 && _CFIsResourceAtPath(cheapStr, &isDir) && isDir)) {
-#endif /* READ_DIRECTORIES */
                 if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageAbbreviation)) CFArrayAppendValue(lprojNames, languageAbbreviation);
                 foundOne = true;
             }
@@ -1810,15 +1846,9 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
         CFStringGetCharacters(languageName, CFRangeMake(0, curLangLen), curLangUniChars);
         pathLen = savedPathLen;
         if (_CFAppendPathComponent(pathUniChars, &pathLen, CFMaxPathSize, curLangUniChars, curLangLen) && _CFAppendPathExtension(pathUniChars, &pathLen, CFMaxPathSize, _LprojUniChars, _LprojLen)) {
-#if READ_DIRECTORIES
             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))) {
-#else /* READ_DIRECTORIES */
-            CFStringSetExternalCharactersNoCopy(tmpString, pathUniChars, pathLen, pathLen);
-            CFStringReplaceAll(cheapStr, tmpString);
-            if ((predefinedLocalizations && CFArrayContainsValue(predefinedLocalizations, predefinedLocalizationsRange, languageName)) || (version != 4 && _CFIsResourceAtPath(cheapStr, &isDir) && isDir)) {
-#endif /* READ_DIRECTORIES */
                 if (!CFArrayContainsValue(lprojNames, CFRangeMake(0, CFArrayGetCount(lprojNames)), languageName)) CFArrayAppendValue(lprojNames, languageName);
                 foundOne = true;
             }
@@ -1833,15 +1863,14 @@ static Boolean _CFBundleTryOnePreferredLprojNameInDirectory(CFAllocatorRef alloc
     if (canonicalLanguageAbbreviation) CFRelease(canonicalLanguageAbbreviation);
     CFRelease(cheapStr);
     CFRelease(tmpString);
-#if READ_DIRECTORIES
     CFRelease(contents);
-#endif /* READ_DIRECTORIES */
     return foundOne;
 }
 
 static Boolean CFBundleAllowMixedLocalizations(void) {
-    static Boolean allowMixed = false, examinedMain = false;
-    if (!examinedMain) {
+    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;
@@ -1855,9 +1884,8 @@ static Boolean CFBundleAllowMixedLocalizations(void) {
                 SInt32 val = 0;
                 if (CFNumberGetValue((CFNumberRef)allowMixedValue, kCFNumberSInt32Type, &val)) allowMixed = (val != 0);
             }
-        }
-        examinedMain = true;
-    }
+        }        
+    });
     return allowMixed;
 }
 
@@ -2121,11 +2149,15 @@ __private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint
     // version 3:  none of the above (see below)
     // version 4:  not a bundle (for main bundle only)
     uint8_t localVersion = 3;
-#if READ_DIRECTORIES
     CFURLRef absoluteURL = CFURLCopyAbsoluteURL(url);
     CFStringRef directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
     CFArrayRef contents = _CFBundleCopySortedDirectoryContentsAtPath(directoryPath, _CFBundleAllContents);
-    if (CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework/"))) {
+    Boolean hasFrameworkSuffix = CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework/"));
+#if DEPLOYMENT_TARGET_WINDOWS
+    hasFrameworkSuffix = hasFrameworkSuffix || CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework\\"));
+#endif
+    
+    if (hasFrameworkSuffix) {
         if (_CFBundleSortedArrayContains(contents, _CFBundleResourcesDirectoryName)) localVersion = 0;
         else if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName2)) localVersion = 2;
         else if (_CFBundleSortedArrayContains(contents, _CFBundleSupportFilesDirectoryName1)) localVersion = 1;
@@ -2137,15 +2169,9 @@ __private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint
     CFRelease(contents);
     CFRelease(directoryPath);
     CFRelease(absoluteURL);
-#endif /* READ_DIRECTORIES */
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
     if (localVersion == 3) {
-#if DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS
-#if DEPLOYMENT_TARGET_WINDOWS
-        if (CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework/")) || CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework\\"))) {
-#else
-        if (CFStringHasSuffix(CFURLGetString(url), CFSTR(".framework/"))) {
-#endif
+        if (hasFrameworkSuffix) {
             if (_CFBundleURLHasSubDir(url, _CFBundleResourcesURLFromBase0)) localVersion = 0;
             else if (_CFBundleURLHasSubDir(url, _CFBundleSupportFilesURLFromBase2)) localVersion = 2;
             else if (_CFBundleURLHasSubDir(url, _CFBundleSupportFilesURLFromBase1)) localVersion = 1;
@@ -2154,8 +2180,8 @@ __private_extern__ Boolean _CFBundleURLLooksLikeBundleVersion(CFURLRef url, uint
             else if (_CFBundleURLHasSubDir(url, _CFBundleResourcesURLFromBase0)) localVersion = 0;
             else if (_CFBundleURLHasSubDir(url, _CFBundleSupportFilesURLFromBase1)) localVersion = 1;
         }
-#endif
     }
+#endif
     if (version) *version = localVersion;
     return (localVersion != 3);
 }
@@ -2196,12 +2222,14 @@ static Boolean _isValidPlatformAndProductSuffixPair(CFStringRef platform, CFStri
 }
 
 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;
 }
 
@@ -2410,31 +2438,23 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
         CFMutableStringRef cheapStr;
         CFStringRef infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension0, infoURLFromBase = _CFBundleInfoURLFromBase0;
         Boolean tryPlatformSpecific = true, tryGlobal = true;
-#if READ_DIRECTORIES
         CFURLRef directoryURL = NULL, absoluteURL;
         CFStringRef directoryPath;
         CFArrayRef contents = NULL;
         CFRange contentsRange = CFRangeMake(0, 0);
-#endif /* READ_DIRECTORIES */    
 
         _CFEnsureStaticBuffersInited();
 
         if (0 == version) {
-#if READ_DIRECTORIES
             directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleResourcesURLFromBase0, url);
-#endif /* READ_DIRECTORIES */    
             infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension0;
             infoURLFromBase = _CFBundleInfoURLFromBase0;
         } else if (1 == version) {
-#if READ_DIRECTORIES
             directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase1, url);
-#endif /* READ_DIRECTORIES */    
             infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension1;
             infoURLFromBase = _CFBundleInfoURLFromBase1;
         } else if (2 == version) {
-#if READ_DIRECTORIES
             directoryURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleSupportFilesURLFromBase2, url);
-#endif /* READ_DIRECTORIES */    
             infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension2;
             infoURLFromBase = _CFBundleInfoURLFromBase2;
         } else if (3 == version) {
@@ -2442,16 +2462,13 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
             // 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))) {
-#if READ_DIRECTORIES
-                    directoryURL = CFRetain(url);
-#endif /* READ_DIRECTORIES */    
+                    directoryURL = (CFURLRef)CFRetain(url);
                     infoURLFromBaseNoExtension = _CFBundleInfoURLFromBaseNoExtension3;
                     infoURLFromBase = _CFBundleInfoURLFromBase3;
                 }
                 CFRelease(path);
             }
         }
-#if READ_DIRECTORIES
         if (directoryURL) {
             absoluteURL = CFURLCopyAbsoluteURL(directoryURL);
             directoryPath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
@@ -2461,7 +2478,6 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
             CFRelease(absoluteURL);
             CFRelease(directoryURL);
         }
-#endif /* READ_DIRECTORIES */    
 
         len = CFStringGetLength(infoURLFromBaseNoExtension);
         CFStringGetCharacters(infoURLFromBaseNoExtension, CFRangeMake(0, len), buff);
@@ -2472,18 +2488,16 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
         cheapStr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
         CFStringAppendCharacters(cheapStr, buff, len);
         infoURL = CFURLCreateWithString(kCFAllocatorSystemDefault, cheapStr, url);
-#if READ_DIRECTORIES
         if (contents) {
             CFIndex resourcesLen, idx;
-            for (resourcesLen = len; resourcesLen > 0; resourcesLen--) if (buff[resourcesLen - 1] == '/') break;
+            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, CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryPlatformSpecific = true;
+                if (kCFCompareEqualTo == CFStringCompare(cheapStr, (CFStringRef)CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryPlatformSpecific = true;
             }
         }
-#endif /* READ_DIRECTORIES */    
         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);
@@ -2491,15 +2505,13 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
             // Check for global Info.plist
             CFRelease(infoURL);
             infoURL = CFURLCreateWithString(kCFAllocatorSystemDefault, infoURLFromBase, url);
-#if READ_DIRECTORIES
             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, CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryGlobal = true;
+                    if (kCFCompareEqualTo == CFStringCompare(_CFBundleInfoFileName, (CFStringRef)CFArrayGetValueAtIndex(contents, idx), kCFCompareCaseInsensitive)) tryGlobal = true;
                 }
             }
-#endif /* READ_DIRECTORIES */    
             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"));
         }
@@ -2523,9 +2535,7 @@ __private_extern__ CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVer
         }
 
         CFRelease(infoURL);
-#if READ_DIRECTORIES
         if (contents) CFRelease(contents);
-#endif /* READ_DIRECTORIES */    
     }
     _processInfoDictionary((CFMutableDictionaryRef)result, _CFGetPlatformName(), _CFGetProductName());
     return result;
@@ -2602,19 +2612,19 @@ static Boolean _CFBundleGetPackageInfoInDirectoryWithInfoDictionary(CFAllocatorR
                 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)'/')) {
+                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)'/')) {
+                } 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)'/')) {
+                } 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)'/')) {
+                } 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)'/')) {
+                } 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 {
@@ -2709,7 +2719,7 @@ CF_EXPORT CFArrayRef _CFBundleGetSupportedPlatforms(CFBundleRef bundle) {
 CF_EXPORT CFStringRef _CFBundleGetCurrentPlatform(void) {
 #if DEPLOYMENT_TARGET_MACOSX
     return CFSTR("MacOS");
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("iPhoneOS");
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("Windows");
@@ -2727,7 +2737,7 @@ CF_EXPORT CFStringRef _CFBundleGetCurrentPlatform(void) {
 }
 
 __private_extern__ CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("MacOS");
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("Windows");
@@ -2745,7 +2755,7 @@ __private_extern__ CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(v
 }
 
 __private_extern__ CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("Mac OS X");
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("WinNT");
@@ -2763,7 +2773,7 @@ __private_extern__ CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirect
 }
 
 __private_extern__ CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("MacOSClassic");
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("Other");
@@ -2781,7 +2791,7 @@ __private_extern__ CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryN
 }
 
 __private_extern__ CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return CFSTR("Mac OS 8");
 #elif DEPLOYMENT_TARGET_WINDOWS
     return CFSTR("Other");
@@ -2805,15 +2815,11 @@ __private_extern__ CFArrayRef _CFBundleCopyBundleRegionsArray(CFBundleRef bundle
 CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) {
     CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle);
     CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(bundle);
-#if READ_DIRECTORIES
     CFURLRef absoluteURL;
     CFStringRef directoryPath;
     CFArrayRef contents;
     CFRange contentsRange;
     CFIndex idx;
-#else /* READ_DIRECTORIES */
-    CFArrayRef urls = ((_CFBundleLayoutVersion(bundle) != 4) ? _CFContentsOfDirectory(CFGetAllocator(bundle), NULL, NULL, resourcesURL, _CFBundleLprojExtension) : NULL);
-#endif /* READ_DIRECTORIES */
     CFArrayRef predefinedLocalizations = NULL;
     CFMutableArrayRef result = NULL;
 
@@ -2830,14 +2836,13 @@ CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) {
         }
     }
 
-#if READ_DIRECTORIES
     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 = CFArrayGetValueAtIndex(contents, 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);
@@ -2849,34 +2854,6 @@ CF_EXPORT CFArrayRef CFBundleCopyBundleLocalizations(CFBundleRef bundle) {
         CFRelease(directoryPath);
         CFRelease(absoluteURL);
     }
-#else /* READ_DIRECTORIES */
-    if (urls) {
-        CFIndex i, c = CFArrayGetCount(urls);
-        CFURLRef curURL, curAbsoluteURL;
-        CFStringRef curStr, regionStr;
-        UniChar buff[CFMaxPathSize];
-        CFIndex strLen, startOfLastPathComponent, regionLen;
-
-        if (c > 0 && !result) result = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &kCFTypeArrayCallBacks);
-        for (i = 0; i < c; i++) {
-            curURL = (CFURLRef)CFArrayGetValueAtIndex(urls, i);
-            curAbsoluteURL = CFURLCopyAbsoluteURL(curURL);
-            curStr = CFURLCopyFileSystemPath(curAbsoluteURL, PLATFORM_PATH_STYLE);
-            CFRelease(curAbsoluteURL);
-            strLen = CFStringGetLength(curStr);
-            if (strLen > CFMaxPathSize) strLen = CFMaxPathSize;
-            CFStringGetCharacters(curStr, CFRangeMake(0, strLen), buff);
-
-            startOfLastPathComponent = _CFStartOfLastPathComponent(buff, strLen);
-            regionLen = _CFLengthAfterDeletingPathExtension(&(buff[startOfLastPathComponent]), strLen - startOfLastPathComponent);
-            regionStr = CFStringCreateWithCharacters(CFGetAllocator(bundle), &(buff[startOfLastPathComponent]), regionLen);
-            CFArrayAppendValue(result, regionStr);
-            CFRelease(regionStr);
-            CFRelease(curStr);
-        }
-        CFRelease(urls);
-    }
-#endif /* READ_DIRECTORIES */
     
     if (!result) {
         CFStringRef developmentLocalization = CFBundleGetDevelopmentRegion(bundle);
@@ -2937,3 +2914,919 @@ CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url) {
     }
     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;
+    if (backward) {
+        for (CFIndex i = start; i > start-length; i--) {
+            if (c == str[i]) {
+                result->location = i;
+                found = true;
+                break;
+            }
+        }
+    } else {
+        for (CFIndex i = start; i < start+length; i++) {
+            if (c == str[i]) {
+                result->location = i;
+                found = true;
+                break;
+            }
+        }
+    }
+    return found;
+}
+
+
+typedef enum {
+    _CFBundleFileVersionNoProductNoPlatform = 1,
+    _CFBundleFileVersionWithProductNoPlatform,
+    _CFBundleFileVersionNoProductWithPlatform,
+    _CFBundleFileVersionWithProductWithPlatform,
+    _CFBundleFileVersionUnmatched
+} _CFBundleFileVersion;
+
+static _CFBundleFileVersion _CFBundleCheckFileProductAndPlatform(CFStringRef file, UniChar *fileBuffer1, CFIndex fileLen, CFRange searchRange, CFStringRef product, CFStringRef platform, CFRange* prodp, CFRange* platp, CFIndex prodLen)
+{
+    _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)) {
+                foundprod = YES;
+            }
+        }
+        if (!foundprod) {
+            for (CFIndex i = 0; i < _CFBundleNumberOfProducts; i++) {
+                if (CFStringFindWithOptions(file, _CFBundleSupportedProducts[i], searchRange, kCFCompareEqualTo, &found)) {
+                    wrong = true;
+                    break;
+                }
+            }
+        }
+    }
+
+    if (!wrong && _CFBundleFindCharacterInStr(fileBuffer, '-', NO, searchRange.location, searchRange.length, &found)) {
+        if (CFStringFindWithOptions(file, platform, searchRange, kCFCompareEqualTo, platp)) {
+            foundplat = YES;
+        }
+        if (!foundplat) {
+            for (CFIndex i = 0; i < _CFBundleNumberOfPlatforms; i++) {
+                if (CFStringFindWithOptions(file, _CFBundleSupportedPlatforms[i], searchRange, kCFCompareEqualTo, &found)) {
+                    wrong = true;
+                    break;
+                }
+            }
+        }
+    }
+    
+    if (wrong) {
+        version = _CFBundleFileVersionUnmatched;
+    } else if (foundplat && foundprod) {
+        version = _CFBundleFileVersionWithProductWithPlatform;
+    } else if (foundplat) {
+        version = _CFBundleFileVersionNoProductWithPlatform;
+    } else if (foundprod) {
+        version = _CFBundleFileVersionWithProductNoPlatform;
+    } else {
+        version = _CFBundleFileVersionNoProductNoPlatform;
+    }
+    return version;
+}
+
+    
+// ZFH
+    
+    
+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);
+    }
+}
+
+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);
+    
+    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);
+    }
+    
+    if (subDirLen) {
+        memmove(valueBuff+pathOfDirWithSlashLen, subDir, subDirLen*sizeof(UniChar));
+        pathOfDirWithSlashLen += subDirLen;
+        if (subDir[subDirLen-1] != _CFGetSlash()) {
+            _CFAppendTrailingPathSlash(valueBuff, &pathOfDirWithSlashLen, valueBufferLen);
+        }
+    }
+    
+    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
+        
+#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;
+        
+        if (pathInUTF8Len + 2 >= CFMaxPathLength) {
+            result = false;
+        }
+        
+        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;
+        }
+        
+        do {
+            CFIndex nameLen = wcslen(filePt.cFileName);
+            if (filePt.cFileName[0] == '.' && (nameLen == 1 || (nameLen == 2  && filePt.cFileName[1] == '.'))) {
+                continue;
+            }
+            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);
+                        }
+                    } 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) {
+                            case _CFBundleFileVersionWithProductNoPlatform:
+                                platformRange = productRange;
+                                searchOffset = productLen;
+                            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);
+                                }
+                                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;
+    }
+    
+    free(cPathBuff);
+    CFAllocatorDeallocate(kCFAllocatorSystemDefault, valueBuff);
+    CFRelease(valueStr);
+    return result;
+}
+
+__private_extern__ CFDictionaryRef _CFBundleCreateQueryTableAtPath(CFBundleRef bundle, CFURLRef bundleURL, CFArrayRef languages, UniChar *resDir, CFIndex resDirLen, UniChar *subDir, CFIndex subDirLen)
+{
+    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);
+    CFMutableDictionaryRef typeDir = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFMutableStringRef type = CFStringCreateMutableWithExternalCharactersNoCopy(kCFAllocatorSystemDefault, NULL, 0, 0, kCFAllocatorNull); 
+    
+    CFStringRef productName = _CFGetProductName();//CFSTR("iphone");
+    CFStringRef platformName = _CFGetPlatformName();//CFSTR("iphoneos");
+    if (CFEqual(productName, CFSTR("ipod"))) {
+        productName = CFSTR("iphone");
+    }
+    CFStringRef product = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("~%@"), productName);
+    CFStringRef platform = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("-%@"), platformName);
+    
+    CFStringRef bundlePath = NULL;
+    if (bundle) {
+        bundlePath = _CFBundleGetBundlePath(bundle);
+        CFRetain(bundlePath);
+    } else {
+        CFURLRef url = CFURLCopyAbsoluteURL(bundleURL);
+        bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
+        CFRelease(url);
+    }
+    // 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);
+    }
+    
+    CFStringRef basePath = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, pathBuffer, pathLen);
+    
+    if (subDirLen > 0) { // should not fail, buffer has enought space
+        appendSucc = _CFAppendPathComponent(pathBuffer, &pathLen, pathBufferSize, subDir, subDirLen);
+    }
+    
+    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);
+    
+    CFIndex numOfAllFiles = CFArrayGetCount(allFiles);
+    
+    if (bundle && !languages) {
+        languages = _CFBundleGetLanguageSearchList(bundle);
+    }
+    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);
+        
+        if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) {
+            hasFileAdded = true;
+        }
+        firstLproj = false;
+    }
+    
+    // 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);
+    }
+    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);
+    
+    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);
+            }
+            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);
+            
+            if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) {
+                hasFileAdded = true;
+            }
+        }
+    }
+    
+    CFRelease(addedTypes);
+    
+    // put the array of all files in sub dir to the query table
+    if (CFArrayGetCount(allFiles) > 0) {
+        CFDictionarySetValue(queryTable, _CFBundleAllFiles, allFiles);
+    }
+    
+    CFRelease(platform);
+    CFRelease(product);
+    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)
+{
+    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);
+    } else {
+        url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, urlStr, PLATFORM_PATH_STYLE, NO);
+    }
+    
+    return url;
+}
+    
+static CFURLRef _CFBundleCreateRelativeURLFromBaseAndPath(CFStringRef path, CFURLRef base, UniChar slash, CFStringRef slashStr)
+{
+    CFURLRef url = NULL;
+    CFRange resultRange;
+    Boolean needToRelease = false;
+    if (CFStringFindWithOptions(path, slashStr, CFRangeMake(0, CFStringGetLength(path)-1), kCFCompareBackwards, &resultRange)) {
+        CFStringRef subPathCom = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, path, CFRangeMake(0, resultRange.location));
+        base = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, base, subPathCom, YES);
+        path = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, path, CFRangeMake(resultRange.location+1, CFStringGetLength(path)-resultRange.location-1));
+        CFRelease(subPathCom);
+        needToRelease = true;
+    }
+    if (CFStringGetCharacterAtIndex(path, CFStringGetLength(path)-1) == slash) {
+        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, YES, base);
+    } else {
+        url = (CFURLRef)CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, path, PLATFORM_PATH_STYLE, NO, base);
+    }
+    if (needToRelease) {
+        CFRelease(base);
+        CFRelease(path);
+    }
+    return url;
+}
+    
+static void _CFBundleFindResourcesWithPredicate(CFMutableArrayRef interResult, CFDictionaryRef queryTable, Boolean (^predicate)(CFStringRef filename, Boolean *stop), Boolean *stop)
+{
+    CFIndex dictSize = CFDictionaryGetCount(queryTable);
+    if (dictSize == 0) {
+        return;
+    }
+    STACK_BUFFER_DECL(CFTypeRef, keys, dictSize);
+    STACK_BUFFER_DECL(CFTypeRef, values, dictSize);
+    CFDictionaryGetKeysAndValues(queryTable, keys, values);
+    for (CFIndex i = 0; i < dictSize; i++) {
+        if (predicate((CFStringRef)keys[i], stop)) {
+            if (CFGetTypeID(values[i]) == CFStringGetTypeID()) {
+                CFArrayAppendValue(interResult, values[i]);
+            } else {
+                CFArrayAppendArray(interResult, (CFArrayRef)values[i], CFRangeMake(0, CFArrayGetCount((CFArrayRef)values[i])));
+            }
+        }
+        
+        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))
+{
+    CFTypeRef value = NULL;
+    Boolean stop = false; // for predicate
+    CFMutableArrayRef interResult = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+    CFDictionaryRef subTable = NULL;
+        
+    if (1 == bundleVersion) {
+        CFIndex savedResDirLen = resDirLen;
+        // 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);
+            }
+        }
+        resDirLen = savedResDirLen;
+    }
+    
+    if (!value && !stop) {
+        if (subTable) CFRelease(subTable);
+        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, resDir, resDirLen, subDirBuffer, subDirLen);
+        if (predicate) {
+            _CFBundleFindResourcesWithPredicate(interResult, subTable, predicate, &stop);
+        } else {
+            // get the path or paths for the given key
+            value = CFDictionaryGetValue(subTable, key);
+        }
+    }
+    
+    // if localization is needed, we filter out the paths for the localization and put the valid ones in the interResult
+    Boolean checkLP = true;
+    CFIndex lpLen = lproj ? CFStringGetLength(lproj) : 0;
+    if (localized && value) {
+        
+        if (CFGetTypeID(value) == CFStringGetTypeID()){
+            // We had one result, but since we are going to do a search in a different localization, we will convert the one result into an array of results.
+            value = CFArrayCreate(kCFAllocatorSystemDefault, (const void **)&value, 1, &kCFTypeArrayCallBacks);
+        } else {
+            CFRetain(value);
+        }
+        
+        CFRange resultRange, searchRange;
+        CFIndex pathValueLen;
+        CFIndex limit = returnArray ? CFArrayGetCount((CFArrayRef)value) : 1;
+        searchRange.location = 0;
+        for (CFIndex i = 0; i < limit; i++) {
+            CFStringRef pathValue = (CFStringRef) CFArrayGetValueAtIndex((CFArrayRef)value, i);
+            pathValueLen = CFStringGetLength(pathValue);
+            searchRange.length = pathValueLen;
+            
+            // 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 (CFStringFindWithOptions(pathValue, subDir, searchRange, kCFCompareEqualTo, &resultRange) && resultRange.location != searchRange.location) {
+                    searchForLocalization = true;
+                }
+            } else if (!subDirLen && searchRange.length != 0) {
+                if (CFStringFindWithOptions(pathValue, _CFBundleLprojExtensionWithDot, searchRange, kCFCompareEqualTo, &resultRange) && resultRange.location + 7 < pathValueLen) {
+                    searchForLocalization = true;
+                }
+            }
+            
+            if (searchForLocalization) {
+                if (!lpLen || !(CFStringFindWithOptions(pathValue, lproj, searchRange, kCFCompareEqualTo | kCFCompareAnchored, &resultRange) && CFStringFindWithOptions(pathValue, CFSTR("."), CFRangeMake(resultRange.location + resultRange.length, 1), kCFCompareEqualTo, &resultRange))) {
+                    break;
+                }
+                checkLP = false;
+            }
+            
+            CFArrayAppendValue(interResult, pathValue);
+        }
+        
+        CFRelease(value);
+        
+        if (!returnArray && CFArrayGetCount(interResult) != 0) {
+            checkLP = false;
+        }
+    } else if (value) {
+        if (CFGetTypeID(value) == CFArrayGetTypeID()) {
+            CFArrayAppendArray(interResult, (CFArrayRef)value, CFRangeMake(0, CFArrayGetCount((CFArrayRef)value)));
+        } else {
+            CFArrayAppendValue(interResult, value);
+        }
+    }
+    
+    value = NULL;
+    CFRelease(subTable);
+    
+    // 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);
+        }
+        subTable = _CFBundleCopyQueryTable(bundle, bundleURL, languages, resDir, resDirLen, lprojBuff, subDirLen+lprojBuffLen);
+        
+        value = CFDictionaryGetValue(subTable, key);
+        
+        if (value) {
+            if (CFGetTypeID(value) == CFStringGetTypeID()) {
+                CFArrayAppendValue(interResult, value);
+            } else {
+                CFArrayAppendArray(interResult, (CFArrayRef)value, CFRangeMake(0, CFArrayGetCount((CFArrayRef)value)));
+            }
+        }
+        
+        CFRelease(subTable);
+    }
+    
+    // after getting paths, we create urls from the paths
+    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;
+        if (bundle) {
+            bundlePath = _CFBundleGetBundlePath(bundle);
+            CFRetain(bundlePath);
+        } else {
+            CFURLRef url = CFURLCopyAbsoluteURL(bundleURL);
+            bundlePath = CFURLCopyFileSystemPath(url, PLATFORM_PATH_STYLE);
+            CFRelease(url);
+        }
+        CFIndex urlBufferLen = CFStringGetLength(bundlePath);
+        CFStringGetCharacters(bundlePath, CFRangeMake(0, urlBufferLen), urlBuffer);
+        CFRelease(bundlePath);
+        
+        if (resDirLen) {
+            _CFAppendPathComponent(urlBuffer, &urlBufferLen, CFMaxPathSize, resDir, resDirLen);
+        }
+        _CFAppendTrailingPathSlash(urlBuffer, &urlBufferLen, CFMaxPathSize);
+        
+        if (!returnArray) {
+            Boolean isOnlyTypeOrAllFiles = CFStringHasPrefix(key, _CFBundleTypeIndicator);
+            isOnlyTypeOrAllFiles |= CFStringHasPrefix(key, _CFBundleAllFiles);
+            
+            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);
+                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);
+            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);
+                CFArrayAppendValue(urls, url);
+                CFRelease(url);
+            }
+            result = urls;
+            CFRelease(base);
+        }
+        CFRelease(urlStr);
+        CFAllocatorDeallocate(kCFAllocatorSystemDefault, urlBuffer);
+    } else if (returnArray) {
+        result = CFRetain(interResult);
+    }
+    
+    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))
+{
+    CFIndex rnameLen = 0;
+    CFIndex typeLen = resourceType ? CFStringGetLength(resourceType) : 0;
+    CFIndex lprojLen = lproj ? CFStringGetLength(lproj) + 7 : 0; // 7 is the length of ".lproj/"
+    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);
+        }
+        
+        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);
+    } else {
+        key = (CFStringRef)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);
+        }
+    }
+    
+    // Init the one-time-only unichar buffers.
+    _CFEnsureStaticBuffersInited();
+    
+    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);
+        
+    if ((!returnValue || (CFGetTypeID(returnValue) == CFArrayGetTypeID() && CFArrayGetCount((CFArrayRef)returnValue) == 0)) && (0 == bundleVersion || 2 == bundleVersion)) {
+        CFStringRef bundlePath = NULL;
+        if (bundle) {
+            bundlePath = _CFBundleGetBundlePath(bundle);
+            CFRetain(bundlePath);
+        } else {
+            CFURLRef absoluteURL = CFURLCopyAbsoluteURL(bundleURL);
+            bundlePath = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE);
+            CFRelease(absoluteURL);
+        }
+        if ((0 == bundleVersion) || CFEqual(CFSTR("/Library/Spotlight"), bundlePath)){
+            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;
+            } else {
+                resDirLen = 0;
+            }
+            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);
+        }
+        CFRelease(bundlePath);
+    }
+
+    if (resourceName) CFRelease(resourceName);
+    if (subPath) CFRelease(subPath);
+    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);
+}
diff --git a/CFBurstTrie.c b/CFBurstTrie.c
new file mode 100644 (file)
index 0000000..b723321
--- /dev/null
@@ -0,0 +1,2095 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*  CFBurstTrie.c
+    Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+    Responsibility: Jennifer Moore
+*/
+
+#include "CFInternal.h"
+#include "CFBurstTrie.h"
+#include "CFByteOrder.h"
+#include "CFNumber.h"
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <limits.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#include <unistd.h>
+#include <sys/param.h>
+#include <sys/mman.h>
+#endif
+
+#include <errno.h>
+#include <assert.h>
+
+#if DEPLOYMENT_TARGET_WINDOWS
+#define open _NS_open
+#define statinfo _stat
+#define stat(x,y) _NS_stat(x,y)
+#define __builtin_memcmp(x, y, z) memcmp(x, y, z)
+#define __builtin_popcountll(x) popcountll(x)
+#define bzero(dst, size)    ZeroMemory(dst, size)
+#define S_IWUSR 0
+#define S_IRUSR 0
+
+static int pwrite(int fd, const void *buf, size_t nbyte, off_t offset) {
+    // Get where we are
+    long pos = _tell(fd);
+    
+    // Move to new offset
+    _lseek(fd, offset, SEEK_SET);
+    
+    // Write data
+    int res = _write(fd, buf, nbyte);
+    
+    // Return to previous offset
+    _lseek(fd, pos, SEEK_SET);
+    
+    return res;
+}
+
+#else
+#define statinfo stat
+#endif
+
+#if 0
+#pragma mark Types and Utilities
+#endif
+
+#define MAX_STRING_ALLOCATION_SIZE  342
+#define MAX_STRING_SIZE             1024
+#define MAX_KEY_LENGTH              MAX_STRING_SIZE * 4
+#define CHARACTER_SET_SIZE          256
+#define MAX_LIST_SIZE               256 // 64
+#define MAX_BITMAP_SIZE             200
+#define MAX_BUFFER_SIZE             (4096<<2)
+
+#define NextTrie_GetPtr(p)  (p & ((~(uintptr_t)0)-3))
+#define NextTrie_GetKind(p) (p & 3)
+#define NextTrie_SetKind(p, kind) (p |= (3&kind))
+
+#define DiskNextTrie_GetPtr(map,offset)  (((uintptr_t)map) + (uintptr_t)(offset & ((~(uintptr_t)0)-3)))
+#define DiskNextTrie_GetKind(p) (p & 3)
+#define DiskNextTrie_SetKind(p, kind) (p |= (3&kind))
+
+// Use this macro to avoid forgetting to check the pointer before assigning value to it.
+#define SetPayload(pointer, value) do { if (pointer) *pointer = value; } while (0)
+
+enum { Nothing = 0, TrieKind = 1, ListKind = 2, CompactTrieKind = 3 };
+typedef enum { FailedInsert = 0, NewTerm = 1, ExistingTerm = 2 } CFBTInsertCode; 
+
+#pragma pack (1)
+typedef uintptr_t NextTrie;
+
+typedef struct _TrieLevel {
+    NextTrie slots[CHARACTER_SET_SIZE];
+    uint32_t weight;        
+    uint32_t payload;
+} TrieLevel;
+typedef TrieLevel *TrieLevelRef;
+
+typedef struct _MapTrieLevel {
+    uint32_t slots[CHARACTER_SET_SIZE];
+    uint32_t payload;
+} MapTrieLevel;
+typedef MapTrieLevel *MapTrieLevelRef;
+
+typedef struct _CompactMapTrieLevel {
+    uint64_t bitmap[CHARACTER_SET_SIZE / 64];
+    uint32_t payload;
+    uint32_t slots[];
+} CompactMapTrieLevel;
+typedef CompactMapTrieLevel *CompactMapTrieLevelRef;
+
+typedef struct _ListNode {
+    struct _ListNode *next;
+    uint32_t weight;
+    uint32_t payload;
+    uint16_t length;
+    UInt8 string[];
+}* ListNodeRef;
+
+typedef struct _Page {
+    uint32_t length;
+    char data[];
+} Page;
+
+typedef struct _PageEntryPacked {
+    uint8_t pfxLen;
+    uint16_t strlen;
+    uint32_t payload;
+    UInt8 string[];
+} PageEntryPacked;
+
+typedef struct _PageEntry {
+    uint16_t strlen;
+    uint32_t payload;
+    UInt8 string[];
+} PageEntry;
+
+typedef struct _TrieHeader {
+    uint32_t signature;
+    uint32_t rootOffset; 
+    uint32_t count; 
+    uint32_t size; 
+    uint32_t flags;
+    uint64_t reserved[16];
+} TrieHeader;
+
+typedef struct _TrieCursor {
+    uint64_t signature;
+    uint64_t counter;
+    NextTrie next;
+    uint32_t keylen;
+    uint32_t prefixlen;
+    const uint8_t *prefix;
+    uint8_t key[MAX_KEY_LENGTH];
+} TrieCursor;
+
+typedef struct _MapCursor {
+    uint64_t signature;
+    TrieHeader *header;
+    uint32_t next;
+    uint32_t prefixlen;
+    uint32_t keylen;
+    const uint8_t *prefix;
+    uint8_t key[MAX_STRING_SIZE*4];
+} MapCursor;
+
+typedef struct _CompactMapCursor {
+    uint32_t next;
+    uint32_t entryOffsetInPage;
+    uint32_t offsetInEntry;
+    uint32_t payload;
+    // On a page, the first entry could has 0 strlen. So we need this variable to tell us whether
+    // the cursor is merely pointing at the beginning of the page, or the first entry.
+    // For example, if the trie contains "ab" and "abc", where "a" is stored on an array level,
+    // while "b" and "bc" are stored on a page level. If we creat a cursor for string "a", this cursor
+    // will point at the beginning of the page, but not at any particular key. The both entryOffsetInPage and
+    // offsetInEntry fields of the cursor are set to 0 in this case. Now if we add "a" to the 
+    // trie. the page level will actually contains three entries. The first entry corresponds to string "a".
+    // That entry has 0 strlen value. If we creat a cursor for string "a" again, this cursor will
+    // point at the first entry on the page. But the entryOffsetInPage and offsetInEntry fields are still
+    // set to 0s. So we need an additional variable to make distinction between these two situations.
+    BOOL isOnPage;
+} CompactMapCursor;
+typedef struct _CompactMapCursor *MapCursorRef;
+
+enum {
+    _kCFBurstTrieCursorTrieType = 0,
+    _kCFBurstTrieCursorMapType
+};
+
+typedef struct _CFBurstTrieCursor {
+    CompactMapCursor mapCursor;
+    CFIndex cursorType;
+    CFBurstTrieRef trie;
+} _CFBurstTrieCursor;
+
+// ** Legacy
+typedef struct _DiskTrieLevel {
+    uint32_t slots[CHARACTER_SET_SIZE];
+    uint32_t weight;        
+    uint32_t payload;
+} DiskTrieLevel;
+typedef DiskTrieLevel *DiskTrieLevelRef;
+
+typedef struct _CompactDiskTrieLevel {
+    uint64_t bitmap[CHARACTER_SET_SIZE / 64]; // CHARACTER_SET_SIZE / 64bits per word 
+    uint32_t weight;        
+    uint32_t payload;
+    uint32_t slots[];
+} CompactDiskTrieLevel;
+typedef CompactDiskTrieLevel *CompactDiskTrieLevelRef;
+
+typedef struct _StringPage {
+    uint32_t length;
+    char data[];
+} StringPage;
+
+typedef struct _StringPageEntryPacked {
+    uint8_t pfxLen;
+    uint16_t strlen;    // make uint8_t if possible
+    uint32_t payload;
+    char string[];
+} StringPageEntryPacked;
+
+typedef struct _StringPageEntry {
+    uint16_t strlen;    // make uint8_t if possible
+    uint32_t payload;
+    char string[];
+} StringPageEntry;
+
+typedef struct _fileHeader {
+    uint32_t signature;
+    uint32_t rootOffset; 
+    uint32_t count; 
+    uint32_t size; 
+    uint32_t flags;
+} fileHeader;
+// **
+#pragma pack()
+
+struct _CFBurstTrie {
+    union {
+        TrieLevel root;
+        DiskTrieLevel diskRoot;
+        MapTrieLevel maproot;
+    };    
+    char *mapBase;
+    uint32_t mapSize;
+    uint32_t mapOffset;
+    uint32_t cflags;
+    uint32_t count;
+    uint32_t containerSize;
+    int retain;
+#if DEPLOYMENT_TARGET_WINDOWS
+    HANDLE mapHandle;
+    HANDLE mappedFileHandle;
+#endif
+};
+
+#if 0
+#pragma mark -
+#pragma mark Forward declarations
+#endif
+
+typedef struct _TraverseContext {
+    void *context;
+    void (*callback)(void*, const UInt8*, uint32_t, uint32_t);
+} TraverseContext;
+
+bool foundKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
+{
+    if (context != NULL) {
+        TraverseContext *ctx = (TraverseContext *)context;
+        if (ctx->context && ctx->callback) {
+            ctx->callback(ctx->context, key, 1, payload);
+        }
+    }
+    return false;
+}
+
+void CFBurstTrieTraverseWithCursor(CFBurstTrieRef trie, const uint8_t *prefix, uint32_t prefixLen, void **cursor, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool));
+
+static CFBTInsertCode addCFBurstTrieLevel(CFBurstTrieRef trie, TrieLevelRef root, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload);
+
+static void findCFBurstTrieLevel(CFBurstTrieRef trie, TrieCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool));
+static void findCFBurstTrieMappedLevel(CFBurstTrieRef trie, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool));
+static void traverseCFBurstTrieLevel(CFBurstTrieRef trie, TrieLevelRef root, TrieCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool));
+static void traverseCFBurstTrieMappedLevel(CFBurstTrieRef trie, MapTrieLevelRef root, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool));
+static void traverseCFBurstTrieCompactMappedLevel(CFBurstTrieRef trie, CompactMapTrieLevelRef root, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool));
+static void traverseCFBurstTrieWithCursor(CFBurstTrieRef trie, const uint8_t *prefix, uint32_t prefixLen, void **cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool));
+
+static size_t serializeCFBurstTrie(CFBurstTrieRef trie, size_t start_offset, int fd);
+
+static Boolean burstTrieMappedFind(DiskTrieLevelRef trie, char *map, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix);
+static Boolean burstTrieMappedPageFind(StringPage *page, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix);
+static Boolean burstTrieCompactTrieMappedFind(CompactDiskTrieLevelRef trie, char *map, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix);
+
+static void destroyCFBurstTrie(CFBurstTrieRef trie);
+static void finalizeCFBurstTrie(TrieLevelRef trie);
+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 CFIndex burstTrieConvertCharactersToUTF8(UniChar *chars, CFIndex numChars, UInt8 *buffer);
+
+static Boolean advanceMapCursor(CFBurstTrieRef trie, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length);
+static Boolean getMapCursorPayload(CFBurstTrieRef trie, const CompactMapCursor *cursor, uint32_t *payload);
+static void copyMapCursor(const CompactMapCursor *source, CompactMapCursor* destination);
+static Boolean areMapCursorsEqual(const CompactMapCursor *lhs, const CompactMapCursor *rhs);
+static void traverseFromMapCursor(CFBurstTrieRef trie, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback);
+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));
+    trie->containerSize = MAX_LIST_SIZE;
+
+    CFNumberRef valueAsCFNumber;
+    if (CFDictionaryGetValueIfPresent(options, kCFBurstTrieCreationOptionNameContainerSize, (const void **)&valueAsCFNumber)) {
+        int value;
+        CFNumberGetValue(valueAsCFNumber, kCFNumberIntType, &value);
+        trie->containerSize = value > 2 && value < 4096 ? value : MAX_LIST_SIZE;
+    }
+    trie->retain = 1;
+    return trie;
+}
+
+CFBurstTrieRef CFBurstTrieCreate() {
+    CFBurstTrieRef trie = NULL;
+    int listSize = MAX_LIST_SIZE;
+    CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &listSize);
+    CFMutableDictionaryRef options = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, NULL, NULL);
+    CFDictionarySetValue(options, kCFBurstTrieCreationOptionNameContainerSize, value);
+    trie = CFBurstTrieCreateWithOptions(options);
+    CFRelease(value);
+    CFRelease(options);
+    return trie;
+}
+
+CFBurstTrieRef CFBurstTrieCreateFromFile(CFStringRef path) {
+    struct statinfo sb;
+    char filename[PATH_MAX];
+    int fd;
+    
+    /* Check valid path name */
+    if (!CFStringGetCString(path, filename, PATH_MAX, kCFStringEncodingUTF8)) return NULL;
+    
+    /* Check if file exists */
+    if (stat(filename, &sb) != 0) return NULL;
+
+    /* Check if file can be opened */
+    if ((fd=open(filename, CF_OPENFLGS|O_RDONLY)) < 0) return NULL;
+    
+#if DEPLOYMENT_TARGET_WINDOWS
+    HANDLE mappedFileHandle = (HANDLE)_get_osfhandle(fd);   
+    if (!mappedFileHandle) return NULL;
+    
+    HANDLE mapHandle = CreateFileMapping(mappedFileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
+    if (!mapHandle) return NULL;
+    
+    char *map = (char *)MapViewOfFile(mapHandle, FILE_MAP_READ, 0, 0, sb.st_size);
+    if (!map) return NULL;
+#else            
+    char *map = mmap(0, sb.st_size, PROT_READ, MAP_FILE|MAP_SHARED, fd, 0);
+#endif
+    
+    CFBurstTrieRef trie = NULL;
+    TrieHeader *header = (TrieHeader *)map;
+
+    if (((uint32_t*)map)[0] == 0xbabeface) {
+        trie = (CFBurstTrieRef) calloc(1, sizeof(struct _CFBurstTrie));
+        trie->mapBase = map;
+        trie->mapSize = CFSwapInt32LittleToHost(sb.st_size); 
+        trie->mapOffset = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->rootOffset);
+        trie->cflags = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->flags);
+        trie->count = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->count);
+        trie->retain = 1;
+#if DEPLOYMENT_TARGET_WINDOWS
+        trie->mappedFileHandle = mappedFileHandle;
+        trie->mapHandle = mapHandle;
+#else
+        // On Windows, the file being mapped must stay open as long as the map exists. Don't close it early. Other platforms close it here.
+        close(fd);
+#endif
+    } else if (header->signature == 0xcafebabe || header->signature == 0x0ddba11) {
+        trie = (CFBurstTrieRef) calloc(1, sizeof(struct _CFBurstTrie));
+        trie->mapBase = map;
+        trie->mapSize = CFSwapInt32LittleToHost(sb.st_size); 
+        trie->cflags = CFSwapInt32LittleToHost(header->flags);
+        trie->count = CFSwapInt32LittleToHost(header->count);
+        trie->retain = 1;
+#if DEPLOYMENT_TARGET_WINDOWS
+        trie->mappedFileHandle = mappedFileHandle;
+        trie->mapHandle = mapHandle;
+#else
+        // On Windows, the file being mapped must stay open as long as the map exists. Don't close it early. Other platforms close it here.
+        close(fd);
+#endif
+    }
+    return trie;
+}
+
+CFBurstTrieRef CFBurstTrieCreateFromMapBytes(char *mapBase) {
+    CFBurstTrieRef trie = NULL;
+    TrieHeader *header = (TrieHeader *)mapBase;
+
+    if (mapBase && ((uint32_t*)mapBase)[0] == 0xbabeface) {
+        trie = (CFBurstTrieRef) malloc(sizeof(struct _CFBurstTrie));
+        trie->mapBase = mapBase;
+        trie->mapSize = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->size);
+        trie->mapOffset = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->rootOffset);
+        trie->cflags = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->flags);
+        trie->count = CFSwapInt32LittleToHost(((fileHeader*)trie->mapBase)->count);
+        trie->retain = 1;
+    } else if (mapBase && (header->signature == 0xcafebabe || header->signature == 0x0ddba11)) {
+        trie = (CFBurstTrieRef) malloc(sizeof(struct _CFBurstTrie));
+        trie->mapBase = mapBase;
+        trie->mapSize = CFSwapInt32LittleToHost(header->size);
+        trie->cflags = CFSwapInt32LittleToHost(header->flags);
+        trie->count = CFSwapInt32LittleToHost(header->count);
+        trie->retain = 1;
+    }
+    return trie;
+}
+
+Boolean CFBurstTrieInsert(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex payload) {
+    return CFBurstTrieAddWithWeight(trie, term, termRange, 1, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAdd(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t payload) {
+    return CFBurstTrieAddWithWeight(trie, term, termRange, 1, payload);
+}
+
+Boolean CFBurstTrieInsertCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex payload) {
+    return CFBurstTrieAddCharactersWithWeight(trie, chars, numChars, 1, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAddCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t payload) {
+    return CFBurstTrieAddCharactersWithWeight(trie, chars, numChars, 1, payload);
+}
+
+Boolean CFBurstTrieInsertUTF8String(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, CFIndex payload) {
+    return CFBurstTrieAddUTF8StringWithWeight(trie, chars, numChars, 1, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAddUTF8String(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, uint32_t payload) {
+    return CFBurstTrieAddUTF8StringWithWeight(trie, chars, numChars, 1, payload);
+}
+
+Boolean CFBurstTrieInsertWithWeight(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex weight, CFIndex payload) {
+    return CFBurstTrieAddWithWeight(trie, term, termRange, weight, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAddWithWeight(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t weight, uint32_t payload) {
+    Boolean success = false;
+    CFIndex size = MAX_STRING_ALLOCATION_SIZE;
+    CFIndex bytesize = termRange.length * 4; //** 4-byte max character size
+    if (!trie->mapBase && termRange.length < MAX_STRING_SIZE && payload > 0) {
+        CFIndex length;
+        UInt8 buffer[MAX_STRING_ALLOCATION_SIZE + 1];
+        UInt8 *key = buffer;
+        if (bytesize >= size) {
+            size = bytesize; 
+            key = (UInt8 *) malloc(sizeof(UInt8) * size + 1);
+        }
+        CFStringGetBytes(term, termRange, kCFStringEncodingUTF8, (UInt8)'-', (Boolean)0, key, size, &length);
+        key[length] = 0;
+        
+        success = CFBurstTrieAddUTF8StringWithWeight(trie, key, length, weight, payload);
+        if (buffer != key) free(key);
+    }
+    return success;
+}
+
+Boolean CFBurstTrieInsertCharactersWithWeight(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex weight, CFIndex payload) {
+    return CFBurstTrieAddCharactersWithWeight(trie, chars, numChars, weight, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAddCharactersWithWeight(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t weight, uint32_t payload) {
+    Boolean success = false;
+    CFIndex size = MAX_STRING_ALLOCATION_SIZE;
+    CFIndex bytesize = numChars * 4; //** 4-byte max character size
+    if (!trie->mapBase && numChars < MAX_STRING_SIZE && payload > 0) {
+        CFIndex length;
+        UInt8 buffer[MAX_STRING_ALLOCATION_SIZE + 1];
+        UInt8 *key = buffer;
+        if (bytesize >= size) {
+            size = bytesize; 
+            key = (UInt8 *) malloc(sizeof(UInt8) * size + 1);
+        }
+        length = burstTrieConvertCharactersToUTF8(chars, numChars, key);
+        key[length] = 0;
+        
+        success = CFBurstTrieAddUTF8StringWithWeight(trie, key, length, weight, payload);
+        if (buffer != key) free(key);
+    }
+    return success;
+}
+
+Boolean CFBurstTrieInsertUTF8StringWithWeight(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, CFIndex weight, CFIndex payload) {
+    return CFBurstTrieAddUTF8StringWithWeight(trie, chars, numChars, weight, (uint32_t)payload);
+}
+
+Boolean CFBurstTrieAddUTF8StringWithWeight(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, uint32_t weight, uint32_t payload) {
+    CFBTInsertCode code = FailedInsert;
+    
+    if (!trie->mapBase && numChars < MAX_STRING_SIZE*4 && payload > 0) {
+        code = addCFBurstTrieLevel(trie, &trie->root, chars, numChars, weight, payload);
+        if (code == NewTerm) trie->count++;
+    }
+    return code > FailedInsert;
+}
+
+Boolean CFBurstTrieFind(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex *payload) {
+    uint32_t p;
+    if (CFBurstTrieContains(trie, term, termRange, &p)) {
+        SetPayload(payload, p);
+        return true;
+    }
+    return false;
+}
+
+Boolean CFBurstTrieContains(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t *payload) {
+    Boolean success = false;
+    CFIndex size = MAX_STRING_ALLOCATION_SIZE;
+    CFIndex bytesize = termRange.length * 4; //** 4-byte max character size
+    if (termRange.length < MAX_STRING_SIZE) {
+        CFIndex length;
+        UInt8 buffer[MAX_STRING_ALLOCATION_SIZE+1];
+        UInt8 *key = buffer;
+        if (bytesize >= size) {
+            size = bytesize;
+            key = (UInt8 *) malloc(sizeof(UInt8) * size + 1);
+        }
+        CFStringGetBytes(term, termRange, kCFStringEncodingUTF8, (UInt8)'-', (Boolean)0, key, size, &length);
+        key[length] = 0;
+        
+        success = CFBurstTrieContainsUTF8String(trie, key, length, payload);
+        if (buffer != key) free(key);
+    }
+    return success;
+}
+
+Boolean CFBurstTrieFindCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex *payload) {
+    uint32_t p;
+    if (CFBurstTrieContainsCharacters(trie, chars, numChars, &p)) {
+        SetPayload(payload, p);
+        return true;
+    }
+    return false;
+}
+
+Boolean CFBurstTrieContainsCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t *payload) {
+    Boolean success = false;
+    CFIndex size = MAX_STRING_ALLOCATION_SIZE;
+    CFIndex bytesize = numChars * 4; //** 4-byte max character size
+    if (numChars < MAX_STRING_SIZE) {
+        CFIndex length;
+        UInt8 buffer[MAX_STRING_ALLOCATION_SIZE + 1];
+        UInt8 *key = buffer;
+        if (bytesize >= size) {
+            size = bytesize;
+            key = (UInt8 *) malloc(sizeof(UInt8) * size + 1);
+        }
+        length = burstTrieConvertCharactersToUTF8(chars, numChars, key);
+        key[length] = 0;
+        
+        success = CFBurstTrieContainsUTF8String(trie, key, length, payload);
+        if (buffer != key) free(key);
+    }
+    return success;
+}
+
+Boolean CFBurstTrieFindUTF8String(CFBurstTrieRef trie, UInt8 *key, CFIndex length, CFIndex *payload) {
+    uint32_t p;
+    if (CFBurstTrieContainsUTF8String(trie, key, length, &p)) {
+        SetPayload(payload, p);
+        return true;
+    }
+    return false;
+}
+
+Boolean CFBurstTrieContainsUTF8String(CFBurstTrieRef trie, UInt8 *key, CFIndex length, uint32_t *payload) {
+    Boolean success = false;
+    if (length < MAX_STRING_SIZE) {
+        if (trie->mapBase && ((fileHeader *)trie->mapBase)->signature == 0xbabeface) {
+            bool prefix = (trie->cflags & kCFBurstTriePrefixCompression);
+            success = burstTrieMappedFind((DiskTrieLevelRef)(trie->mapBase+CFSwapInt32LittleToHost((((uint32_t*)trie->mapBase)[1]))), trie->mapBase, key, length, payload, prefix);
+        } else if (trie->mapBase && trie->cflags & (kCFBurstTriePrefixCompression | kCFBurstTrieSortByKey)) {
+            _CFBurstTrieCursor cursor;
+            if (!CFBurstTrieSetCursorForBytes(trie, &cursor, key, length))
+                return FALSE;
+            return CFBurstTrieCursorGetPayload(&cursor, payload);
+        } else {
+            uint32_t found = 0;
+            void *cursor = 0;
+            traverseCFBurstTrieWithCursor(trie, key, length, &cursor, true, &found, containsKey);
+            if (found) SetPayload(payload, found);
+            success = found > 0;
+        }
+    }
+    return success;
+}
+
+Boolean CFBurstTrieSerialize(CFBurstTrieRef trie, CFStringRef path, CFBurstTrieOpts opts) {    
+    Boolean success = false;    
+    if (trie->mapBase) {
+        return success;
+    } else {
+        int fd;
+        char filename[PATH_MAX];
+        
+        /* Check valid path name */
+        if (!CFStringGetCString(path, filename, PATH_MAX, kCFStringEncodingUTF8)) return success;
+        
+        /* Check if file can be opened */
+        if ((fd=open(filename, CF_OPENFLGS|O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR)) < 0) return success;
+        
+        if (CFBurstTrieSerializeWithFileDescriptor(trie, fd, opts)) success = true;
+        
+        close(fd);
+    }
+    return success;
+}
+
+Boolean CFBurstTrieSerializeWithFileDescriptor(CFBurstTrieRef trie, int fd, CFBurstTrieOpts opts) {
+    Boolean success = false;
+    if (!trie->mapBase && fd >= 0) {
+        off_t start_offset = lseek(fd, 0, SEEK_END);
+
+        trie->cflags = opts;
+        trie->mapSize = serializeCFBurstTrie(trie, start_offset, fd);
+        
+#if DEPLOYMENT_TARGET_WINDOWS
+        HANDLE mappedFileHandle = (HANDLE)_get_osfhandle(fd);
+        // We need to make sure we have our own handle to keep this file open as long as the mmap lasts
+        DuplicateHandle(GetCurrentProcess(), mappedFileHandle, GetCurrentProcess(), &mappedFileHandle, 0, 0, DUPLICATE_SAME_ACCESS);
+        HANDLE mapHandle = CreateFileMapping(mappedFileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
+        if (!mapHandle) return NULL;
+        char *map = (char *)MapViewOfFile(mapHandle, FILE_MAP_READ, 0, start_offset, trie->mapSize);
+        if (!map) return NULL;
+        trie->mapBase = map;
+        trie->mapHandle = mapHandle;
+        trie->mappedFileHandle = mappedFileHandle;
+#else
+        trie->mapBase = mmap(0, trie->mapSize, PROT_READ, MAP_FILE|MAP_SHARED, fd, start_offset);
+#endif
+        success = true;
+    }
+    
+    return success;
+}
+
+void CFBurstTrieTraverse(CFBurstTrieRef trie, void *ctx, void (*callback)(void*, const UInt8*, uint32_t, uint32_t)) {
+    TrieHeader *header = (TrieHeader *)trie->mapBase;
+    if (!trie->mapBase || (header->signature == 0xcafebabe || header->signature == 0x0ddba11)) {
+        void *cursor = 0;
+        TraverseContext context;
+        context.context = ctx;
+        context.callback = callback;
+        traverseCFBurstTrieWithCursor(trie, (const uint8_t *)"", 0, &cursor, false, &context, foundKey);
+    }
+}
+
+
+void CFBurstTrieTraverseWithCursor(CFBurstTrieRef trie, const uint8_t *prefix, uint32_t prefixLen, void **cursor, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool))
+{
+    traverseCFBurstTrieWithCursor(trie, prefix, prefixLen, cursor, false, ctx, callback);
+}
+
+void CFBurstTriePrint(CFBurstTrieRef trie) {
+
+}
+
+CFIndex CFBurstTrieGetCount(CFBurstTrieRef trie) {
+    return trie->count;
+}
+
+CFBurstTrieRef CFBurstTrieRetain(CFBurstTrieRef trie) {
+    trie->retain++;
+    return trie;
+}
+
+void CFBurstTrieRelease(CFBurstTrieRef trie) {
+    trie->retain--;
+    if (trie->retain == 0) destroyCFBurstTrie(trie);
+    return;
+}
+
+Boolean CFBurstTrieSetCursorForBytes(CFBurstTrieRef trie, CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length)
+{
+    if (!trie->mapBase || !(trie->cflags & (kCFBurstTriePrefixCompression | kCFBurstTrieSortByKey))) {
+        //fprintf(stderr, "CFBurstTrieCreateCursorForBytes() only support file based trie in prefix compression format.\n");
+        return FALSE;
+    }
+
+    TrieHeader *header = (TrieHeader*)trie->mapBase;
+    if (length < 0 || !trie)
+        return FALSE;
+
+    cursor->trie = trie;
+    if (trie->mapBase) {
+        cursor->cursorType = _kCFBurstTrieCursorMapType;
+        cursor->mapCursor.next = header->rootOffset;
+        cursor->mapCursor.isOnPage = FALSE;
+        cursor->mapCursor.entryOffsetInPage = 0;
+        cursor->mapCursor.offsetInEntry = 0;
+        cursor->mapCursor.payload = 0;
+    } else
+        assert(false);
+
+    if (!bytes || length == 0)
+        return TRUE;
+
+    return CFBurstTrieCursorAdvanceForBytes(cursor, bytes, length);
+}
+
+
+CFBurstTrieCursorRef CFBurstTrieCreateCursorForBytes(CFBurstTrieRef trie, const UInt8* bytes, CFIndex length)
+{
+    CFBurstTrieCursorRef cursor = (CFBurstTrieCursorRef)calloc(sizeof(_CFBurstTrieCursor), 1);
+    if (!CFBurstTrieSetCursorForBytes(trie, cursor, bytes, length)) {
+        CFBurstTrieCursorRelease(cursor);
+        return NULL;
+    }
+    return cursor;
+}
+
+CFBurstTrieCursorRef CFBurstTrieCursorCreateByCopy(CFBurstTrieCursorRef cursor)
+{
+    if (!cursor)
+        return NULL;
+
+    CFBurstTrieCursorRef newCursor = (CFBurstTrieCursorRef)calloc(sizeof(_CFBurstTrieCursor), 1);
+    switch (cursor->cursorType) {
+        case _kCFBurstTrieCursorMapType:
+            copyMapCursor(&cursor->mapCursor, &newCursor->mapCursor);
+            break;
+        case _kCFBurstTrieCursorTrieType:
+            assert(false);
+            break;
+    }
+    newCursor->cursorType = cursor->cursorType;
+    newCursor->trie = cursor->trie;
+    return newCursor;
+}
+
+Boolean CFBurstTrieCursorIsEqual(CFBurstTrieCursorRef lhs, CFBurstTrieCursorRef rhs)
+{
+    if (lhs->trie != rhs->trie || lhs->cursorType != rhs->cursorType)
+        return FALSE;
+
+    if (lhs->cursorType == _kCFBurstTrieCursorMapType)
+        return areMapCursorsEqual(&lhs->mapCursor, &rhs->mapCursor);
+    else
+        return FALSE;
+}
+
+Boolean CFBurstTrieCursorAdvanceForBytes(CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length)
+{
+    switch (cursor->cursorType) {
+        case _kCFBurstTrieCursorMapType: {
+            CompactMapCursor tempCursor;
+            copyMapCursor(&cursor->mapCursor, &tempCursor);
+            if (advanceMapCursor(cursor->trie, (CompactMapCursor*)&cursor->mapCursor, bytes, length))
+                return TRUE;
+            else {
+                copyMapCursor(&tempCursor, &cursor->mapCursor);
+                return FALSE;
+            }
+        }
+        case _kCFBurstTrieCursorTrieType:
+            return FALSE;
+    }
+    return FALSE;
+}
+
+Boolean CFBurstTrieCursorGetPayload(CFBurstTrieCursorRef cursor, uint32_t *payload)
+{
+    switch (cursor->cursorType) {
+        case _kCFBurstTrieCursorMapType:
+            return getMapCursorPayload(cursor->trie, (CompactMapCursor*)&cursor->mapCursor, payload);
+        case _kCFBurstTrieCursorTrieType:
+            return FALSE;
+    }
+    return FALSE;
+}
+
+void CFBurstTrieCursorRelease(CFBurstTrieCursorRef cursor)
+{
+    if (!cursor)
+        return;
+    free(cursor);
+}
+
+void CFBurstTrieTraverseFromCursor(CFBurstTrieCursorRef cursor, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    if (!cursor)
+        return;
+
+    UInt8 *bytes = (UInt8*)calloc(1, MAX_KEY_LENGTH);
+    uint32_t capacity = MAX_KEY_LENGTH;
+    uint32_t length = 0;
+    Boolean stop = FALSE;
+    switch (cursor->cursorType) {
+        case _kCFBurstTrieCursorMapType: {
+            CompactMapCursor tempCursor;
+            copyMapCursor(&cursor->mapCursor, &tempCursor);
+            traverseFromMapCursor(cursor->trie, &tempCursor, bytes, capacity,length, &stop, ctx, callback);
+            break;
+        }
+        case _kCFBurstTrieCursorTrieType:
+            break;
+    }
+    free(bytes);
+}
+
+#if 0
+#pragma mark -
+#pragma mark Insertion
+#endif
+
+static ListNodeRef makeCFBurstTrieListNode(const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload) {
+    ListNodeRef node = (ListNodeRef) calloc(1, sizeof(*node) + keylen + 1);
+    memcpy(node->string, key, keylen);
+    node->string[keylen] = 0;
+    node->next = 0;
+    node->length = keylen;
+    node->weight = weight;
+    node->payload = payload;
+    return node;
+}
+
+static void addCFBurstTrieBurstLevel(CFBurstTrieRef trie, TrieLevelRef root, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload) {
+    if (keylen) {
+        NextTrie next = root->slots[*key];
+        ListNodeRef newNode = makeCFBurstTrieListNode(key+1, keylen-1, weight, payload);
+        newNode->weight = weight;
+        newNode->next = (ListNodeRef) NextTrie_GetPtr(next);
+        next = (uintptr_t) newNode;
+        NextTrie_SetKind(next, ListKind);
+        root->slots[*key] = next;
+    } else { 
+        // ** Handle payload.
+        root->weight = weight;
+        root->payload = payload;
+    }
+}
+
+static TrieLevelRef burstCFBurstTrieLevel(CFBurstTrieRef trie, ListNodeRef list, uint32_t listCount) {
+    TrieLevelRef newLevel = (TrieLevelRef) calloc(1, sizeof(struct _TrieLevel));
+    while (list) {
+        addCFBurstTrieBurstLevel(trie, newLevel, list->string, list->length, list->weight, list->payload);
+        ListNodeRef temp = list;
+        list = list->next;
+        free(temp);
+    }
+    return newLevel;
+}
+
+static CFBTInsertCode addCFBurstTrieListNode(CFBurstTrieRef trie, ListNodeRef list, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload, uint32_t *listCount)
+{
+    CFBTInsertCode code = FailedInsert;
+    uint32_t count = 1;
+    
+    ListNodeRef last = list;
+    while (list) {
+        if (list->length == keylen && memcmp(key, list->string, keylen) == 0) {
+            list->weight += weight;
+            list->payload = payload;
+            code = ExistingTerm;
+            break;
+        } else {
+            count++;
+            last = list;
+            list = list->next;
+        }
+    }
+    
+    if (!list) {
+        last->next = makeCFBurstTrieListNode(key, keylen, weight, payload);
+        code = NewTerm;
+    }
+    
+    *listCount = count;
+    return code;
+}
+
+static CFBTInsertCode addCFBurstTrieLevel(CFBurstTrieRef trie, TrieLevelRef root, const uint8_t *key, uint32_t keylen, uint32_t weight, uint32_t payload)
+{
+    CFBTInsertCode code = FailedInsert;
+    if (keylen) {
+        NextTrie next = root->slots[*key];
+        if (NextTrie_GetKind(next) == TrieKind) {
+            TrieLevelRef nextLevel = (TrieLevelRef) NextTrie_GetPtr(next);
+            code = addCFBurstTrieLevel(trie, nextLevel, key+1, keylen-1, weight, payload);
+        } else {
+            if (NextTrie_GetKind(next) == ListKind) {
+                uint32_t listCount;
+                ListNodeRef listNode = (ListNodeRef) NextTrie_GetPtr(next);
+                code = addCFBurstTrieListNode(trie, listNode, key+1, keylen-1, weight, payload, &listCount);
+                if (listCount > trie->containerSize) {
+                    next = (uintptr_t) burstCFBurstTrieLevel(trie, listNode, listCount);
+                    NextTrie_SetKind(next, TrieKind);
+                }
+            } else {
+                // ** Make a new list node
+                next = (uintptr_t) makeCFBurstTrieListNode(key+1, keylen-1, weight, payload);
+                NextTrie_SetKind(next, ListKind);
+                code = NewTerm;
+            }
+            root->slots[*key] = next;
+        }
+    } else {
+        // ** Handle payload
+        if (!root->weight) code = NewTerm;
+        else code = ExistingTerm;
+        root->weight += weight;
+        root->payload = payload;
+    }
+    
+    return code;
+}
+#if 0
+#pragma mark -
+#pragma mark Searching
+#endif
+static void findCFBurstTrieList(CFBurstTrieRef trie, TrieCursor *cursor, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool))
+{
+    ListNodeRef list = (ListNodeRef)NextTrie_GetPtr(cursor->next);
+    int len = cursor->prefixlen-cursor->keylen;
+    len = len <= 0 ? 0 : len;
+    while (list) {
+        int lencompare = list->length-len;
+        if (list->length >= len && 
+            (len == 0 || memcmp(list->string, cursor->prefix+cursor->keylen, len) == 0)) {
+            memcpy(cursor->key+cursor->keylen, list->string, list->length);
+            cursor->key[cursor->keylen+list->length] = 0;
+            cursor->next = (NextTrie)list;
+            if (list->payload && callback(ctx, cursor->key, list->payload, lencompare==0)) return;
+        }
+        list = list->next;
+    }
+}
+
+static void findCFBurstTrieMappedPage(CFBurstTrieRef trie, MapCursor *cursor, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool))
+{
+    Page *page = (Page *)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    uint32_t end = page->length;
+    uint32_t cur = 0;
+    int len = cursor->prefixlen-cursor->keylen;
+    len = len <= 0 ? 0 : len;
+    if (trie->cflags & kCFBurstTriePrefixCompression) {
+        uint8_t pfx[CHARACTER_SET_SIZE];
+        PageEntryPacked *lastEntry = 0;
+        while (cur < end) {
+            PageEntryPacked *entry = (PageEntryPacked *)&page->data[cur];
+            int lencompare = (entry->strlen+entry->pfxLen)-len;
+            if (lastEntry && entry->pfxLen>lastEntry->pfxLen) memcpy(pfx+lastEntry->pfxLen, lastEntry->string, entry->pfxLen-lastEntry->pfxLen);
+            if (lencompare >= 0 &&
+                (len == 0 || (__builtin_memcmp(pfx, cursor->prefix+cursor->keylen, entry->pfxLen) == 0 && 
+                              __builtin_memcmp(entry->string, cursor->prefix+cursor->keylen+entry->pfxLen, cursor->prefixlen-cursor->keylen-entry->pfxLen) == 0))) {
+                memcpy(cursor->key+cursor->keylen, pfx, entry->pfxLen);
+                memcpy(cursor->key+cursor->keylen+entry->pfxLen, entry->string, entry->strlen);
+                cursor->key[cursor->keylen+entry->pfxLen+entry->strlen] = 0;
+                if (entry->payload && callback(ctx, (const uint8_t *)cursor->key, entry->payload, lencompare==0)) return;
+            }
+            lastEntry = entry;
+            cur += sizeof(*entry) + entry->strlen;
+        }
+    } else {
+        while (cur < end) {
+            PageEntry *entry = (PageEntry *)&page->data[cur];
+            int lencompare = entry->strlen-len;
+            if (lencompare >= 0 && __builtin_memcmp(entry->string, cursor->prefix+cursor->keylen, len) == 0) {
+                memcpy(cursor->key+cursor->keylen, entry->string, entry->strlen);
+                cursor->key[cursor->keylen+entry->strlen] = 0;
+                if (entry->payload && callback(ctx, (const uint8_t *)cursor->key, entry->payload, lencompare==0)) return;
+            }
+            cur += sizeof(*entry) + entry->strlen;
+        }
+    }
+}
+
+
+static void findCFBurstTrieLevel(CFBurstTrieRef trie, TrieCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool))
+{
+    if (cursor->keylen < cursor->prefixlen) {
+        cursor->next = ((TrieLevelRef)NextTrie_GetPtr(cursor->next))->slots[cursor->prefix[cursor->keylen]];
+        cursor->key[cursor->keylen++] = cursor->prefix[cursor->keylen];
+        
+        if (NextTrie_GetKind(cursor->next) == TrieKind) {
+            findCFBurstTrieLevel(trie, cursor, exactmatch, ctx, callback);
+        } else if (NextTrie_GetKind(cursor->next) == ListKind) {
+            findCFBurstTrieList(trie, cursor, ctx, callback);
+        }
+    } else {
+        TrieLevelRef root = (TrieLevelRef)NextTrie_GetPtr(cursor->next);
+        if (root->payload && callback(ctx, cursor->key, root->payload, cursor->prefixlen==cursor->keylen)) return;
+        if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+        traverseCFBurstTrieLevel(trie, root, cursor, exactmatch, ctx, callback);
+    }
+}
+
+static void findCFBurstTrieCompactMappedLevel(CFBurstTrieRef trie, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool))
+{
+    CompactMapTrieLevelRef root = (CompactMapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (cursor->keylen < cursor->prefixlen) {
+        uint8_t mykey = *(cursor->prefix+cursor->keylen);
+        cursor->key[cursor->keylen++] = *(cursor->prefix+cursor->keylen);
+        
+        uint8_t slot = mykey / 64;
+        uint8_t bit = mykey % 64;
+        uint32_t item = 0;
+        uint64_t bword = root->bitmap[slot];
+        
+        if (bword & (1ull << bit)) {
+            // ** Count all the set bits up to this bit
+            for (int i=0; i < slot; i++) item += __builtin_popcountll(root->bitmap[i]);
+            item += __builtin_popcountll(bword & ((1ull << bit)-1));
+            uint32_t offset = root->slots[item]; 
+            cursor->next = offset;
+            
+            if (DiskNextTrie_GetKind(offset) == TrieKind) {
+                findCFBurstTrieMappedLevel(trie, cursor, exactmatch, ctx, callback);
+            } else if (DiskNextTrie_GetKind(offset) == CompactTrieKind) {
+                findCFBurstTrieCompactMappedLevel(trie, cursor, exactmatch, ctx, callback);
+            } else if (DiskNextTrie_GetKind(offset) == ListKind) {
+                findCFBurstTrieMappedPage(trie, cursor, ctx, callback);
+            }
+        }
+    } else {
+        if(root->payload && callback(ctx, cursor->key, root->payload, cursor->prefixlen==cursor->keylen)) return;
+        if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+        traverseCFBurstTrieCompactMappedLevel(trie, root, cursor,  exactmatch, ctx, callback);
+    }
+}
+
+static void findCFBurstTrieMappedLevel(CFBurstTrieRef trie, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void*, const uint8_t*, uint32_t, bool))
+{
+    MapTrieLevelRef root = (MapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (cursor->keylen < cursor->prefixlen) {
+        uint8_t slot = *(cursor->prefix+cursor->keylen);
+        cursor->next = root->slots[slot];
+        cursor->key[cursor->keylen++] = slot;
+        
+        if (DiskNextTrie_GetKind(cursor->next) == TrieKind) {
+            findCFBurstTrieMappedLevel(trie, cursor, exactmatch, ctx, callback);
+        } else if (DiskNextTrie_GetKind(cursor->next) == CompactTrieKind) {
+            findCFBurstTrieCompactMappedLevel(trie, cursor, exactmatch, ctx, callback);
+        } else if (DiskNextTrie_GetKind(cursor->next) == ListKind) {
+            findCFBurstTrieMappedPage(trie, cursor, ctx, callback);
+        }
+    }  else {
+        if (root->payload && callback(ctx, cursor->key, root->payload, cursor->prefixlen==cursor->keylen)) return;
+        if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+        traverseCFBurstTrieMappedLevel(trie, root, cursor, exactmatch, ctx, callback);
+    }
+}
+
+static void traverseCFBurstTrieLevel(CFBurstTrieRef trie, TrieLevelRef root, TrieCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool))
+{       
+    cursor->key[cursor->keylen] = 0;    
+    uint32_t len = cursor->keylen;
+    for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+        NextTrie next = root->slots[i];
+        cursor->keylen = len;
+        cursor->key[cursor->keylen++] = i;
+
+        if (NextTrie_GetKind(next) == TrieKind) {
+            TrieLevelRef level = (TrieLevelRef)NextTrie_GetPtr(next);
+            if (level->payload && callback(ctx, cursor->key, level->payload, cursor->prefixlen==cursor->keylen)) return;
+            if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+            traverseCFBurstTrieLevel(trie, level, cursor, exactmatch, ctx, callback);
+        } else if (NextTrie_GetKind(next) == ListKind) {
+            cursor->next = next;
+            cursor->key[cursor->keylen] = 0;
+            findCFBurstTrieList(trie, cursor, ctx, callback);
+        }
+    }
+}
+
+static void traverseCFBurstTrieMappedLevel(CFBurstTrieRef trie, MapTrieLevelRef root, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool))
+{
+    cursor->key[cursor->keylen] = 0;    
+    uint32_t len = cursor->keylen;
+    
+    for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+        uint32_t offset = (uint32_t)root->slots[i];
+        cursor->keylen = len;
+        cursor->key[cursor->keylen++] = i;
+        
+        if (DiskNextTrie_GetKind(offset) == TrieKind) {
+            MapTrieLevelRef level = (MapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, offset);
+            if (level->payload && callback(ctx, cursor->key, level->payload, cursor->prefixlen==cursor->keylen)) return;
+            if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+            traverseCFBurstTrieMappedLevel(trie, level, cursor, exactmatch, ctx, callback);
+        } else if (DiskNextTrie_GetKind(offset) == CompactTrieKind) {
+            CompactMapTrieLevelRef level = (CompactMapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, offset);
+            if (level->payload && callback(ctx, cursor->key, level->payload, cursor->prefixlen==cursor->keylen)) return;
+            if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+            traverseCFBurstTrieCompactMappedLevel(trie, level, cursor, exactmatch, ctx, callback);
+        } else if (DiskNextTrie_GetKind(offset) == ListKind) {
+            cursor->next = offset;
+            cursor->key[cursor->keylen] = 0;
+            findCFBurstTrieMappedPage(trie, cursor, ctx, callback);
+        }
+    }
+}
+
+static void traverseCFBurstTrieCompactMappedLevel(CFBurstTrieRef trie, CompactMapTrieLevelRef root, MapCursor *cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool))
+{
+    cursor->key[cursor->keylen] = 0;
+    uint32_t len = cursor->keylen;    
+    for (uint32_t c=0; c < CHARACTER_SET_SIZE; c++) {
+        //** This could be optimized to remember what the last slot/item was and not count bits over and over.
+        uint8_t mykey = c;
+        uint32_t slot = mykey / 64;
+        uint32_t bit = mykey % 64;
+        uint32_t item = 0;
+        uint64_t bword = root->bitmap[slot];
+        cursor->keylen = len;
+        
+        if (bword & (1ull << bit)) {
+            // ** Count all the set bits up to this bit
+            for (int i=0; i < slot; i++) item += __builtin_popcountll(root->bitmap[i]);
+            item += __builtin_popcountll(bword & ((1ull << bit)-1));
+            uint32_t offset = root->slots[item];
+            cursor->key[cursor->keylen++] = mykey;
+            
+            if(DiskNextTrie_GetKind(offset) == CompactTrieKind) {
+                CompactMapTrieLevelRef level = (CompactMapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, offset);
+                if (level->payload && callback(ctx, cursor->key, level->payload, cursor->prefixlen==cursor->keylen)) return;
+                if (cursor->keylen == cursor->prefixlen && exactmatch) return;
+                traverseCFBurstTrieCompactMappedLevel(trie, level, cursor, exactmatch, ctx, callback);
+            } else if(DiskNextTrie_GetKind(offset) == TrieKind) {
+                traverseCFBurstTrieMappedLevel(trie, (MapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, offset), cursor, exactmatch, ctx, callback);
+            } else if (DiskNextTrie_GetKind(offset) == ListKind) {
+                cursor->next = offset;
+                cursor->key[cursor->keylen] = 0;
+                findCFBurstTrieMappedPage(trie, cursor, ctx, callback);
+            }
+        }
+    }
+}
+
+static void traverseCFBurstTrieWithCursor(CFBurstTrieRef trie, const uint8_t *prefix, uint32_t prefixLen, void **cursor, bool exactmatch, void *ctx, bool (*callback)(void *, const uint8_t *, uint32_t, bool)) {
+    if (trie->mapBase) {
+        if (trie->cflags & kCFBurstTriePrefixCompression) {
+            fprintf(stderr, "Please use CFBurstTrieCursorRef API for file based trie.\n");
+            return;
+        } else {
+            TrieHeader *header = (TrieHeader *)trie->mapBase;
+            MapCursor csr;
+            csr.next = header->rootOffset;
+            csr.prefix = prefix;
+            csr.prefixlen = prefixLen;
+            csr.key[0] = 0;
+            csr.keylen = 0;
+            findCFBurstTrieMappedLevel(trie, &csr, exactmatch, ctx, callback);
+        }
+    } else {    
+        TrieCursor csr;
+        csr.next = ((unsigned long)&trie->root)|TrieKind;
+        csr.prefix = prefix;
+        csr.prefixlen = prefixLen;
+        csr.key[0] = 0;
+        csr.keylen = 0;
+        findCFBurstTrieLevel(trie, &csr, exactmatch, ctx, callback);
+    }
+}
+
+CF_INLINE uint32_t getPackedPageEntrySize(PageEntryPacked *entry)
+{
+    return sizeof(PageEntryPacked) + entry->strlen;
+}
+
+CF_INLINE uint32_t getPageEntrySize(PageEntry *entry)
+{
+    return sizeof(PageEntry) + entry->strlen;
+}
+
+/*
+static void _printPageEntry(PageEntryPacked *entry) {
+    printf("entry 0x%p:\n", entry);
+    printf("pfxLen = %d, strLen = %d\n", entry->pfxLen, entry->strlen);
+    if (entry->strlen > 0) {
+        printf("string = ");
+        for (int i = 0; i < entry->strlen; ++i)
+            printf("%d ", entry->string[i]);
+        printf("\n");
+    }
+    printf("\n");
+}
+*/
+static Boolean advanceCursorOnMappedPageForByte(Page *page, CompactMapCursor *cursor, UInt8 byte) {
+    PageEntryPacked *entry;
+    Boolean found = FALSE;
+    uint32_t minPrefixLength = 0;
+
+    if (cursor->isOnPage) {
+        entry = (PageEntryPacked *)&page->data[cursor->entryOffsetInPage];
+        //_printPageEntry(entry);
+        BOOL shouldContinue = TRUE;
+
+        if (!(cursor->entryOffsetInPage  == 0 && entry->strlen == 0)) {
+            if (cursor->entryOffsetInPage == entry->strlen - 1) {
+                minPrefixLength = entry->pfxLen + entry->strlen;
+                cursor->entryOffsetInPage += getPackedPageEntrySize(entry);
+            } else {
+                cursor->offsetInEntry++;
+                if (entry->string[cursor->offsetInEntry] == byte)
+                    found = TRUE;
+                else if (entry->string[cursor->offsetInEntry] > byte)
+                    shouldContinue = FALSE;
+                else {
+                    minPrefixLength = entry->pfxLen + cursor->offsetInEntry;
+                    cursor->entryOffsetInPage += getPackedPageEntrySize(entry);
+                }
+            }
+        }
+
+        if (found) {
+            cursor->isOnPage = TRUE;
+            return TRUE;
+        } else if (!shouldContinue)
+            return FALSE;
+    } else {
+        cursor->entryOffsetInPage = 0;
+    }
+
+    uint32_t pageSize = page->length - sizeof(Page);
+    while (cursor->entryOffsetInPage < pageSize) {
+        entry = (PageEntryPacked *)&page->data[cursor->entryOffsetInPage];
+        //_printPageEntry(entry);
+        if (minPrefixLength > entry->pfxLen)
+            break;
+        else if (minPrefixLength < entry->pfxLen)
+            cursor->entryOffsetInPage += getPackedPageEntrySize(entry);
+        else {
+            if (entry->strlen == 0)
+                cursor->entryOffsetInPage += getPackedPageEntrySize(entry);
+            else {
+                if (entry->string[0] > byte)
+                    // Entries are sorted alphabetically
+                    break;
+                else if (entry->string[0] < byte)
+                    cursor->entryOffsetInPage += getPackedPageEntrySize(entry);
+                else {
+                    cursor->offsetInEntry = 0;
+                    found = TRUE;
+                    break;
+                }
+            }
+        }
+    }
+
+    if (found)
+        cursor->isOnPage = TRUE;
+
+    return found;
+}
+
+static Boolean advanceCursorMappedPageWithPerfixCompression(Page *page, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    if (length == 0) {
+        PageEntryPacked *entry = (PageEntryPacked*)&page->data[0];
+        if (!cursor->isOnPage) {
+            cursor->entryOffsetInPage = 0;
+            cursor->offsetInEntry = 0;
+            cursor->isOnPage = entry->pfxLen == 0 && entry->strlen == 0;
+        }
+        getMapCursorPayloadFromPackedPageEntry(entry, cursor, &cursor->payload);
+        return TRUE;
+    }
+
+    for (CFIndex i = 0; i < length; ++i) {
+        if (!advanceCursorOnMappedPageForByte(page, cursor, bytes[i]))
+            return FALSE;
+    }
+    PageEntryPacked *entry = (PageEntryPacked*)&page->data[cursor->entryOffsetInPage];
+    getMapCursorPayloadFromPackedPageEntry(entry, cursor, &cursor->payload);
+    return TRUE;
+}
+
+static Boolean advanceCursorMappedPageSortedByKey(Page *page, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    if (length == 0) {
+        PageEntry*entry = (PageEntry*)&page->data[0];
+        if (!cursor->isOnPage) {
+            cursor->entryOffsetInPage = 0;
+            cursor->offsetInEntry = 0;
+            cursor->isOnPage = entry->strlen == 0;
+        }
+        getMapCursorPayloadFromPageEntry(entry, cursor, &cursor->payload);
+        return TRUE;
+    }
+
+    PageEntry *entry;
+    uint32_t pageSize = page->length - sizeof(Page);
+    const UInt8 * prefix = NULL;
+    uint32_t prefixLength = 0;
+
+    if (cursor->isOnPage) {
+        entry = (PageEntry*)&page->data[cursor->entryOffsetInPage];
+        prefix = entry->string;
+        prefixLength = cursor->offsetInEntry + 1;
+    }
+
+    while (cursor->entryOffsetInPage < pageSize) {
+        PageEntry *entry = (PageEntry*)&page->data[cursor->entryOffsetInPage];
+        if (entry->strlen == 0) {
+            cursor->entryOffsetInPage += getPageEntrySize(entry);
+            continue;
+        }
+
+        if (entry->strlen <= prefixLength)
+            return FALSE;
+        else {
+            int cmpResult = 0;
+            if (prefixLength > 0)
+                cmpResult = __builtin_memcmp(entry->string, prefix, prefixLength);
+            if (cmpResult > 0)
+                return FALSE;
+            else if (cmpResult == 0) {
+                if (entry->strlen < prefixLength + length) {
+                    int cmpResult2 = __builtin_memcmp(entry->string + prefixLength, bytes, entry->strlen - prefixLength);
+                    if (cmpResult2 > 0)
+                        return FALSE;
+                    else
+                        cursor->entryOffsetInPage += getPageEntrySize(entry);
+                } else {
+                    int cmpResult2 = __builtin_memcmp(entry->string + prefixLength, bytes, length);
+                    if (cmpResult2 > 0)
+                        return FALSE;
+                    else if (cmpResult2 == 0) {
+                        cursor->isOnPage = TRUE;
+                        cursor->offsetInEntry = prefixLength + length - 1;
+                        getMapCursorPayloadFromPageEntry(entry, cursor, &cursor->payload);
+                        return TRUE;
+                    } else
+                        cursor->entryOffsetInPage += getPageEntrySize(entry);
+                }
+            } else
+                cursor->entryOffsetInPage += getPageEntrySize(entry);
+        }
+    }
+    return FALSE;
+}
+
+static Boolean advanceCursorMappedPage(CFBurstTrieRef trie, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    if (!bytes || length < 0)
+        return FALSE;
+
+    Page *page = (Page *)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    uint32_t pageSize = page->length - sizeof(Page);
+    if (pageSize == 0)
+        return FALSE;
+
+    if (trie->cflags & kCFBurstTrieSortByKey)
+        return advanceCursorMappedPageSortedByKey(page, cursor, bytes, length);
+    else if (trie->cflags & kCFBurstTriePrefixCompression)
+        return advanceCursorMappedPageWithPerfixCompression(page, cursor, bytes, length);
+    else
+        return FALSE;
+}
+
+static Boolean advanceCursorCompactMappedLevel(CFBurstTrieRef trie, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    if (!bytes || length < 0)
+        return FALSE;
+
+    CompactMapTrieLevelRef root = (CompactMapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (length == 0) {
+        cursor->payload = root->payload;
+        return TRUE;
+    }
+
+    uint8_t slot = bytes[0] / 64;
+    uint8_t bit = bytes[0] % 64;
+    uint32_t item = 0;
+    uint64_t bword = root->bitmap[slot];
+    if (bword & (1ull << bit)) {
+        // Count all the set bits up to this bit
+        for (int i = 0; i < slot; ++i)
+            item += __builtin_popcountll(root->bitmap[i]);
+        item += __builtin_popcountll(bword & ((1ull << bit)-1));
+        cursor->next = root->slots[item];
+        return advanceMapCursor(trie, cursor, bytes + 1, length - 1);
+    } else {
+        return FALSE;
+    }
+}
+
+static Boolean advanceCursorMappedLevel(CFBurstTrieRef trie, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    if (!bytes || length < 0)
+        return FALSE;
+
+    MapTrieLevelRef root = (MapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (length == 0) {
+        cursor->payload = root->payload;
+        return TRUE;
+    }
+
+    cursor->next = root->slots[bytes[0]];
+    return advanceMapCursor(trie, cursor, bytes + 1, length - 1);
+}
+
+static Boolean advanceMapCursor(CFBurstTrieRef trie, CompactMapCursor *cursor, const UInt8* bytes, CFIndex length)
+{
+    bool result = FALSE;
+    switch (DiskNextTrie_GetKind(cursor->next)) {
+        case TrieKind:
+            result = advanceCursorMappedLevel(trie, cursor, bytes, length);
+            break;
+        case CompactTrieKind:
+            result = advanceCursorCompactMappedLevel(trie, cursor, bytes, length);
+            break;
+        case ListKind:
+            result = advanceCursorMappedPage(trie, cursor, bytes, length);
+            break;
+        case Nothing: {
+            TrieHeader *header = (TrieHeader*)trie->mapBase;
+            if (cursor->next == header->rootOffset)
+                result = advanceCursorMappedLevel(trie, cursor, bytes, length);
+        }
+    }
+
+    return result;
+}
+
+static void traverseFromMapCursorMappedLevel(CFBurstTrieRef trie, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    MapTrieLevelRef root = (MapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (root->payload) {
+        callback(ctx, bytes, length, root->payload, stop);
+        if (*stop)
+            return;
+    }
+
+    if (length >= capacity)
+        return;
+
+    for (int i = 0; i < CHARACTER_SET_SIZE; ++i) {i =
+        bytes[length] = i;
+        cursor->next = (uint32_t)root->slots[i];;
+        cursor->isOnPage = FALSE;
+        cursor->entryOffsetInPage = 0;
+        cursor->offsetInEntry = 0;
+        cursor->payload = 0;
+        traverseFromMapCursor(trie, cursor, bytes, capacity - 1, length + 1, stop, ctx, callback);
+        if (*stop)
+            return;
+    }
+}
+
+static void traverseFromMapCursorCompactMappedLevel(CFBurstTrieRef trie, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    CompactMapTrieLevelRef root = (CompactMapTrieLevelRef)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (root->payload) {
+        callback(ctx, bytes, length, root->payload, stop);
+        if (*stop)
+            return;
+    }
+
+    if (length >= capacity)
+        return;
+    for (int c = 0; c < CHARACTER_SET_SIZE; ++c) {
+        bytes[length] = c;
+        //This could be optimized to remember what the last slot/item was and not count bits over and over.
+        uint8_t slot = c / 64;
+        uint8_t bit = c % 64;
+        uint32_t item = 0;
+        uint64_t bword = root->bitmap[slot];
+        if (bword & (1ull << bit)) {
+            // Count all the set bits up to this bit
+            for (int i = 0; i < slot; ++i)
+                item += __builtin_popcountll(root->bitmap[i]);
+            item += __builtin_popcountll(bword & ((1ull << bit)-1));
+            cursor->next = root->slots[item];
+            cursor->isOnPage = FALSE;
+            cursor->entryOffsetInPage = 0;
+            cursor->offsetInEntry = 0;
+            cursor->payload = 0;
+            traverseFromMapCursor(trie, cursor, bytes, capacity - 1, length + 1, stop, ctx, callback);
+            if (*stop)
+                return;
+        }
+    }
+}
+
+static void traverseFromMapCursorMappedPageWithPrefixCompression(Page *page, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    uint32_t pageSize = page->length - sizeof(Page);
+    uint32_t offset = cursor->entryOffsetInPage;
+    uint32_t minPrefixLength = 0;
+    if (cursor->isOnPage) {
+        PageEntryPacked *entry = (PageEntryPacked*)&page->data[offset];
+        int32_t remainingLength = entry->strlen - cursor->offsetInEntry - 1;
+        if (remainingLength >= 0 && remainingLength <= capacity) {
+            memcpy(bytes + length, entry->string + cursor->offsetInEntry + 1, remainingLength);
+            callback(ctx, bytes, length + remainingLength, entry->payload, stop);
+            if (*stop)
+                return;
+        }
+        minPrefixLength = entry->pfxLen + cursor->offsetInEntry;
+        offset += getPackedPageEntrySize(entry);
+    }
+    PageEntryPacked *previousEntry = NULL;
+    while (offset < pageSize) {
+        PageEntryPacked *entry = (PageEntryPacked*)&page->data[offset];
+        if (minPrefixLength > entry->pfxLen)
+            break;
+        else if (entry->payload && entry->strlen <= capacity) {
+            if (previousEntry)
+                length -=   previousEntry->strlen + previousEntry->pfxLen - entry->pfxLen;
+            memcpy(bytes + length, entry->string, entry->strlen);
+            callback(ctx, bytes, length + entry->strlen, entry->payload, stop);
+            length += entry->strlen;
+            if (*stop)
+                return;
+        }
+        previousEntry = entry;
+        offset += getPackedPageEntrySize(entry);
+    }
+}
+
+static void traverseFromMapCursorMappedPageSortedByKey(Page *page, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    uint32_t pageSize = page->length - sizeof(Page);
+    uint32_t offset = cursor->entryOffsetInPage;
+    uint32_t prefixLength = 0;
+    const UInt8 *prefix = NULL;
+    if (cursor->isOnPage) {
+        PageEntry *entry = (PageEntry*)&page->data[offset];
+        int32_t remainingLength = entry->strlen - cursor->offsetInEntry - 1;
+        if (remainingLength >= 0 && remainingLength <= capacity) {
+            memcpy(bytes + length, entry->string + cursor->offsetInEntry, remainingLength);
+            callback(ctx, bytes, length + remainingLength, entry->payload, stop);
+            if (*stop)
+                return;
+        }
+        prefixLength = cursor->offsetInEntry + 1;
+        prefix = entry->string;
+        offset += getPageEntrySize(entry);
+    }
+
+    while (offset < pageSize) {
+        PageEntry *entry = (PageEntry*)&page->data[offset];
+        if (entry->strlen < prefixLength)
+            break;
+        else {
+            int cmpResult = __builtin_memcmp(entry->string, prefix, prefixLength);
+            if (cmpResult > 0)
+                break;
+            else if (entry->payload && entry->strlen <= capacity) {
+                if (entry->strlen > 0)
+                    memcpy(bytes + length, entry->string + prefixLength, entry->strlen - prefixLength);
+                callback(ctx, bytes, length + entry->strlen - prefixLength, entry->payload, stop);
+                if (*stop)
+                    return;
+            }
+            offset += getPageEntrySize(entry);
+        }
+    }
+}
+
+static void traverseFromMapCursorMappedPage(CFBurstTrieRef trie, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    Page *page = (Page *)DiskNextTrie_GetPtr(trie->mapBase, cursor->next);
+    if (trie->cflags & kCFBurstTrieSortByKey)
+        traverseFromMapCursorMappedPageSortedByKey(page, cursor, bytes, capacity, length, stop, ctx, callback);
+    else if (trie->cflags & kCFBurstTriePrefixCompression)
+        traverseFromMapCursorMappedPageWithPrefixCompression(page, cursor, bytes, capacity, length, stop, ctx, callback);
+}
+
+void traverseFromMapCursor(CFBurstTrieRef trie, CompactMapCursor *cursor, UInt8* bytes, uint32_t capacity, uint32_t length, Boolean *stop, void *ctx, CFBurstTrieTraversalCallback callback)
+{
+    switch (DiskNextTrie_GetKind(cursor->next)) {
+        case TrieKind:
+            traverseFromMapCursorMappedLevel(trie, cursor, bytes, capacity, length, stop, ctx, callback);
+            break;
+        case CompactTrieKind:
+            traverseFromMapCursorCompactMappedLevel(trie, cursor, bytes, capacity, length, stop, ctx, callback);
+            break;
+        case ListKind:
+            traverseFromMapCursorMappedPage(trie, cursor, bytes, capacity, length, stop, ctx, callback);
+            break;
+        case Nothing: {
+            TrieHeader *header = (TrieHeader*)trie->mapBase;
+            if (cursor->next == header->rootOffset) {
+                traverseFromMapCursorMappedLevel(trie, cursor, bytes, capacity, length, stop, ctx, callback);
+            }
+            break;
+        }
+    }
+}
+
+void copyMapCursor(const CompactMapCursor *source, CompactMapCursor* destination)
+{
+    destination->next = source->next;
+    destination->entryOffsetInPage = source->entryOffsetInPage;
+    destination->offsetInEntry = source->offsetInEntry;
+    destination->isOnPage = source->isOnPage;
+    destination->payload = source->payload;
+}
+
+Boolean areMapCursorsEqual(const CompactMapCursor *lhs, const CompactMapCursor *rhs)
+{
+    return lhs->entryOffsetInPage == rhs->entryOffsetInPage && lhs->isOnPage == rhs->isOnPage && lhs->next == rhs->next && lhs->offsetInEntry == rhs->offsetInEntry;
+}
+
+static Boolean getMapCursorPayloadFromPackedPageEntry(PageEntryPacked *entry, const CompactMapCursor *cursor, uint32_t *payload)
+{
+    if (payload)
+        *payload = 0;
+    if (cursor->entryOffsetInPage == 0 && cursor->offsetInEntry == 0 && entry->strlen == 0) {
+        if (payload)
+            *payload = entry->payload;
+        return TRUE;
+    } else if (cursor->offsetInEntry != entry->strlen - 1)
+        return FALSE;
+    else {
+        if (payload)
+            *payload = entry->payload;
+        return TRUE;
+    }
+}
+
+static Boolean getMapCursorPayloadFromPageEntry(PageEntry *entry, const CompactMapCursor *cursor, uint32_t *payload)
+{
+    if (payload)
+        *payload = 0;
+    if (cursor->entryOffsetInPage == 0 && cursor->offsetInEntry == 0 && entry->strlen == 0) {
+        if (payload)
+            *payload = entry->payload;
+        return TRUE;
+    } else if (cursor->offsetInEntry != entry->strlen - 1)
+        return FALSE;
+    else {
+        if (payload)
+            *payload = entry->payload;
+        return TRUE;
+    }
+}
+
+Boolean getMapCursorPayload(CFBurstTrieRef trie, const CompactMapCursor *cursor, uint32_t *payload)
+{
+    if (!cursor)
+        return FALSE;
+    if (cursor->payload) {
+        if (payload)
+            *payload  = cursor->payload;
+        return TRUE;
+    }
+    return FALSE;
+}
+
+// Legacy
+
+static Boolean burstTrieMappedFind(DiskTrieLevelRef trie, char *map, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix) {
+    Boolean success = false;
+    if (length) {
+        uint32_t offset = CFSwapInt32LittleToHost((uint32_t)trie->slots[*key]);
+        if(DiskNextTrie_GetKind(offset) == TrieKind) {
+            return burstTrieMappedFind((DiskTrieLevelRef)DiskNextTrie_GetPtr(map,offset), map, key+1, length-1, payload, prefix);
+        } else if(DiskNextTrie_GetKind(offset) == CompactTrieKind) {
+            return burstTrieCompactTrieMappedFind((CompactDiskTrieLevelRef)DiskNextTrie_GetPtr(map, offset), map, key+1, length-1, payload, prefix);
+        } else {
+            if(DiskNextTrie_GetKind(offset) == ListKind) {
+                return burstTrieMappedPageFind((StringPage *)DiskNextTrie_GetPtr(map, offset), key+1, length-1, payload, prefix);
+            } else {
+                return success;
+            }
+        }
+    } else {
+        if (trie->weight) {
+            SetPayload(payload, CFSwapInt32LittleToHost(trie->payload));
+            success = true;
+        }
+    }
+    return success;
+}
+
+static Boolean burstTrieCompactTrieMappedFind(CompactDiskTrieLevelRef trie, char *map, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix) {
+    Boolean success = false;
+    if (length) {
+        uint32_t mykey = *key;
+        uint32_t slot = mykey / 64;
+        uint32_t bit = mykey % 64;
+        uint32_t item = 0;
+        uint64_t bword = CFSwapInt64LittleToHost(trie->bitmap[slot]);
+        if (bword & (1ull << bit)) {
+            /* Count all the set bits up to this bit */
+            for (int i=0; i < slot; i++) {
+                item += __builtin_popcountll(trie->bitmap[i]);
+            }
+            item += __builtin_popcountll(bword & ((1ull << bit)-1));
+            uint32_t offset = CFSwapInt32LittleToHost((uint32_t)trie->slots[item]);
+            if(DiskNextTrie_GetKind(offset) == TrieKind) {
+                return burstTrieMappedFind((DiskTrieLevelRef)DiskNextTrie_GetPtr(map, offset), map, key+1, length-1, payload, prefix);
+            } else if(DiskNextTrie_GetKind(offset) == CompactTrieKind) {
+                return burstTrieCompactTrieMappedFind((CompactDiskTrieLevelRef)DiskNextTrie_GetPtr(map, offset), map, key+1, length-1, payload, prefix);
+            } 
+            else {
+                if(DiskNextTrie_GetKind(offset) == ListKind) {
+                    return burstTrieMappedPageFind((StringPage *)DiskNextTrie_GetPtr(map, offset), key+1, length-1, payload, prefix);
+                } else {
+                    return success;
+                }
+            }
+        }
+    } else {
+        if (trie->weight) {
+            SetPayload(payload, CFSwapInt32LittleToHost(trie->payload));
+            success = true;
+        }
+    }
+    return success;
+}
+
+static Boolean burstTrieMappedPageFind(StringPage *page, const UInt8 *key, uint32_t length, uint32_t *payload, bool prefix) {
+    Boolean success = false;
+    uint32_t end = CFSwapInt32LittleToHost(page->length);
+    uint32_t cur = 0;
+    if (prefix) {
+        uint8_t pfx[256];
+        while (cur < end) {
+            StringPageEntryPacked *entry = (StringPageEntryPacked *)&page->data[cur];
+            uint16_t strlen = entry->pfxLen+CFSwapInt16LittleToHost(entry->strlen);
+            if (strlen == length && __builtin_memcmp(pfx, key, entry->pfxLen) == 0 && __builtin_memcmp(entry->string, key+entry->pfxLen, length-entry->pfxLen) == 0) {
+                SetPayload(payload, CFSwapInt32LittleToHost(entry->payload));
+                success = true;
+                return success;
+            } else {
+                memcpy(pfx+entry->pfxLen, entry->string, MIN(255-entry->pfxLen, length-entry->pfxLen));
+                cur += sizeof(*entry) + strlen - entry->pfxLen;
+            }
+        }        
+    } else {
+        while (cur < end) {
+            StringPageEntry *entry = (StringPageEntry *)&page->data[cur];
+            uint16_t strlen = CFSwapInt16LittleToHost(entry->strlen);
+            if (strlen == length && __builtin_memcmp(entry->string, key, length) == 0) {
+                SetPayload(payload, CFSwapInt32LittleToHost(entry->payload));
+                success = true;
+                return success;
+            } else {
+                cur += sizeof(*entry) + strlen;
+            }
+        }        
+        
+    }
+    return success;
+}
+
+
+#if 0
+#pragma mark -
+#pragma mark Serialization
+#endif
+
+static bool serializeCFBurstTrieLevels(CFBurstTrieRef trie, TrieLevelRef root, uint32_t *offset, off_t start_offset, bool dispose, bool isroot, int fd)
+{
+    bool dense = true;
+    int count = 0;
+    
+    for (int i=0; i < CHARACTER_SET_SIZE; i++) if (root->slots[i]) count++;
+    
+    uint32_t this_offset = *offset;
+    
+    if ((trie->cflags & kCFBurstTrieBitmapCompression) && count < MAX_BITMAP_SIZE && !isroot) {
+        size_t size = sizeof(CompactMapTrieLevel) + sizeof(uint32_t) * count;
+        int offsetSlot = 0;
+        
+        CompactMapTrieLevel *maptrie = (CompactMapTrieLevel *)alloca(size);
+        bzero(maptrie, size);
+        *offset += size;
+        
+        for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+            NextTrie next = root->slots[i];
+            if (next) {
+                uint32_t slot = i / 64;
+                uint32_t bit = i % 64;
+                maptrie->bitmap[slot] |= 1ull<<bit;
+                if (NextTrie_GetKind(next) == TrieKind) {
+                    TrieLevelRef nextLevel = (TrieLevelRef)NextTrie_GetPtr(next);
+                    uint32_t childOffset = *offset;
+                    if (serializeCFBurstTrieLevels(trie, nextLevel, offset, start_offset, true, false, fd)) {
+                        maptrie->slots[offsetSlot] = (TrieKind|childOffset);
+                    } else {
+                        maptrie->slots[offsetSlot] = (CompactTrieKind|childOffset);
+                    }
+                } else {
+                    maptrie->slots[offsetSlot] = next;
+                }
+                offsetSlot++;
+            }
+        }
+        maptrie->payload = root->payload;
+        
+        int bitcount = 0;
+        for (int i=0; i < 4; i++) bitcount += __builtin_popcountll(maptrie->bitmap[i]);
+        assert(bitcount == count);
+        
+        pwrite(fd, maptrie, size, this_offset+start_offset);
+        dense = false;
+    } else {
+        MapTrieLevel maptrie;
+        *offset += sizeof(maptrie);
+        
+        for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+            NextTrie next = root->slots[i];
+            if (NextTrie_GetKind(next) == TrieKind) {
+                TrieLevelRef nextLevel = (TrieLevelRef)NextTrie_GetPtr(next);
+                uint32_t childOffset = *offset;
+                if (serializeCFBurstTrieLevels(trie, nextLevel, offset, start_offset, true, false, fd)) {
+                    maptrie.slots[i] = (TrieKind|childOffset);
+                } else {
+                    maptrie.slots[i] = (CompactTrieKind|childOffset);
+                }
+            } else {
+                maptrie.slots[i] = next;
+            }
+        }
+        maptrie.payload = root->payload;
+        pwrite(fd, &maptrie, sizeof(maptrie), this_offset+start_offset);
+    }
+    
+    if (dispose) free(root);
+    return dense;
+}
+
+static void serializeCFBurstTrieList(CFBurstTrieRef trie, ListNodeRef listNode, int fd)
+{
+    uint32_t listCount;
+    size_t size = trie->containerSize;
+    
+    // ** Temp list of nodes to sort
+    ListNodeRef *nodes = (ListNodeRef *)malloc(sizeof(ListNodeRef) * size);
+    for (listCount = 0; listNode; listCount++) {
+        if (listCount >= size) {
+            size *= 2;
+            nodes = (ListNodeRef *)realloc(nodes, sizeof(ListNodeRef) * size);
+        }
+        nodes[listCount] = listNode;
+        listNode = listNode->next;
+    }
+    
+    char _buffer[MAX_BUFFER_SIZE];
+    char bufferSize = (sizeof(Page) + size * (sizeof(PageEntryPacked) + MAX_STRING_SIZE));
+    char *buffer = bufferSize < MAX_BUFFER_SIZE ? _buffer : (char *) malloc(bufferSize);
+    
+    Page *page = (Page *)buffer;
+    uint32_t current = 0;
+    
+    if (trie->cflags & kCFBurstTriePrefixCompression) {
+        qsort(nodes, listCount, sizeof(ListNodeRef), nodeStringCompare);
+        
+        ListNodeRef last = 0;
+        for (int i=0; i < listCount; i++) {
+            listNode = nodes[i];
+            uint8_t pfxLen = 0;
+            if (last) {
+                for ( ; 
+                     pfxLen < CHARACTER_SET_SIZE-1 && 
+                     pfxLen < listNode->length && 
+                     pfxLen < last->length && 
+                     listNode->string[pfxLen] == last->string[pfxLen]; 
+                     pfxLen++);
+            }
+            
+            PageEntryPacked *entry = (PageEntryPacked *)(&page->data[current]);
+            entry->strlen = listNode->length - pfxLen;
+            entry->payload = listNode->payload;
+            entry->pfxLen = pfxLen;
+            memcpy(entry->string, listNode->string+pfxLen, listNode->length-pfxLen);
+            current += listNode->length - pfxLen + sizeof(PageEntryPacked);
+            last = listNode;
+        }
+    } else {
+        if (trie->cflags & kCFBurstTrieSortByKey)
+            qsort(nodes, listCount, sizeof(ListNodeRef), nodeStringCompare);
+        else
+            qsort(nodes, listCount, sizeof(ListNodeRef), nodeWeightCompare);
+        
+        for (int i=0; i < listCount; i++) {
+            listNode = nodes[i];
+            PageEntry *entry = (PageEntry *)(&page->data[current]);
+            entry->strlen = listNode->length;
+            entry->payload = listNode->payload;
+            memcpy(entry->string, listNode->string, listNode->length);
+            current += listNode->length + sizeof(PageEntry);
+        }
+    }
+    
+    size_t len = (sizeof(Page) + current + 3) & ~3;
+    page->length = current;
+    write(fd, page, len);
+    
+    free(nodes);
+    if (buffer != _buffer) free(buffer);
+}
+
+static void serializeCFBurstTrieLists(CFBurstTrieRef trie, TrieLevelRef root, off_t start_offset, int fd)
+{
+    for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+        NextTrie next = root->slots[i];
+        uint32_t offset;
+        if (NextTrie_GetKind(next) == TrieKind) {
+            TrieLevelRef nextLevel = (TrieLevelRef)NextTrie_GetPtr(next);
+            serializeCFBurstTrieLists(trie, nextLevel, start_offset, fd);
+        } else {
+            if (NextTrie_GetKind(next) == ListKind) {
+                ListNodeRef listNode = (ListNodeRef)NextTrie_GetPtr(next);
+                offset = lseek(fd, 0, SEEK_CUR) - start_offset;
+                serializeCFBurstTrieList(trie, listNode, fd);
+                finalizeCFBurstTrieList(listNode);
+                //assert((offset & 3)==0);
+                root->slots[i] = (offset|ListKind);
+            }
+        }
+    }
+}
+
+static size_t serializeCFBurstTrie(CFBurstTrieRef trie, size_t start_offset, int fd)
+{
+    TrieHeader header;
+    header.signature = 0x0ddba11;
+    header.rootOffset = 0;
+    header.count = trie->count;
+    header.size = 0;
+    header.flags = trie->cflags;
+    header.reserved[0] = 0;
+    
+    uint32_t offset;
+    lseek(fd, start_offset, SEEK_SET);
+    
+    size_t header_size = sizeof(header);
+    write(fd, &header, header_size);
+    
+    serializeCFBurstTrieLists(trie, &trie->root, start_offset, fd);
+    
+    offset = lseek(fd, 0, SEEK_CUR) - start_offset;
+    size_t off = offsetof(TrieHeader, rootOffset);
+    size_t offsize = sizeof(offset);
+    pwrite(fd, &offset, offsize, off+start_offset);
+    
+    serializeCFBurstTrieLevels(trie, &trie->root, &offset, start_offset, false, true, fd);
+    
+    size_t off2 = offsetof(TrieHeader, size);
+    offsize = sizeof(offset);
+    pwrite(fd, &offset, offsize, off2+start_offset);
+    
+    offset = lseek(fd, 0, SEEK_END);
+    return (size_t)(offset-start_offset);
+}
+
+#if 0
+#pragma mark -
+#pragma mark Release
+#endif
+
+static void destroyCFBurstTrie(CFBurstTrieRef trie) {
+    if (trie->mapBase) {
+#if DEPLOYMENT_TARGET_WINDOWS
+        UnmapViewOfFile(trie->mapBase);
+        CloseHandle(trie->mapHandle);
+        CloseHandle(trie->mappedFileHandle);
+#else
+        munmap(trie->mapBase, trie->mapSize);
+#endif
+    } else {
+        finalizeCFBurstTrie(&trie->root);
+    }
+    free(trie);
+    return;
+}
+
+static void finalizeCFBurstTrie(TrieLevelRef trie) {
+    for (int i=0; i < CHARACTER_SET_SIZE; i++) {
+        if (NextTrie_GetKind(trie->slots[i]) == TrieKind) {
+            finalizeCFBurstTrie((TrieLevelRef)NextTrie_GetPtr(trie->slots[i]));
+            free((void *)NextTrie_GetPtr(trie->slots[i]));
+        } else if (NextTrie_GetKind(trie->slots[i]) == ListKind) {
+            finalizeCFBurstTrieList((ListNodeRef)NextTrie_GetPtr(trie->slots[i]));
+        }
+    }
+}
+
+static void finalizeCFBurstTrieList(ListNodeRef node) {
+    do {
+        ListNodeRef next = node->next;
+        free(node);
+        node = next;
+    } while(node);
+}
+
+#if 0
+#pragma mark -
+#pragma mark Helpers
+#endif
+
+static int nodeWeightCompare(const void *a, const void *b) {
+    ListNodeRef nodeA = *(ListNodeRef *)a;
+    ListNodeRef nodeB = *(ListNodeRef *)b;
+    return (nodeB->weight - nodeA->weight);
+}
+
+static int nodeStringCompare(const void *a, const void *b) {
+    ListNodeRef nodeA = *(ListNodeRef *)a;
+    ListNodeRef nodeB = *(ListNodeRef *)b;
+    int result = memcmp((char *)nodeA->string, (char *)nodeB->string, MIN(nodeA->length, nodeB->length));
+    if (result == 0) result = nodeA->length-nodeB->length;
+    return result;
+}
+
+bool containsKey(void *context, const uint8_t *key, uint32_t payload, bool exact)
+{
+    uint32_t *ctx = (uint32_t *)context;
+    if (exact) *ctx = payload;
+    return exact;
+}
+
+static CFIndex burstTrieConvertCharactersToUTF8(UniChar *chars, CFIndex numChars, UInt8 *buffer) {
+    uint32_t i, j;
+    for (i = j = 0; i < numChars; i++) {
+        UniChar c = chars[i];
+        if (CFStringIsSurrogateHighCharacter(c) && i + 1 < numChars && CFStringIsSurrogateLowCharacter(chars[i + 1])) {
+            UTF32Char lc = CFStringGetLongCharacterForSurrogatePair(c, chars[i + 1]);
+            buffer[j++] = 0xf0 + (lc >> 18);
+            buffer[j++] = 0x80 + ((lc & 0x3ffff) >> 12);
+            buffer[j++] = 0x80 + ((lc & 0xfff) >> 6);
+            buffer[j++] = 0x80 + (lc & 0x3f);
+            i++;
+        } else {
+            if (c < 0x80) {
+                buffer[j++] = c;
+            } else if (c < 0x800) {
+                buffer[j++] = 0xc0 + (c >> 6);
+                buffer[j++] = 0x80 + (c & 0x3f);
+            } else {
+                buffer[j++] = 0xe0 + (c >> 12);
+                buffer[j++] = 0x80 + ((c & 0xfff) >> 6);
+                buffer[j++] = 0x80 + (c & 0x3f);
+            }
+        }
+    }
+    buffer[j] = 0;
+    return j;
+}
+
diff --git a/CFBurstTrie.h b/CFBurstTrie.h
new file mode 100644 (file)
index 0000000..e6c8830
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*     CFBurstTrie.h
+        Copyright (c) 2008-2012, Apple Inc. All rights reserved.
+*/
+
+#if !defined(__COREFOUNDATION_CFBURSTTRIE__)
+#define __COREFOUNDATION_CFBURSTTRIE__ 1
+
+#include <CoreFoundation/CFString.h>
+#include <CoreFoundation/CFDictionary.h>
+
+CF_EXTERN_C_BEGIN
+
+typedef struct _CFBurstTrie *CFBurstTrieRef;
+typedef struct _CFBurstTrieCursor *CFBurstTrieCursorRef;
+
+typedef CF_OPTIONS(CFOptionFlags, CFBurstTrieOpts) {
+        /*!
+         BurstTrie Options
+         Use one or more of these options with CFBurstTrieCreate to tailor optimizations to the data
+         structure for a specific kind of application. Default is no read-write, no compression.
+         */
+    
+    /*  kCFBurstTrieReadOnly
+        When specified, the dictionary file will be serialized in an optimized format so as to be
+        memory-mapped on the next read. Once a trie is serialized as read-only, insertions can no
+        longer occur.
+    */
+    kCFBurstTrieReadOnly            = 1<<1,
+    
+    /*  kCFBurstTrieBitmapCompression
+        This option can only be used with a read-only trie, and can be used to reduce on disk file size.
+    */
+    kCFBurstTrieBitmapCompression   = 1<<2,
+    
+    /*
+        kCFBurstTriePrefixCompression
+        This option can only be used with a read-only trie, and can be used to reduce on-disk file size.
+        It is important to note that any optimizations based on word frequency will be lost; recommended
+        for applications that often search for infrequent or uncommon words. This also allow you to use
+        cursor interface.
+    */
+    kCFBurstTriePrefixCompression   = 1<<3,
+
+    /*
+        kCFBurstTriePrefixCompression
+        By default, keys at list level are sorted by weight. Use this option to sort them by key value.
+        This allow you to use cursor interface.
+     */
+    kCFBurstTrieSortByKey = 1 << 4
+};
+
+// Value for this option should be a CFNumber which contains an int.
+#define kCFBurstTrieCreationOptionNameContainerSize CFSTR("ContainerSize")
+
+typedef void (*CFBurstTrieTraversalCallback)(void* context, const UInt8* key, uint32_t keyLength, uint32_t payload, Boolean *stop);
+
+CF_EXPORT 
+CFBurstTrieRef CFBurstTrieCreate() CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+CFBurstTrieRef CFBurstTrieCreateWithOptions(CFDictionaryRef options) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT 
+CFBurstTrieRef CFBurstTrieCreateFromFile(CFStringRef path) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+CFBurstTrieRef CFBurstTrieCreateFromMapBytes(char *mapBase) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieInsert(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieAdd(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieInsertCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieAddCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieInsertUTF8String(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieAddUTF8String(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT
+Boolean CFBurstTrieInsertWithWeight(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex weight, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+Boolean CFBurstTrieAddWithWeight(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t weight, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT
+Boolean CFBurstTrieInsertCharactersWithWeight(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex weight, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+Boolean CFBurstTrieAddCharactersWithWeight(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t weight, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT
+Boolean CFBurstTrieInsertUTF8StringWithWeight(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, CFIndex weight, CFIndex payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+Boolean CFBurstTrieAddUTF8StringWithWeight(CFBurstTrieRef trie, UInt8 *chars, CFIndex numChars, uint32_t weight, uint32_t payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieFind(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex *payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieContains(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, uint32_t *payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieFindCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, CFIndex *payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieContainsCharacters(CFBurstTrieRef trie, UniChar *chars, CFIndex numChars, uint32_t *payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieFindUTF8String(CFBurstTrieRef trie, UInt8 *key, CFIndex length, CFIndex *payload) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+Boolean CFBurstTrieContainsUTF8String(CFBurstTrieRef trie, UInt8 *key, CFIndex length, uint32_t *payload) CF_AVAILABLE(10_7, 5_0);
+
+
+CF_EXPORT 
+Boolean CFBurstTrieSerialize(CFBurstTrieRef trie, CFStringRef path, CFBurstTrieOpts opts) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+Boolean CFBurstTrieSerializeWithFileDescriptor(CFBurstTrieRef trie, int fd, CFBurstTrieOpts opts) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+void CFBurstTrieTraverse(CFBurstTrieRef trie, void *ctx, void (*callback)(void*, const UInt8*, uint32_t, uint32_t)) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+CFIndex CFBurstTrieGetCount(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+CFBurstTrieRef CFBurstTrieRetain(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT 
+void CFBurstTrieRelease(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2);
+
+CF_EXPORT
+CFBurstTrieCursorRef CFBurstTrieCreateCursorForBytes(CFBurstTrieRef trie, const UInt8* bytes, CFIndex length) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+CFBurstTrieCursorRef CFBurstTrieCursorCreateByCopy(CFBurstTrieCursorRef cursor) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+Boolean CFBurstTrieSetCursorForBytes(CFBurstTrieRef trie, CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+Boolean CFBurstTrieCursorIsEqual(CFBurstTrieCursorRef lhs, CFBurstTrieCursorRef rhs) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+Boolean CFBurstTrieCursorAdvanceForBytes(CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+Boolean CFBurstTrieCursorGetPayload(CFBurstTrieCursorRef cursor, uint32_t *payload) CF_AVAILABLE(10_8, 6_0);
+
+CF_EXPORT
+void CFBurstTrieTraverseFromCursor(CFBurstTrieCursorRef cursor, void *ctx, CFBurstTrieTraversalCallback callback) CF_AVAILABLE(10_8, 6_0);
+
+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 4c05f6aedbb805ff3fc71e28e1bab8ba68d6e667..d7d506ebbe83cf03cdc5922959bc978b8ba29529 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFByteOrder.h
-       Copyright (c) 1995-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1995-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFBYTEORDER__)
index a95c5150e55c4f0242955ac3c7e87a0f68bd9272..c3a19207cde66c391ecfc1db4a1474af10084734 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFCalendar.c
-       Copyright (c) 2004-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -176,19 +176,19 @@ CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringR
 }
 
 CFStringRef CFCalendarGetIdentifier(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFStringRef, calendar, "calendarIdentifier");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFStringRef, calendar, calendarIdentifier);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     return calendar->_identifier;
 }
 
 CFLocaleRef CFCalendarCopyLocale(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFLocaleRef, calendar, "_copyLocale");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFLocaleRef, calendar, _copyLocale);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     return (CFLocaleRef)CFLocaleCreate(kCFAllocatorSystemDefault, calendar->_localeID);
 }
 
 void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setLocale:", locale);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, setLocale:locale);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     __CFGenericValidateType(locale, CFLocaleGetTypeID());
     CFStringRef localeID = CFLocaleGetIdentifier(locale);
@@ -201,13 +201,13 @@ void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) {
 }
 
 CFTimeZoneRef CFCalendarCopyTimeZone(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFTimeZoneRef, calendar, "_copyTimeZone");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFTimeZoneRef, calendar_copyTimeZone);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     return (CFTimeZoneRef)CFRetain(calendar->_tz);
 }
 
 void CFCalendarSetTimeZone(CFCalendarRef calendar, CFTimeZoneRef tz) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setTimeZone:", tz);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, setTimeZone:tz);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (tz) __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     if (tz != calendar->_tz) {
@@ -218,7 +218,7 @@ void CFCalendarSetTimeZone(CFCalendarRef calendar, CFTimeZoneRef tz) {
 }
 
 CFIndex CFCalendarGetFirstWeekday(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFIndex, calendar, "firstWeekday");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFIndex, calendar, firstWeekday);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     if (calendar->_cal) {
@@ -228,7 +228,7 @@ CFIndex CFCalendarGetFirstWeekday(CFCalendarRef calendar) {
 }
 
 void CFCalendarSetFirstWeekday(CFCalendarRef calendar, CFIndex wkdy) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setFirstWeekday:", wkdy);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, setFirstWeekday:wkdy);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     if (calendar->_cal) {
@@ -237,21 +237,21 @@ void CFCalendarSetFirstWeekday(CFCalendarRef calendar, CFIndex wkdy) {
 }
 
 CFIndex CFCalendarGetMinimumDaysInFirstWeek(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFIndex, calendar, "minimumDaysInFirstWeek");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFIndex, calendar, minimumDaysInFirstWeek);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     return calendar->_cal ? ucal_getAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK) : -1;
 }
 
 void CFCalendarSetMinimumDaysInFirstWeek(CFCalendarRef calendar, CFIndex mwd) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "setMinimumDaysInFirstWeek:", mwd);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, setMinimumDaysInFirstWeek:mwd);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     if (calendar->_cal) ucal_setAttribute(calendar->_cal, UCAL_MINIMAL_DAYS_IN_FIRST_WEEK, mwd);
 }
 
 CFDateRef CFCalendarCopyGregorianStartDate(CFCalendarRef calendar) {
-    CF_OBJC_FUNCDISPATCH0(CFCalendarGetTypeID(), CFDateRef, calendar, "_gregorianStartDate");
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFDateRef, calendar, _gregorianStartDate);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     UErrorCode status = U_ZERO_ERROR;
@@ -264,7 +264,7 @@ CFDateRef CFCalendarCopyGregorianStartDate(CFCalendarRef calendar) {
 }
 
 void CFCalendarSetGregorianStartDate(CFCalendarRef calendar, CFDateRef date) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), void, calendar, "_setGregorianStartDate:", date);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), void, calendar, _setGregorianStartDate:date);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (date) __CFGenericValidateType(date, CFDateGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
@@ -348,7 +348,7 @@ static CFCalendarUnit __CFCalendarGetCalendarUnitFromChar(char ch) {
 }
 
 CFRange CFCalendarGetMinimumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), CFRange, calendar, "_minimumRangeOfUnit:", unit);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFRange, calendar, _minimumRangeOfUnit:unit);
     CFRange range = {kCFNotFound, kCFNotFound};
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
@@ -365,7 +365,7 @@ CFRange CFCalendarGetMinimumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit u
 }
 
 CFRange CFCalendarGetMaximumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit) {
-    CF_OBJC_FUNCDISPATCH1(CFCalendarGetTypeID(), CFRange, calendar, "_maximumRangeOfUnit:", unit);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFRange, calendar, _maximumRangeOfUnit:unit);
     CFRange range = {kCFNotFound, kCFNotFound};
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
@@ -505,7 +505,7 @@ static Boolean __validUnits(CFCalendarUnit smaller, CFCalendarUnit bigger) {
 static CFRange __CFCalendarGetRangeOfUnit1(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
     CFRange range = {kCFNotFound, kCFNotFound};
     if (!__validUnits(smallerUnit, biggerUnit)) return range;
-    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFRange, calendar, _rangeOfUnit:smallerUnit inUnit:biggerUnit forAT:at);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     if (calendar->_cal) {
@@ -604,7 +604,7 @@ static CFRange __CFCalendarGetRangeOfUnit1(CFCalendarRef calendar, CFCalendarUni
 
 static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) __attribute__((noinline));
 static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
-    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFRange, calendar, "_rangeOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFRange, calendar, _rangeOfUnit:smallerUnit inUnit:biggerUnit forAT:at);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     CFRange range = {kCFNotFound, kCFNotFound};
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
@@ -766,17 +766,13 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni
 }
 
 CFRange CFCalendarGetRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
-    if (_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard)) {
        return __CFCalendarGetRangeOfUnit2(calendar, smallerUnit, biggerUnit, at);
-    } else {
-       return __CFCalendarGetRangeOfUnit1(calendar, smallerUnit, biggerUnit, at);
-    }
 }
 
 CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) {
     CFIndex result = kCFNotFound;
     if (!__validUnits(smallerUnit, biggerUnit)) return result;
-    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), CFIndex, calendar, "_ordinalityOfUnit:inUnit:forAT:", smallerUnit, biggerUnit, at);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), CFIndex, calendar, _ordinalityOfUnit:smallerUnit inUnit:biggerUnit forAT:at);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (!calendar->_cal) __CFCalendarSetupCal(calendar);
     if (calendar->_cal) {
@@ -974,7 +970,7 @@ Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTim
 Boolean CFCalendarComposeAbsoluteTime(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, ...) {
     va_list args;
     va_start(args, componentDesc);
-    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), Boolean, calendar, "_composeAbsoluteTime:::", atp, componentDesc, args);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), Boolean, calendar, _composeAbsoluteTime:atp :componentDesc :args);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     int idx, cnt = strlen((char *)componentDesc);
     STACK_BUFFER_DECL(int, vector, cnt);
@@ -989,7 +985,7 @@ Boolean CFCalendarComposeAbsoluteTime(CFCalendarRef calendar, /* out */ CFAbsolu
 Boolean CFCalendarDecomposeAbsoluteTime(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, ...) {
     va_list args;
     va_start(args, componentDesc);
-    CF_OBJC_FUNCDISPATCH3(CFCalendarGetTypeID(), Boolean, calendar, "_decomposeAbsoluteTime:::", at, componentDesc, args);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), Boolean, calendar, _decomposeAbsoluteTime:at :componentDesc :args);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     int idx, cnt = strlen((char *)componentDesc);
     STACK_BUFFER_DECL(int *, vector, cnt);
@@ -1004,7 +1000,7 @@ Boolean CFCalendarDecomposeAbsoluteTime(CFCalendarRef calendar, CFAbsoluteTime a
 Boolean CFCalendarAddComponents(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, ...) {
     va_list args;
     va_start(args, componentDesc);
-    CF_OBJC_FUNCDISPATCH4(CFCalendarGetTypeID(), Boolean, calendar, "_addComponents::::", atp, options, componentDesc, args);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), Boolean, calendar, _addComponents:atp :options :componentDesc :args);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     int idx, cnt = strlen((char *)componentDesc);
     STACK_BUFFER_DECL(int, vector, cnt);
@@ -1019,7 +1015,7 @@ Boolean CFCalendarAddComponents(CFCalendarRef calendar, /* inout */ CFAbsoluteTi
 Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, ...) {
     va_list args;
     va_start(args, componentDesc);
-    CF_OBJC_FUNCDISPATCH5(CFCalendarGetTypeID(), Boolean, calendar, "_diffComponents:::::", startingAT, resultAT, options, componentDesc, args);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), Boolean, calendar, _diffComponents:startingAT :resultAT :options :componentDesc :args);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     int idx, cnt = strlen((char *)componentDesc);
     STACK_BUFFER_DECL(int *, vector, cnt);
@@ -1033,7 +1029,7 @@ Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime
 }
 
 Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at, CFAbsoluteTime *startp, CFTimeInterval *tip) {
-    CF_OBJC_FUNCDISPATCH4(CFCalendarGetTypeID(), Boolean, calendar, "_rangeOfUnit:startTime:interval:forAT:", unit, startp, tip, at);
+    CF_OBJC_FUNCDISPATCHV(CFCalendarGetTypeID(), Boolean, calendar, _rangeOfUnit:unit startTime:startp interval:tip forAT:at);
     __CFGenericValidateType(calendar, CFCalendarGetTypeID());
     if (kCFCalendarUnitWeekdayOrdinal == unit) return false;
     if (kCFCalendarUnitWeekday == unit) unit = kCFCalendarUnitDay;
index 175143485accb1635e627dae950156d1a40a45e4..8cee56590af6c1916cc91b4e8c46ae472e3c63f6 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFCalendar.h
-       Copyright (c) 2004-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFCALENDAR__)
@@ -33,6 +33,7 @@
 #include <CoreFoundation/CFDate.h>
 #include <CoreFoundation/CFTimeZone.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef struct __CFCalendar * CFCalendarRef;
@@ -77,7 +78,7 @@ CF_EXPORT
 void CFCalendarSetMinimumDaysInFirstWeek(CFCalendarRef calendar, CFIndex mwd);
 
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFCalendarUnit) {
        kCFCalendarUnitEra = (1UL << 1),
        kCFCalendarUnitYear = (1UL << 2),
        kCFCalendarUnitMonth = (1UL << 3),
@@ -88,16 +89,11 @@ enum {
        kCFCalendarUnitWeek = (1UL << 8) /* CF_DEPRECATED(10_4, 10_7, 2_0, 5_0) */,
        kCFCalendarUnitWeekday = (1UL << 9),
        kCFCalendarUnitWeekdayOrdinal = (1UL << 10),
-#if MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_4_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
-       kCFCalendarUnitQuarter = (1UL << 11),
-#endif
-#if MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_5_0 <= __IPHONE_OS_VERSION_MAX_ALLOWED
-       kCFCalendarUnitWeekOfMonth = (1UL << 12),
-       kCFCalendarUnitWeekOfYear = (1UL << 13),
-       kCFCalendarUnitYearForWeekOfYear = (1UL << 14),
-#endif
+       kCFCalendarUnitQuarter CF_ENUM_AVAILABLE(10_6, 4_0) = (1UL << 11),
+       kCFCalendarUnitWeekOfMonth CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 12),
+       kCFCalendarUnitWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 13),
+       kCFCalendarUnitYearForWeekOfYear CF_ENUM_AVAILABLE(10_7, 5_0) = (1UL << 14),
 };
-typedef CFOptionFlags CFCalendarUnit;
 
 CF_EXPORT
 CFRange CFCalendarGetMinimumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit);
@@ -133,6 +129,7 @@ Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime
 
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFCALENDAR__ */
 
index 5e45395be7d227dafea4c6265dc70c07e4f00d99..771ee4d6a42b7db61910339ae1bb9a30b6eb3488 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSet.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -1484,7 +1484,7 @@ CFCharacterSetRef CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef al
 CFCharacterSetRef CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc, CFCharacterSetRef theSet) {
     CFMutableCharacterSetRef cset;
     
-    CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFCharacterSetRef , theSet, "invertedSet");
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, CFCharacterSetRef , (NSCharacterSet *)theSet, invertedSet);
 
     cset = CFCharacterSetCreateMutableCopy(alloc, theSet);
     CFCharacterSetInvert(cset);
@@ -1508,7 +1508,7 @@ CFMutableCharacterSetRef CFCharacterSetCreateMutable(CFAllocatorRef allocator) {
 static CFMutableCharacterSetRef __CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet, bool isMutable) {
     CFMutableCharacterSetRef cset;
 
-    CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFMutableCharacterSetRef , theSet, "mutableCopy");
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, CFMutableCharacterSetRef , (NSCharacterSet *)theSet, mutableCopy);
 
     __CFGenericValidateType(theSet, __kCFCharacterSetTypeID);
 
@@ -1606,7 +1606,7 @@ Boolean CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet, UniChar theCha
     Boolean isInverted;
     Boolean result = false;
     
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, Boolean, theSet, "longCharacterIsMember:", theChar);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (NSCharacterSet *)theSet, longCharacterIsMember:(UTF32Char)theChar);
     
     __CFGenericValidateType(theSet, __kCFCharacterSetTypeID);
     
@@ -1649,7 +1649,7 @@ Boolean CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, UTF32Char
     Boolean isInverted;
     Boolean result = false;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, Boolean, theSet, "longCharacterIsMember:", theChar);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (NSCharacterSet *)theSet, longCharacterIsMember:(UTF32Char)theChar);
 
     __CFGenericValidateType(theSet, __kCFCharacterSetTypeID);
 
@@ -1715,7 +1715,7 @@ Boolean CFCharacterSetIsSurrogatePairMember(CFCharacterSetRef theSet, UniChar su
 
 
 static inline CFCharacterSetRef __CFCharacterSetGetExpandedSetForNSCharacterSet(const void *characterSet) {
-    CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFCharacterSetRef , characterSet, "_expandedCFCharacterSet");
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, CFCharacterSetRef , (NSCharacterSet *)characterSet, _expandedCFCharacterSet);
     return NULL;
 }
 
@@ -1818,7 +1818,7 @@ Boolean CFCharacterSetIsSupersetOfSet(CFCharacterSetRef theSet, CFCharacterSetRe
 Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlane) {
     Boolean isInverted = __CFCSetIsInverted(theSet);
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, Boolean, theSet, "hasMemberInPlane:", thePlane);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (NSCharacterSet *)theSet, hasMemberInPlane:(uint8_t)thePlane);
 
     if (__CFCSetIsEmpty(theSet)) {
         return (isInverted ? TRUE : FALSE);
@@ -1903,7 +1903,7 @@ CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFChara
     int length;
     bool isAnnexInverted;
 
-    CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, CFDataRef , theSet, "_retainedBitmapRepresentation");
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, CFDataRef , (NSCharacterSet *)theSet, _retainedBitmapRepresentation);
 
     __CFGenericValidateType(theSet, __kCFCharacterSetTypeID);
 
@@ -2059,7 +2059,7 @@ CFDataRef CFCharacterSetCreateBitmapRepresentation(CFAllocatorRef alloc, CFChara
 
 /*** MutableCharacterSet functions ***/
 void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange) {
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "addCharactersInRange:", theRange);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, addCharactersInRange:NSMakeRange(theRange.location, theRange.length));
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
     __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__);
@@ -2078,7 +2078,7 @@ void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange
             CFIndex length = __CFCSetRangeLength(theSet);
 
             if (firstChar == theRange.location) {
-                __CFCSetPutRangeLength(theSet, __CFMin(length, theRange.length));
+                __CFCSetPutRangeLength(theSet, __CFMax(length, theRange.length));
                 __CFCSetPutHasHashValue(theSet, false);
                 return;
             } else if (firstChar < theRange.location && theRange.location <= firstChar + length) {
@@ -2117,7 +2117,7 @@ void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange
 }
 
 void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet, CFRange theRange) {
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "removeCharactersInRange:", theRange);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, removeCharactersInRange:NSMakeRange(theRange.location, theRange.length));
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
     __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__);
@@ -2184,7 +2184,7 @@ void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet,  CFStr
     CFIndex length;
     BOOL hasSurrogate = NO;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "addCharactersInString:", theString);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, addCharactersInString:(NSString *)theString);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
 
@@ -2268,7 +2268,7 @@ void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFS
     CFIndex length;
     BOOL hasSurrogate = NO;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "removeCharactersInString:", theString);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, removeCharactersInString:(NSString *)theString);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
 
@@ -2344,7 +2344,7 @@ void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFS
 void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet) {
     CFCharacterSetRef expandedSet = NULL;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "formUnionWithCharacterSet:", theOtherSet);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, formUnionWithCharacterSet:(NSCharacterSet *)theOtherSet);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
 
@@ -2467,7 +2467,7 @@ void CFCharacterSetUnion(CFMutableCharacterSetRef theSet, CFCharacterSetRef theO
 void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef theOtherSet) {
     CFCharacterSetRef expandedSet = NULL;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFCharacterSetTypeID, void, theSet, "formIntersectionWithCharacterSet:", theOtherSet);
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, formIntersectionWithCharacterSet:(NSCharacterSet *)theOtherSet);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
 
@@ -2648,7 +2648,7 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef
 
 void CFCharacterSetInvert(CFMutableCharacterSetRef theSet) {
 
-    CF_OBJC_FUNCDISPATCH0(__kCFCharacterSetTypeID, void, theSet, "invert");
+    CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, void, (NSMutableCharacterSet *)theSet, invert);
 
     __CFCSetValidateTypeAndMutability(theSet, __PRETTY_FUNCTION__);
 
index 769db151c9a9068af9de5426259a9ca7541369ac..f499893c4fdd51de5ade1ae7d2af4447cb94277a 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSet.h
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
 */
 
 /*!
@@ -57,6 +57,7 @@
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFData.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -76,7 +77,7 @@ typedef struct __CFCharacterSet * CFMutableCharacterSetRef;
         Type of the predefined CFCharacterSet selector values.
 */
    
-enum {
+typedef CF_ENUM(CFIndex, CFCharacterSetPredefinedSet) {
     kCFCharacterSetControl = 1, /* Control character set (Unicode General Category Cc and Cf) */
     kCFCharacterSetWhitespace, /* Whitespace character set (Unicode General Category Zs and U0009 CHARACTER TABULATION) */
     kCFCharacterSetWhitespaceAndNewline,  /* Whitespace and Newline character set (Unicode General Category Z*, U000A ~ U000D, and U0085) */
@@ -90,12 +91,9 @@ enum {
     kCFCharacterSetPunctuation, /* Punctuation character set (Unicode General Category P*) */
     kCFCharacterSetCapitalizedLetter = 13, /* Titlecase character set (Unicode General Category Lt) */
     kCFCharacterSetSymbol = 14, /* Symbol character set (Unicode General Category S*) */
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    kCFCharacterSetNewline = 15, /* Newline character set (U000A ~ U000D, U0085, U2028, and U2029) */
-#endif
+    kCFCharacterSetNewline CF_ENUM_AVAILABLE(10_5, 2_0) = 15, /* Newline character set (U000A ~ U000D, U0085, U2028, and U2029) */
     kCFCharacterSetIllegal = 12/* Illegal character set */
 };
-typedef CFIndex CFCharacterSetPredefinedSet;
 
 /*!
        @function CFCharacterSetGetTypeID
@@ -401,6 +399,7 @@ CF_EXPORT
 void CFCharacterSetInvert(CFMutableCharacterSetRef theSet);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFCHARACTERSET__ */
 
index cd0af97b1f1f211aecbc1f7fde28ec011ef8611f..a80d388ad54d384ea2316beafe696864e06d7221 100644 (file)
Binary files a/CFCharacterSetBitmaps.bitmap and b/CFCharacterSetBitmaps.bitmap differ
index ee8fafb8423ba44095bebb08fdc675448370fe91..a9e9572a6404a9aee3d70c5d86d69253faec0e1f 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFCharacterSetPriv.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFCHARACTERSETPRIV__)
@@ -62,7 +62,7 @@ CF_INLINE Boolean CFCharacterSetIsSurrogateLowCharacter(UniChar character) {
        @result The UTF-32 value for the surrogate pair.
 */
 CF_INLINE UTF32Char CFCharacterSetGetLongCharacterForSurrogatePair(UniChar surrogateHigh, UniChar surrogateLow) {
-    return ((surrogateHigh - 0xD800UL) << 10) + (surrogateLow - 0xDC00UL) + 0x0010000UL;
+    return (UTF32Char)(((surrogateHigh - 0xD800UL) << 10) + (surrogateLow - 0xDC00UL) + 0x0010000UL);
 }
 
 /* Check to see if the character represented by the surrogate pair surrogateHigh & surrogateLow is in the chraracter set */
@@ -70,14 +70,13 @@ CF_EXPORT Boolean CFCharacterSetIsSurrogatePairMember(CFCharacterSetRef theSet,
 
 /* Keyed-coding support
 */
-enum {
+typedef CF_ENUM(CFIndex, CFCharacterSetKeyedCodingType) {
     kCFCharacterSetKeyedCodingTypeBitmap = 1,
     kCFCharacterSetKeyedCodingTypeBuiltin = 2,
     kCFCharacterSetKeyedCodingTypeRange = 3,
     kCFCharacterSetKeyedCodingTypeString = 4,
     kCFCharacterSetKeyedCodingTypeBuiltinAndBitmap = 5
 };
-typedef CFIndex CFCharacterSetKeyedCodingType;
 
 CF_EXPORT CFCharacterSetKeyedCodingType _CFCharacterSetGetKeyedCodingType(CFCharacterSetRef cset);
 CF_EXPORT CFCharacterSetPredefinedSet _CFCharacterSetGetKeyedCodingBuiltinType(CFCharacterSetRef cset);
index 5565774bd2a2e01953093144abfdd6068689f92c..c2f9c715b9aaaa9efe7898164a5dee50b56b6618 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFConcreteStreams.c
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
 #include <string.h>
 #include <stdio.h>
 #include <sys/stat.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <sys/time.h>
 #include <unistd.h>
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
 
@@ -70,7 +67,9 @@ typedef struct {
 
 
 CONST_STRING_DECL(kCFStreamPropertyFileCurrentOffset, "kCFStreamPropertyFileCurrentOffset");
-
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+CONST_STRING_DECL(_kCFStreamPropertyFileNativeHandle, "_kCFStreamPropertyFileNativeHandle");
+#endif
 
 #ifdef REAL_FILE_SCHEDULING
 extern void _CFFileDescriptorInduceFakeReadCallBack(CFFileDescriptorRef);
@@ -101,11 +100,9 @@ static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *erro
     wchar_t path[CFMaxPathSize];
     flags |= (_O_BINARY|_O_NOINHERIT);
     if (_CFURLGetWideFileSystemRepresentation(fileStream->url, TRUE, path, CFMaxPathSize) == FALSE)
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     char path[CFMaxPathSize];
     if (CFURLGetFileSystemRepresentation(fileStream->url, TRUE, (UInt8 *)path, CFMaxPathSize) == FALSE)
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
      {
         error->error = ENOENT;
@@ -118,7 +115,7 @@ static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *erro
     }
     
     do {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         fileStream->fd = open((const char *)path, flags, 0666);
 #elif DEPLOYMENT_TARGET_WINDOWS
        fileStream->fd = _wopen(path, flags, 0666);
@@ -438,7 +435,14 @@ static CFTypeRef fileCopyProperty(struct _CFStream *stream, CFStringRef property
         if (fileStream->offset != -1) {
             result = CFNumberCreate(CFGetAllocator((CFTypeRef)stream), kCFNumberSInt64Type, &(fileStream->offset));
         }
-    }
+#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+    } else if (CFEqual(propertyName, _kCFStreamPropertyFileNativeHandle)) {
+               int fd = fileStream->fd;
+               if (fd != -1) {
+                       result = CFDataCreate(CFGetAllocator((CFTypeRef) stream), (const uint8_t *)&fd, sizeof(fd));
+               }
+#endif
+       }
 
     return result;
 }
index c1775c5647a0c99e9ee7731b065787f9880e6ec8..b6528f57a88ab71ab83994288e78cfc5c11c8ee1 100644 (file)
--- a/CFData.c
+++ b/CFData.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFData.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Kevin Perry
 */
 
 #include <CoreFoundation/CFPriv.h>
 #include "CFInternal.h"
 #include <string.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#include <mach/mach_init.h>
-#elif DEPLOYMENT_TARGET_WINDOWS
-#include <windows.h> // For GetSystemInfo()
-#endif
+
+
 
 #if __LP64__
 #define CFDATA_MAX_SIZE            ((1ULL << 42) - 1)
@@ -42,7 +39,8 @@
 #define CFDATA_MAX_SIZE            ((1ULL << 31) - 1)
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#import <mach/mach.h>
 CF_INLINE unsigned long __CFPageSize() { return vm_page_size; }
 #elif DEPLOYMENT_TARGET_WINDOWS
 CF_INLINE unsigned long __CFPageSize() {
@@ -176,14 +174,14 @@ CF_INLINE CFIndex __CFDataRoundUpCapacity(CFIndex capacity) {
        return 16;
     } else if (capacity < LOW_THRESHOLD) {
        /* Up to 4x */
-       int idx = flsl(capacity);
-       return (1 << (idx + ((idx % 2 == 0) ? 0 : 1)));
+       long idx = flsl(capacity);
+       return (1L << (long)(idx + ((idx % 2 == 0) ? 0 : 1)));
     } else if (capacity < HIGH_THRESHOLD) {
        /* Up to 2x */
-       return (1 << flsl(capacity));
+       return (1L << (long)flsl(capacity));
     } else {
        /* Round up to next multiple of CHUNK_SIZE */
-       unsigned long newCapacity = CHUNK_SIZE * (1+(capacity >> (flsl(CHUNK_SIZE)-1)));
+       unsigned long newCapacity = CHUNK_SIZE * (1+(capacity >> ((long)flsl(CHUNK_SIZE)-1)));
        return __CFMin(newCapacity, CFDATA_MAX_SIZE);
     }
 }
@@ -491,27 +489,27 @@ CFMutableDataRef CFDataCreateMutableCopy(CFAllocatorRef allocator, CFIndex capac
 }
 
 CFIndex CFDataGetLength(CFDataRef data) {
-    CF_OBJC_FUNCDISPATCH0(__kCFDataTypeID, CFIndex, data, "length");
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, CFIndex, (NSData *)data, length);
     __CFGenericValidateType(data, __kCFDataTypeID);
     return __CFDataLength(data);
 }
 
 const uint8_t *CFDataGetBytePtr(CFDataRef data) {
-    CF_OBJC_FUNCDISPATCH0(__kCFDataTypeID, const uint8_t *, data, "bytes");
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, const uint8_t *, (NSData *)data, bytes);
     __CFGenericValidateType(data, __kCFDataTypeID);
     // compaction: if inline, always do the computation.
     return __CFDataBytesInline(data) ? (uint8_t *)__CFDataInlineBytesPtr(data) : data->_bytes;
 }
 
 uint8_t *CFDataGetMutableBytePtr(CFMutableDataRef data) {
-    CF_OBJC_FUNCDISPATCH0(__kCFDataTypeID, uint8_t *, data, "mutableBytes");
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, uint8_t *, (NSMutableData *)data, mutableBytes);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
     // compaction: if inline, always do the computation.
     return __CFDataBytesInline(data) ? (uint8_t *)__CFDataInlineBytesPtr(data) : data->_bytes;
 }
 
 void CFDataGetBytes(CFDataRef data, CFRange range, uint8_t *buffer) {
-    CF_OBJC_FUNCDISPATCH2(__kCFDataTypeID, void, data, "getBytes:range:", buffer, range);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSData *)data, getBytes:(void *)buffer range:NSMakeRange(range.location, range.length));
     __CFDataValidateRange(data, range, __PRETTY_FUNCTION__);
     memmove(buffer, CFDataGetBytePtr(data) + range.location, range.length);
 }
@@ -556,7 +554,7 @@ static void __CFDataGrow(CFMutableDataRef data, CFIndex numNewValues, Boolean cl
 void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) {
     CFIndex oldLength, capacity;
     Boolean isGrowable;
-    CF_OBJC_FUNCDISPATCH1(__kCFDataTypeID, void, data, "setLength:", newLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, setLength:(NSUInteger)newLength);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
     oldLength = __CFDataLength(data);
     capacity = __CFDataCapacity(data);
@@ -585,26 +583,26 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) {
 }
 
 void CFDataIncreaseLength(CFMutableDataRef data, CFIndex extraLength) {
-    CF_OBJC_FUNCDISPATCH1(__kCFDataTypeID, void, data, "increaseLengthBy:", extraLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, increaseLengthBy:(NSUInteger)extraLength);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
     if (extraLength < 0) HALT; // Avoid integer overflow.
     CFDataSetLength(data, __CFDataLength(data) + extraLength);
 }
 
 void CFDataAppendBytes(CFMutableDataRef data, const uint8_t *bytes, CFIndex length) {
-    CF_OBJC_FUNCDISPATCH2(__kCFDataTypeID, void, data, "appendBytes:length:", bytes, length);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, appendBytes:(const void *)bytes length:(NSUInteger)length);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
     CFDataReplaceBytes(data, CFRangeMake(__CFDataLength(data), 0), bytes, length); 
 }
 
 void CFDataDeleteBytes(CFMutableDataRef data, CFRange range) {
-    CF_OBJC_FUNCDISPATCH3(__kCFDataTypeID, void, data, "replaceBytesInRange:withBytes:length:", range, NULL, 0);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:NULL length:0);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
     CFDataReplaceBytes(data, range, NULL, 0); 
 }
 
 void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *newBytes, CFIndex newLength) {
-    CF_OBJC_FUNCDISPATCH3(__kCFDataTypeID, void, data, "replaceBytesInRange:withBytes:length:", range, newBytes, newLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFDataTypeID, void, (NSMutableData *)data, replaceBytesInRange:NSMakeRange(range.location, range.length) withBytes:(const void *)newBytes length:(NSUInteger)newLength);
     __CFGenericValidateType(data, __kCFDataTypeID);
     __CFDataValidateRange(data, range, __PRETTY_FUNCTION__);
     CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__);
index 2283a6d723c877857ed59a50ab3e70e004e87a2e..8647e6ea97ef9f056dd23a2f836efb8dcbcb77fe 100644 (file)
--- a/CFData.h
+++ b/CFData.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFData.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATA__)
@@ -30,6 +30,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
     
 typedef const struct __CFData * CFDataRef;
@@ -81,18 +82,16 @@ void CFDataReplaceBytes(CFMutableDataRef theData, CFRange range, const UInt8 *ne
 CF_EXPORT
 void CFDataDeleteBytes(CFMutableDataRef theData, CFRange range);
 
-#if MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_4_0 <=  __IPHONE_OS_VERSION_MAX_ALLOWED
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFDataSearchFlags) {
     kCFDataSearchBackwards = 1UL << 0,
     kCFDataSearchAnchored = 1UL << 1
-};
-#endif
-typedef CFOptionFlags CFDataSearchFlags;
+} CF_ENUM_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 CFRange CFDataFind(CFDataRef theData, CFDataRef dataToFind, CFRange searchRange, CFDataSearchFlags compareOptions) CF_AVAILABLE(10_6, 4_0);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFDATA__ */
 
index 01e6e86d37ae59f7947261952f051f17ff615f3f..766ebdac9ba746aafca362de7e5df205d7cdb951 100644 (file)
--- a/CFDate.c
+++ b/CFDate.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFDate.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
 #include <CoreFoundation/CFNumber.h>
 #include "CFInternal.h"
 #include <math.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <sys/time.h>
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
+#define DEFINE_CFDATE_FUNCTIONS 1
 
 /* cjk: The Julian Date for the reference date is 2451910.5,
         I think, in case that's ever useful. */
 
-#define DEFINE_CFDATE_FUNCTIONS 1
-
 #if DEFINE_CFDATE_FUNCTIONS
 
 const CFTimeInterval kCFAbsoluteTimeIntervalSince1970 = 978307200.0L;
@@ -66,23 +62,15 @@ __private_extern__ CFTimeInterval __CFTSRToTimeInterval(int64_t tsr) {
 
 CFAbsoluteTime CFAbsoluteTimeGetCurrent(void) {
     CFAbsoluteTime ret;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
     struct timeval tv;
     gettimeofday(&tv, NULL);
     ret = (CFTimeInterval)tv.tv_sec - kCFAbsoluteTimeIntervalSince1970;
     ret += (1.0E-6 * (CFTimeInterval)tv.tv_usec);
-#elif DEPLOYMENT_TARGET_WINDOWS
-    FILETIME ft;
-    GetSystemTimeAsFileTime(&ft);
-    ret = _CFAbsoluteTimeFromFileTime(&ft);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
-#endif
     return ret;
 }
 
 __private_extern__ void __CFDateInitialize(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     struct mach_timebase_info info;
     mach_timebase_info(&info);
     __CFTSRRate = (1.0E9 / (double)info.numer) * (double)info.denom;
@@ -102,12 +90,11 @@ __private_extern__ void __CFDateInitialize(void) {
     __CFTSRRate = res.tv_sec + (1000000000 * res.tv_nsec);
     __CF1_TSRRate = 1.0 / __CFTSRRate;
 #else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+#error Unable to initialize date
 #endif
     CFDateGetTypeID(); // cause side-effects
 }
 
-#if 1
 struct __CFDate {
     CFRuntimeBase _base;
     CFAbsoluteTime _time;       /* immutable */
@@ -162,27 +149,26 @@ CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at) {
 }
 
 CFTimeInterval CFDateGetAbsoluteTime(CFDateRef date) {
-    CF_OBJC_FUNCDISPATCH0(CFDateGetTypeID(), CFTimeInterval, date, "timeIntervalSinceReferenceDate");
+    CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFTimeInterval, (NSDate *)date, timeIntervalSinceReferenceDate);
     __CFGenericValidateType(date, CFDateGetTypeID());
     return date->_time;
 }
 
 CFTimeInterval CFDateGetTimeIntervalSinceDate(CFDateRef date, CFDateRef otherDate) {
-    CF_OBJC_FUNCDISPATCH1(CFDateGetTypeID(), CFTimeInterval, date, "timeIntervalSinceDate:", otherDate);
+    CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFTimeInterval, (NSDate *)date, timeIntervalSinceDate:(NSDate *)otherDate);
     __CFGenericValidateType(date, CFDateGetTypeID());
     __CFGenericValidateType(otherDate, CFDateGetTypeID());
     return date->_time - otherDate->_time;
 }   
     
 CFComparisonResult CFDateCompare(CFDateRef date, CFDateRef otherDate, void *context) {
-    CF_OBJC_FUNCDISPATCH1(CFDateGetTypeID(), CFComparisonResult, date, "compare:", otherDate);
+    CF_OBJC_FUNCDISPATCHV(CFDateGetTypeID(), CFComparisonResult, (NSDate *)date, compare:(NSDate *)otherDate);
     __CFGenericValidateType(date, CFDateGetTypeID());
     __CFGenericValidateType(otherDate, CFDateGetTypeID());
     if (date->_time < otherDate->_time) return kCFCompareLessThan;
     if (date->_time > otherDate->_time) return kCFCompareGreaterThan;
     return kCFCompareEqualTo;
 }
-#endif
 
 #endif
 
@@ -283,17 +269,19 @@ Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags) {
 
 CFAbsoluteTime CFGregorianDateGetAbsoluteTime(CFGregorianDate gdate, CFTimeZoneRef tz) {
     CFAbsoluteTime at;
-    CFTimeInterval offset0, offset1;
+    at = 86400.0 * __CFAbsoluteFromYMD(gdate.year - 2001, gdate.month, gdate.day);
+    at += 3600.0 * gdate.hour + 60.0 * gdate.minute + gdate.second;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
-    at = 86400.0 * __CFAbsoluteFromYMD(gdate.year - 2001, gdate.month, gdate.day);
-    at += 3600.0 * gdate.hour + 60.0 * gdate.minute + gdate.second;
+    CFTimeInterval offset0, offset1;
     if (NULL != tz) {
        offset0 = CFTimeZoneGetSecondsFromGMT(tz, at);
        offset1 = CFTimeZoneGetSecondsFromGMT(tz, at - offset0);
        at -= offset1;
     }
+#endif
     return at;
 }
 
@@ -302,10 +290,14 @@ CFGregorianDate CFAbsoluteTimeGetGregorianDate(CFAbsoluteTime at, CFTimeZoneRef
     int64_t absolute, year;
     int8_t month, day;
     CFAbsoluteTime fixedat;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
     fixedat = at + (NULL != tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
+#else
+    fixedat = at;
+#endif
     absolute = (int64_t)floor(fixedat / 86400.0);
     __CFYMDFromAbsolute(absolute, &year, &month, &day);
     if (INT32_MAX - 2001 < year) year = INT32_MAX - 2001;
@@ -326,10 +318,12 @@ CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef
     CFAbsoluteTime candidate_at0, candidate_at1;
     uint8_t monthdays;
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
-
+#endif
+    
     /* Most people seem to expect years, then months, then days, etc.
        to be added in that order.  Thus, 27 April + (4 days, 1 month)
        = 31 May, and not 1 June. This is also relatively predictable.
@@ -440,10 +434,14 @@ CFGregorianUnits CFAbsoluteTimeGetDifferenceAsGregorianUnits(CFAbsoluteTime at1,
 SInt32 CFAbsoluteTimeGetDayOfWeek(CFAbsoluteTime at, CFTimeZoneRef tz) {
     int64_t absolute;
     CFAbsoluteTime fixedat;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
     fixedat = at + (NULL != tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
+#else
+    fixedat = at;
+#endif
     absolute = (int64_t)floor(fixedat / 86400.0);
     return (absolute < 0) ? ((absolute + 1) % 7 + 7) : (absolute % 7 + 1); /* Monday = 1, etc. */
 }
@@ -452,10 +450,14 @@ SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) {
     CFAbsoluteTime fixedat;
     int64_t absolute, year;
     int8_t month, day;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
     fixedat = at + (NULL != tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
+#else
+    fixedat = at;
+#endif
     absolute = (int64_t)floor(fixedat / 86400.0);
     __CFYMDFromAbsolute(absolute, &year, &month, &day);
     return __CFDaysBeforeMonth(month, year, isleap(year)) + day;
@@ -466,10 +468,14 @@ SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) {
     int64_t absolute, year;
     int8_t month, day;
     CFAbsoluteTime fixedat;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (NULL != tz) {
        __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     }
     fixedat = at + (NULL != tz ? CFTimeZoneGetSecondsFromGMT(tz, at) : 0.0);
+#else
+    fixedat = at;
+#endif
     absolute = (int64_t)floor(fixedat / 86400.0);
     __CFYMDFromAbsolute(absolute, &year, &month, &day);
     double absolute0101 = __CFAbsoluteFromYMD(year, 1, 1);
index 354aae3041cb073e4458806fe38671f96ce02574..fada953e99413b1c83404520f552b4c1139a3280 100644 (file)
--- a/CFDate.h
+++ b/CFDate.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFDate.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATE__)
@@ -30,6 +30,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef double CFTimeInterval;
@@ -62,6 +63,8 @@ CFTimeInterval CFDateGetTimeIntervalSinceDate(CFDateRef theDate, CFDateRef other
 CF_EXPORT
 CFComparisonResult CFDateCompare(CFDateRef theDate, CFDateRef otherDate, void *context);
 
+CF_IMPLICIT_BRIDGING_DISABLED
+
 typedef const struct __CFTimeZone * CFTimeZoneRef;
 
 typedef struct {
@@ -82,7 +85,7 @@ typedef struct {
     double seconds;
 } CFGregorianUnits;
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFGregorianUnitFlags) {
     kCFGregorianUnitsYears = (1UL << 0),
     kCFGregorianUnitsMonths = (1UL << 1),
     kCFGregorianUnitsDays = (1UL << 2),
@@ -91,7 +94,6 @@ enum {
     kCFGregorianUnitsSeconds = (1UL << 5),
     kCFGregorianAllUnits = 0x00FFFFFF
 };
-typedef CFOptionFlags CFGregorianUnitFlags;
 
 CF_EXPORT
 Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags);
index d751f6e0190021dd312224326736a173b4c763ec..1b1426562e4d9b498b4b2f5334754b635c6c70f3 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*        CFDateFormatter.c
-        Copyright (c) 2002-2011, Apple Inc. All rights reserved.
+        Copyright (c) 2002-2012, Apple Inc. All rights reserved.
         Responsibility: David Smith
 */
 
 #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
+    kCFDateFormatterAmbiguousYearAssumeToCurrent = 2, // default to assuming the current century or era
+    kCFDateFormatterAmbiguousYearAssumeToCenteredAroundCurrentDate = 3,
+    kCFDateFormatterAmbiguousYearAssumeToFuture = 4,
+    kCFDateFormatterAmbiguousYearAssumeToPast = 5,
+    kCFDateFormatterAmbiguousYearAssumeToLikelyFuture = 6,
+    kCFDateFormatterAmbiguousYearAssumeToLikelyPast = 7
+};
+
 extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz);
 static void __CFDateFormatterCustomize(CFDateFormatterRef formatter);
 
@@ -148,7 +159,7 @@ struct __CFDateFormatter {
         CFBooleanRef _IsLenient;
        CFBooleanRef _DoesRelativeDateFormatting;
        CFBooleanRef _HasCustomFormat;
-        CFTimeZoneRef _TimeZone; 
+        CFTimeZoneRef _TimeZone;
         CFCalendarRef _Calendar;
         CFStringRef _CalendarName;
         CFDateRef _TwoDigitStartDate;
@@ -174,6 +185,7 @@ struct __CFDateFormatter {
         CFArrayRef _ShortStandaloneQuarterSymbols;
         CFStringRef _AMSymbol;
         CFStringRef _PMSymbol;
+        CFNumberRef _AmbiguousYearStrategy;
     } _property;
 };
 
@@ -216,6 +228,7 @@ static void __CFDateFormatterDeallocate(CFTypeRef cf) {
     CFReleaseIfNotNull(formatter->_property._ShortStandaloneQuarterSymbols);
     CFReleaseIfNotNull(formatter->_property._AMSymbol);
     CFReleaseIfNotNull(formatter->_property._PMSymbol);
+    CFReleaseIfNotNull(formatter->_property._AmbiguousYearStrategy);
 }
 
 static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef formatter, CFStringRef inString);
@@ -261,7 +274,7 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     }
     Boolean wantRelative = (NULL != df->_property._DoesRelativeDateFormatting && df->_property._DoesRelativeDateFormatting == kCFBooleanTrue);
     Boolean hasFormat = (NULL != df->_property._HasCustomFormat && df->_property._HasCustomFormat == kCFBooleanTrue) || goingToHaveCustomFormat;
-    if (wantRelative && !hasFormat) {
+    if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) {
        udstyle |= UDAT_RELATIVE;
     }
 
@@ -272,7 +285,12 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     }
     udat_setLenient(icudf, 0);
     if (kCFDateFormatterNoStyle == df->_dateStyle && kCFDateFormatterNoStyle == df->_timeStyle) {
-        udat_applyPattern(icudf, false, NULL, 0);
+        if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != df->_dateStyle) {
+            UErrorCode s = U_ZERO_ERROR;
+            udat_applyPatternRelative(icudf, NULL, 0, NULL, 0, &s);
+        } else {
+            udat_applyPattern(icudf, false, NULL, 0);
+        }
     }
     CFStringRef calident = (CFStringRef)CFLocaleGetValue(df->_locale, kCFLocaleCalendarIdentifierKey);
     if (calident && CFEqual(calident, kCFCalendarIdentifierGregorian)) {
@@ -283,35 +301,81 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
 
     __CFDateFormatterCustomize(df);
 
-    UChar ubuffer[BUFFER_SIZE];
-    status = U_ZERO_ERROR;
-    int32_t ret = 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);
-        CFIndex cnt = CFStringGetLength(formatString);
-        CFAssert1(cnt <= 1024, __kCFLogAssertion, "%s(): format string too long", __PRETTY_FUNCTION__);
-        if (df->_format != formatString && cnt <= 1024) {
-            STACK_BUFFER_DECL(UChar, ubuffer, cnt);
-            const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)formatString);
-            if (NULL == ustr) {
-                CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)ubuffer);
-                ustr = ubuffer;
+    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;
+        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);
+            CFStringRef formatString = __CFDateFormatterCreateForcedString(df, newFormat);
+            CFIndex cnt = CFStringGetLength(formatString);
+            CFAssert1(cnt <= BUFFER_SIZE, __kCFLogAssertion, "%s(): time format string too long", __PRETTY_FUNCTION__);
+            if (cnt <= BUFFER_SIZE) {
+                CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)timeBuffer);
+                timeLen = cnt;
+                status = U_ZERO_ERROR;
+                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
+                if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
+                    if (df->_format) CFRelease(df->_format);
+                    df->_format = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, ret);
+                }
             }
-            UErrorCode status = U_ZERO_ERROR;
+            CFRelease(formatString);
+            CFRelease(newFormat);
+        }
+    } else {
+        UChar ubuffer[BUFFER_SIZE];
+        status = U_ZERO_ERROR;
+        int32_t ret = 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);
+            CFIndex cnt = CFStringGetLength(formatString);
+            CFAssert1(cnt <= 1024, __kCFLogAssertion, "%s(): format string too long", __PRETTY_FUNCTION__);
+            if (df->_format != formatString && cnt <= 1024) {
+                STACK_BUFFER_DECL(UChar, ubuffer, cnt);
+                const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)formatString);
+                if (NULL == ustr) {
+                    CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)ubuffer);
+                    ustr = ubuffer;
+                }
+                UErrorCode status = U_ZERO_ERROR;
 //            udat_applyPattern(df->_df, false, ustr, cnt, &status);
-            udat_applyPattern(df->_df, false, ustr, cnt);
-            if (U_SUCCESS(status)) {
-                if (df->_format) CFRelease(df->_format);
-                df->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(df), formatString);
+                udat_applyPattern(df->_df, false, ustr, cnt);
+                if (U_SUCCESS(status)) {
+                    if (df->_format) CFRelease(df->_format);
+                    df->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(df), formatString);
+                }
             }
+            CFRelease(formatString);
+            CFRelease(newFormat);
         }
-        CFRelease(formatString);
-        CFRelease(newFormat);
     }
     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);
@@ -340,6 +404,7 @@ static void __ResetUDateFormat(CFDateFormatterRef df, Boolean goingToHaveCustomF
     RESET_PROPERTY(_ShortStandaloneQuarterSymbols, kCFDateFormatterShortStandaloneQuarterSymbolsKey);
     RESET_PROPERTY(_AMSymbol, kCFDateFormatterAMSymbolKey);
     RESET_PROPERTY(_PMSymbol, kCFDateFormatterPMSymbolKey);
+    RESET_PROPERTY(_AmbiguousYearStrategy, kCFDateFormatterAmbiguousYearStrategyKey);
 }
 
 static CFTypeID __kCFDateFormatterTypeID = _kCFRuntimeNotATypeID;
@@ -352,7 +417,7 @@ static const CFRuntimeClass __CFDateFormatterClass = {
     __CFDateFormatterDeallocate,
     NULL,
     NULL,
-    NULL,        // 
+    NULL,        //
     __CFDateFormatterCopyDescription
 };
 
@@ -410,6 +475,7 @@ CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef l
     memory->_property._ShortStandaloneQuarterSymbols = NULL;
     memory->_property._AMSymbol = NULL;
     memory->_property._PMSymbol = NULL;
+    memory->_property._AmbiguousYearStrategy = NULL;
 
     switch (dateStyle) {
     case kCFDateFormatterNoStyle:
@@ -639,7 +705,7 @@ static CFStringRef __CFDateFormatterCreateForcedTemplate(CFLocaleRef locale, CFS
         }
         if (emit) CFStringAppendCharacters(outString, &ch, 1);
     }
-    
+
     return outString;
 }
 
@@ -728,7 +794,7 @@ static CFStringRef __CFDateFormatterCreateForcedString(CFDateFormatterRef format
 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) {
+    if (wantRelative && !hasFormat && kCFDateFormatterNoStyle != formatter->_dateStyle) {
         __substituteFormatStringFromPrefsDFRelative(formatter);
     } else {
         __substituteFormatStringFromPrefsDF(formatter, false);
@@ -796,6 +862,7 @@ void CFDateFormatterSetFormat(CFDateFormatterRef formatter, CFStringRef formatSt
         // the whole UDateFormat.
         if (formatter->_property._HasCustomFormat != kCFBooleanTrue && formatter->_property._DoesRelativeDateFormatting == kCFBooleanTrue) {
             __ResetUDateFormat(formatter, true);
+            // the "true" results in: if you set a custom format string, you don't get relative date formatting
         }
         STACK_BUFFER_DECL(UChar, ubuffer, cnt);
         const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)formatString);
@@ -846,6 +913,256 @@ CFStringRef CFDateFormatterCreateStringWithAbsoluteTime(CFAllocatorRef allocator
     return string;
 }
 
+static UDate __CFDateFormatterCorrectTimeWithTarget(UCalendar *calendar, UDate at, int32_t target, Boolean isEra, UErrorCode *status) {
+    ucal_setMillis(calendar, at, status);
+    UCalendarDateFields field = isEra ? UCAL_ERA : UCAL_YEAR;
+    ucal_set(calendar, field, target);
+    return 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);
+    UCalendarDateFields field = isEra ? UCAL_ERA : UCAL_YEAR;
+    int32_t currEraOrCentury = ucal_get(calendar, field, status);
+    if (!isEra) {
+        currYear %= 100;
+        currEraOrCentury = currEraOrCentury / 100 * 100; // get century
+    }
+
+    CFIndex futureMax = currYear + futureYears;
+    CFIndex pastMin = currYear - pastYears;
+
+    CFRange currRange, futureRange, pastRange;
+    currRange.location = futureRange.location = pastRange.location = kCFNotFound;
+    currRange.length = futureRange.length = pastRange.length = 0;
+    if (!isEra) {
+        if (period < INT_MAX && futureMax >= period) {
+            futureRange.location = 0;
+            futureRange.length = futureMax - period + 1;
+        }
+        if (pastMin < 0) {
+            pastRange.location = period + pastMin;
+            pastRange.length = period - pastRange.location;
+        }
+        if (pastRange.location != kCFNotFound) {
+            currRange.location = 0;
+        } else {
+            currRange.location = pastMin;
+        }
+    } else {
+        if (period < INT_MAX && futureMax > period) {
+            futureRange.location = 1,
+            futureRange.length = futureMax - period;
+        }
+        if (pastMin <= 0) {
+            pastRange.location = period + pastMin;
+            pastRange.length = period - pastRange.location + 1;
+        }
+        if (pastRange.location != kCFNotFound) {
+            currRange.location = 1;
+        } else {
+            currRange.location = pastMin;
+        }
+
+    }
+    currRange.length = period - pastRange.length - futureRange.length;
+
+    ucal_setMillis(calendar, at, status);
+    int32_t atYear = ucal_get(calendar, UCAL_YEAR, status);
+    if (!isEra) {
+        atYear %= 100;
+        currEraOrCentury += atYear;
+    }
+
+    int32_t offset = 0; // current era or century
+    if (pastRange.location != kCFNotFound && atYear >= pastRange.location && atYear - pastRange.location + 1 <= pastRange.length) {
+        offset = -1; // past era or century
+    } else if (futureRange.location != kCFNotFound && atYear >= futureRange.location && atYear - futureRange.location + 1 <= futureRange.length) {
+        offset = 1; // next era or century
+    }
+    if (!isEra) offset *= 100;
+    return __CFDateFormatterCorrectTimeWithTarget(calendar, at, currEraOrCentury+offset, isEra, status);
+}
+
+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);
+    return years+1;
+}
+
+static Boolean __CFDateFormatterHandleAmbiguousYear(CFDateFormatterRef formatter, CFStringRef calendar_id, UDateFormat *df, UCalendar *cal, UDate *at, const UChar *ustr, CFIndex length, UErrorCode *status) {
+    Boolean success = true;
+    int64_t ambigStrat = kCFDateFormatterAmbiguousYearAssumeToNone;
+    if (formatter->_property._AmbiguousYearStrategy) {
+        CFNumberGetValue(formatter->_property._AmbiguousYearStrategy, kCFNumberSInt64Type, &ambigStrat);
+    }
+    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) {
+            switch (ambigStrat) {
+                case kCFDateFormatterAmbiguousYearFailToParse:
+                    success = false;
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToCurrent: {
+                    ucal_setMillis(cal, ucal_getNow(), status);
+                    int32_t currEra = ucal_get(cal, UCAL_ERA, status);
+                    *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
+                    break;
+                    }
+                case kCFDateFormatterAmbiguousYearAssumeToCenteredAroundCurrentDate:
+                    *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 60, 29, 30, true, status);
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToFuture:
+                    *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 60, 0, 59, true, status);
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToPast:
+                    *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 60, 59, 0, true, status);
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToLikelyFuture:
+                    *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 60, 10, 49, true, status);
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToLikelyPast:
+                    *at = __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(cal, *at, 60, 49, 10, true, status);
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToNone:
+                default:
+                    break; // do nothing
+            }
+        }
+    } 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 (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);
+            switch (ambigStrat) {
+                case kCFDateFormatterAmbiguousYearFailToParse:
+                    success = false;
+                    break;
+                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;
+                    } else { // current era
+                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
+                    }
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToPast:
+                    if (givenYear > currYear) { // past era
+                        success = false;
+                        // we find the closest era that has the given year
+                        // if no era has such given year, we fail the parse
+                        for (CFIndex era = currEra-1; era >= 234; era--) { // Showa era (234) is the longest era
+                            int32_t years = __CFDateFormatterGetMaxYearGivenJapaneseEra(cal, era, status);
+                            if (givenYear > years) {
+                                continue;
+                            }
+                            success = true;
+                            *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, era, true, status);
+                            break;
+                        }
+                    } else { // current era
+                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
+                    }
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToLikelyFuture:
+                    if (givenYear < currYear - 10) { // we allow 10 years to the past
+                        success = false;
+                    } else {
+                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
+                    }
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToLikelyPast:
+                    if (givenYear > currYear + 10) {
+                        success = false;
+                        // we find the closest era that has the given year
+                        // if no era has such given year, we fail the parse
+                        for (CFIndex era = currEra-1; era >= 234; era--) { // Showa era (234) is the longest era
+                            int32_t years = __CFDateFormatterGetMaxYearGivenJapaneseEra(cal, era, status);
+                            if (givenYear > years) {
+                                continue;
+                            }
+                            success = true;
+                            *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, era, true, status);
+                            break;
+                        }
+                    } else { // current era
+                        *at = __CFDateFormatterCorrectTimeWithTarget(cal, *at, currEra, true, status);
+                    }
+                    break;
+                case kCFDateFormatterAmbiguousYearAssumeToNone:
+                default:
+                    break; // do nothing
+            }
+        }
+    } 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);
+                }
+                break; // do nothing
+            }
+        }
+
+    }
+    return success;
+}
+
 CFDateRef CFDateFormatterCreateDateFromString(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFStringRef string, CFRange *rangep) {
     if (allocator == NULL) allocator = __CFGetDefaultAllocator();
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
@@ -879,26 +1196,54 @@ 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);
+    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);
+    } 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
+    } 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);
+    }
     if (formatter->_property._DefaultDate) {
         CFAbsoluteTime at = CFDateGetAbsoluteTime(formatter->_property._DefaultDate);
         udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
-        UDateFormat *df2 = udat_clone(formatter->_df, &status);
-        UCalendar *cal2 = (UCalendar *)udat_getCalendar(df2);
         ucal_setMillis(cal2, udate, &status);
-        udat_parseCalendar(formatter->_df, cal2, ustr, range.length, &dpos, &status);
-        udate = ucal_getMillis(cal2, &status);
-        udat_close(df2);
-    } else {
-        udate = udat_parse(formatter->_df, ustr, range.length, &dpos, &status);
     }
+    udat_parseCalendar(df2, cal2, ustr, range.length, &dpos, &status);
+    udate = ucal_getMillis(cal2, &status);
     if (rangep) rangep->length = dpos;
-    if (U_FAILURE(status)) {
-        return false;
-    }
-    if (atp) {
-        *atp = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
+    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 (atp) {
+            *atp = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
+        }
+        success = true;
     }
-    return true;
+    CFRelease(calendar_id);
+    udat_close(df2);
+    return success;
 }
 
 static void __CFDateFormatterSetSymbolsArray(UDateFormat *icudf, int32_t icucode, int index_base, CFTypeRef value) {
@@ -1163,6 +1508,11 @@ static void __CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringR
        if (!directToICU) {
             formatter->_property. _PMSymbol = (CFStringRef)CFDateFormatterCopyProperty(formatter, kCFDateFormatterPMSymbolKey);
        }
+    } else if (kCFDateFormatterAmbiguousYearStrategyKey == key) {
+        oldProperty = formatter->_property._AmbiguousYearStrategy;
+        formatter->_property._AmbiguousYearStrategy = NULL;
+        __CFGenericValidateType(value, CFNumberGetTypeID());
+        formatter->_property._AmbiguousYearStrategy = (CFNumberRef)CFRetain(value);
     } else {
         CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
     }
@@ -1277,7 +1627,7 @@ CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef
             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);
@@ -1286,7 +1636,9 @@ CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef
             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 {
         CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
     }
index 065f5b906b31014f5b33df574e3e48cc9e6a7bce..49ca96887875e35570acfc795c2b38c420477542 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFDateFormatter.h
-       Copyright (c) 2003-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2003-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFDATEFORMATTER__)
@@ -45,14 +45,13 @@ CFStringRef CFDateFormatterCreateDateFormatFromTemplate(CFAllocatorRef allocator
 CF_EXPORT
 CFTypeID CFDateFormatterGetTypeID(void);
 
-enum { // date and time format styles
+typedef CF_ENUM(CFIndex, CFDateFormatterStyle) {       // date and time format styles
        kCFDateFormatterNoStyle = 0,
        kCFDateFormatterShortStyle = 1,
        kCFDateFormatterMediumStyle = 2,
        kCFDateFormatterLongStyle = 3,
        kCFDateFormatterFullStyle = 4
 };
-typedef CFIndex CFDateFormatterStyle;
 
 // The exact formatted result for these date and time styles depends on the
 // locale, but generally:
@@ -165,7 +164,7 @@ CF_EXPORT const CFStringRef kCFDateFormatterDoesRelativeDateFormattingKey CF_AVA
 //     const CFStringRef kCFRepublicOfChinaCalendar;
 //     const CFStringRef kCFPersianCalendar;
 //     const CFStringRef kCFIndianCalendar;
-//     const CFStringRef kCFISO8601Calendar;   not yet implemented
+//     const CFStringRef kCFISO8601Calendar;
 
 CF_EXTERN_C_END
 
index de1067fb8a84e1b8d951125900c2142546a1bee3..173c0ae97d11ba6d7d6965d6c2b5d44070c620d9 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFDictionary.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -36,6 +36,7 @@
 #include "CFBasicHash.h"
 #include <CoreFoundation/CFString.h>
 
+
 #define CFDictionary 0
 #define CFSet 0
 #define CFBag 0
@@ -217,7 +218,7 @@ static CFBasicHashCallbacks *__CFDictionaryCopyCallbacks(CFConstBasicHashRef ht,
     } else {
         newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
     }
-    if (!newcb) HALT;
+    if (!newcb) return NULL;
     memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
     return newcb;
 }
@@ -386,7 +387,7 @@ static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, cons
         } else {
             newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) HALT;
+        if (!newcb) return NULL;
         newcb->copyCallbacks = __CFDictionaryCopyCallbacks;
         newcb->freeCallbacks = __CFDictionaryFreeCallbacks;
         newcb->retainValue = __CFDictionaryRetainValue;
@@ -427,7 +428,8 @@ static CFBasicHashRef __CFDictionaryCreateGeneric(CFAllocatorRef allocator, cons
     }
 
     CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, specialBits);
+    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
+    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
     return ht;
 }
 
@@ -468,6 +470,7 @@ CFHashRef CFDictionaryCreate(CFAllocatorRef allocator, const_any_pointer_t *klis
     CFTypeID typeID = CFDictionaryGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFBasicHashRef ht = __CFDictionaryCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
+    if (!ht) return NULL;
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
@@ -489,6 +492,7 @@ CFMutableHashRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex cap
     CFTypeID typeID = CFDictionaryGetTypeID();
     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);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)");
@@ -513,8 +517,8 @@ CFHashRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFDictionaryCreateGeneric(allocator, & kCFTypeDictionaryKeyCallBacks, CFDictionary ? & kCFTypeDictionaryValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -522,6 +526,7 @@ CFHashRef CFDictionaryCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
@@ -548,8 +553,8 @@ CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFDictionaryCreateGeneric(allocator, & kCFTypeDictionaryKeyCallBacks, CFDictionary ? & kCFTypeDictionaryValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -557,6 +562,7 @@ CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFDictionary (mutable)");
@@ -564,8 +570,8 @@ CFMutableHashRef CFDictionaryCreateMutableCopy(CFAllocatorRef allocator, CFIndex
 }
 
 CFIndex CFDictionaryGetCount(CFHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID, CFIndex, hc, "count");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID, CFIndex, hc, "count");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, CFIndex, (NSDictionary *)hc, count);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, CFIndex, (NSSet *)hc, count);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     return CFBasicHashGetCount((CFBasicHashRef)hc);
 }
@@ -576,8 +582,8 @@ CFIndex CFDictionaryGetCountOfKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, CFIndex, hc, "countForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, CFIndex, hc, "countForObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, CFIndex, (NSDictionary *)hc, countForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, CFIndex, (NSSet *)hc, countForObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key);
 }
@@ -588,23 +594,23 @@ Boolean CFDictionaryContainsKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, char, hc, "containsKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, char, hc, "containsObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, char, (NSDictionary *)hc, containsKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, char, (NSSet *)hc, containsObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key));
 }
 
 const_any_pointer_t CFDictionaryGetValue(CFHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, const_any_pointer_t, hc, "objectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, const_any_pointer_t, hc, "member:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, const_any_pointer_t, (NSSet *)hc, member:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0);
 }
 
 Boolean CFDictionaryGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, Boolean, hc, "__getValue:forKey:", (any_t *)value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, Boolean, hc, "__getValue:forObj:", (any_t *)value, key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -622,19 +628,18 @@ Boolean CFDictionaryGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, con
 
 #if CFDictionary
 CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, CFIndex, hc, "countForObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, CFIndex, (NSDictionary *)hc, countForObject:(id)value);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value);
 }
 
 Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, char, hc, "containsObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, char, (NSDictionary *)hc, containsObject:(id)value);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value));
 }
 
 CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) {
-    CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, Boolean, hc, "getActualKey:forKey:", actualkey, key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -658,8 +663,8 @@ void CFDictionaryGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, con
 void CFDictionaryGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
     const_any_pointer_t *valuebuf = 0;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "getObjects:andKeys:", (any_t *)valuebuf, (any_t *)keybuf);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "getObjects:", (any_t *)keybuf);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSSet *)hc, getObjects:(id *)keybuf);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     if (kCFUseCollectableAllocator) {
         CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc);
@@ -681,8 +686,8 @@ void CFDictionaryGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
 
 void CFDictionaryApplyFunction(CFHashRef hc, CFDictionaryApplierFunction applier, any_pointer_t context) {
     FAULT_CALLBACK((void **)&(applier));
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "__apply:context:", applier, context);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "__applyValues:context:", applier, context);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
 #if CFDictionary
@@ -756,8 +761,8 @@ void CFDictionaryAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_an
 void CFDictionaryAddValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "addObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "addObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableSet *)hc, addObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -775,8 +780,8 @@ void CFDictionaryReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, cons
 void CFDictionaryReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "replaceObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "replaceObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableDictionary *)hc, replaceObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableSet *)hc, replaceObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -794,8 +799,8 @@ void CFDictionarySetValue(CFMutableHashRef hc, const_any_pointer_t key, const_an
 void CFDictionarySetValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFDictionaryTypeID, void, hc, "setObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "setObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableDictionary *)hc, __setObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableSet *)hc, setObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -808,8 +813,8 @@ void CFDictionarySetValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFDictionaryRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "removeObjectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFDictionaryTypeID, void, hc, "removeObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableSet *)hc, removeObject:(id)key);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -821,8 +826,8 @@ void CFDictionaryRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFDictionaryRemoveAllValues(CFMutableHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID, void, hc, "removeAllObjects");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFDictionaryTypeID, void, hc, "removeAllObjects");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableDictionary *)hc, removeAllObjects);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFDictionaryTypeID, void, (NSMutableSet *)hc, removeAllObjects);
     __CFGenericValidateType(hc, __kCFDictionaryTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
index 590c99076b71dbc3ebe12801fc92f60d3829db65..41c75d22da83112cf3aed63342f4df0bfa0f4fee 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFDictionary.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 /*!
@@ -84,6 +84,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -685,6 +686,7 @@ CF_EXPORT
 void CFDictionaryRemoveAllValues(CFMutableDictionaryRef theDict);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFDICTIONARY__ */
 
index df641055d2c76993e30e3e73abf94b2b99d511c0..d1cee849eccb00f396c2e599f5c53e7dab587c08 100644 (file)
--- a/CFError.c
+++ b/CFError.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFError.c
-       Copyright (c) 2006-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2006-2012, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
@@ -34,6 +34,7 @@
 #include <mach/mach_error.h>
 #endif
 
+
 /* Pre-defined userInfo keys
 */
 CONST_STRING_DECL(kCFErrorLocalizedDescriptionKey,          "NSLocalizedDescription");
@@ -198,7 +199,7 @@ static CFDictionaryRef _CFErrorCreateEmptyDictionary(CFAllocatorRef allocator) {
 /* A non-retained accessor for the userInfo. Might return NULL in some cases, if the subclass of NSError returned nil for some reason. It works with a CF or NSError.
 */
 static CFDictionaryRef _CFErrorGetUserInfo(CFErrorRef err) {
-    CF_OBJC_FUNCDISPATCH0(__kCFErrorTypeID, CFDictionaryRef, err, "userInfo");
+    CF_OBJC_FUNCDISPATCHV(__kCFErrorTypeID, CFDictionaryRef, (NSError *)err, userInfo);
     __CFAssertIsError(err);
     return err->userInfo;
 }
@@ -314,7 +315,7 @@ CFStringRef _CFErrorCreateDebugDescription(CFErrorRef err) {
     CFStringAppendFormat(result, NULL, CFSTR("Error Domain=%@ Code=%d"), CFErrorGetDomain(err), (long)CFErrorGetCode(err));
     CFStringAppendFormat(result, NULL, CFSTR(" \"%@\""), desc);
     if (debugDesc && CFStringGetLength(debugDesc) > 0) CFStringAppendFormat(result, NULL, CFSTR(" (%@)"), debugDesc);
-    if (userInfo) {
+    if (userInfo && CFDictionaryGetCount(userInfo)) {
         CFStringAppendFormat(result, NULL, CFSTR(" UserInfo=%p {"), userInfo);
        CFDictionaryApplyFunction(userInfo, userInfoKeyValueShow, (void *)result);
        CFIndex commaLength = (CFStringHasSuffix(result, CFSTR(", "))) ? 2 : 0;
@@ -362,13 +363,13 @@ CFErrorRef CFErrorCreateWithUserInfoKeysAndValues(CFAllocatorRef allocator, CFSt
 }
 
 CFStringRef CFErrorGetDomain(CFErrorRef err) {
-    CF_OBJC_FUNCDISPATCH0(__kCFErrorTypeID, CFStringRef, err, "domain");
+    CF_OBJC_FUNCDISPATCHV(__kCFErrorTypeID, CFStringRef, (NSError *)err, domain);
     __CFAssertIsError(err);
     return err->domain;
 }
 
 CFIndex CFErrorGetCode(CFErrorRef err) {
-    CF_OBJC_FUNCDISPATCH0(__kCFErrorTypeID, CFIndex, err, "code");
+    CF_OBJC_FUNCDISPATCHV(__kCFErrorTypeID, CFIndex, (NSError *)err, code);
     __CFAssertIsError(err);
     return err->code;
 }
@@ -382,8 +383,7 @@ CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) {
 
 CFStringRef CFErrorCopyDescription(CFErrorRef err) {
     if (CF_IS_OBJC(__kCFErrorTypeID, err)) {  // Since we have to return a retained result, we need to treat the toll-free bridging specially
-        CFStringRef desc;
-        CF_OBJC_CALL0(CFStringRef, desc, err, "localizedDescription");
+        CFStringRef desc = (CFStringRef) CF_OBJC_CALLV((NSError *)err, localizedDescription);
         return desc ? (CFStringRef)CFRetain(desc) : NULL;    // !!! It really should never return nil.
     }
     __CFAssertIsError(err);
@@ -392,8 +392,7 @@ CFStringRef CFErrorCopyDescription(CFErrorRef err) {
 
 CFStringRef CFErrorCopyFailureReason(CFErrorRef err) {
     if (CF_IS_OBJC(__kCFErrorTypeID, err)) {  // Since we have to return a retained result, we need to treat the toll-free bridging specially
-        CFStringRef str;
-        CF_OBJC_CALL0(CFStringRef, str, err, "localizedFailureReason");
+        CFStringRef str = (CFStringRef) CF_OBJC_CALLV((NSError *)err, localizedFailureReason);
         return str ? (CFStringRef)CFRetain(str) : NULL;    // It's possible for localizedFailureReason to return nil
     }
     __CFAssertIsError(err);
@@ -402,8 +401,7 @@ CFStringRef CFErrorCopyFailureReason(CFErrorRef err) {
 
 CFStringRef CFErrorCopyRecoverySuggestion(CFErrorRef err) {
     if (CF_IS_OBJC(__kCFErrorTypeID, err)) {  // Since we have to return a retained result, we need to treat the toll-free bridging specially
-        CFStringRef str;
-        CF_OBJC_CALL0(CFStringRef, str, err, "localizedRecoverySuggestion");
+        CFStringRef str = (CFStringRef) CF_OBJC_CALLV((NSError *)err, localizedRecoverySuggestion);
         return str ? (CFStringRef)CFRetain(str) : NULL;    // It's possible for localizedRecoverySuggestion to return nil
     }
     __CFAssertIsError(err);
@@ -435,26 +433,30 @@ static CFTypeRef _CFErrorPOSIXCallBack(CFErrorRef err, CFStringRef key) {
     CFArrayRef paths = CFCopySearchPathForDirectoriesInDomains(kCFLibraryDirectory, kCFSystemDomainMask, false);
     if (paths) {
        if (CFArrayGetCount(paths) > 0) {
-           CFStringRef path = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@/CoreServices/CoreTypes.bundle"), CFArrayGetValueAtIndex(paths, 0));
-           CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, false /* not a directory */);
-           if (url) {
-               CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url);
-               if (bundle) {
-                   // We only want to return a result if there was a localization
-                   CFStringRef localizedErrStr = CFBundleCopyLocalizedString(bundle, errStr, errStr, CFSTR("ErrnoErrors"));
-                   if (localizedErrStr == errStr) {
-                       CFRelease(localizedErrStr);
-                       CFRelease(errStr);
-                       errStr = NULL;
-                   } else {
-                       CFRelease(errStr);
-                       errStr = localizedErrStr;
-                   }
-                   CFRelease(bundle);
-               }
-               CFRelease(url);
-           }
-           CFRelease(path);
+            CFStringRef fileSystemPath = CFURLCopyFileSystemPath((CFURLRef)CFArrayGetValueAtIndex(paths, 0), kCFURLPOSIXPathStyle);
+            if (fileSystemPath) {
+                CFStringRef path = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@/CoreServices/CoreTypes.bundle"), fileSystemPath);
+                CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, false /* not a directory */);
+                CFRelease(fileSystemPath);
+                if (url) {
+                    CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url);
+                    if (bundle) {
+                        // We only want to return a result if there was a localization
+                        CFStringRef localizedErrStr = CFBundleCopyLocalizedString(bundle, errStr, errStr, CFSTR("ErrnoErrors"));
+                        if (localizedErrStr == errStr) {
+                            CFRelease(localizedErrStr);
+                            CFRelease(errStr);
+                            errStr = NULL;
+                        } else {
+                            CFRelease(errStr);
+                            errStr = localizedErrStr;
+                        }
+                        CFRelease(bundle);
+                    }
+                    CFRelease(url);
+                }
+                CFRelease(path);
+            }
        }
        CFRelease(paths);
     }
@@ -500,7 +502,7 @@ void CFErrorSetCallBackForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallB
     if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable();
     __CFSpinLock(&_CFErrorSpinlock);
     if (callBack) {
-        CFDictionarySetValue(_CFErrorCallBackTable, domainName, callBack);
+        CFDictionarySetValue(_CFErrorCallBackTable, domainName, (void *)callBack);
     } else {
         CFDictionaryRemoveValue(_CFErrorCallBackTable, domainName);
     }
index a8878119f8c3332ef3166830c37f55f745bb41b4..61ee8a123145073b4a8a01f9059f7595be496a72 100644 (file)
--- a/CFError.h
+++ b/CFError.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFError.h
-       Copyright (c) 2006-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2006-2012, Apple Inc. All rights reserved.
 */
 
 /*!
@@ -56,6 +56,7 @@
 #include <CoreFoundation/CFString.h>
 #include <CoreFoundation/CFDictionary.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -190,6 +191,7 @@ CFStringRef CFErrorCopyRecoverySuggestion(CFErrorRef err) CF_AVAILABLE(10_5, 2_0
 
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFERROR__ */
 
index d43971c98df78213b67cbd01414ace26659b0004..6a9b6ef65941aa02864f69d4325cd9a622aaf0d8 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFError_Private.h
-        Copyright (c) 2006-2011, Apple Inc. All rights reserved.
+        Copyright (c) 2006-2012, Apple Inc. All rights reserved.
        
        This is Apple-internal SPI for CFError.
 */
index 0bffeb9cbc373d11cf9aa54e683d55c96ec67f4a..4334b0ee67f55df93b3a39e3bb163e12b2fc1236 100644 (file)
  */
 
 /*     CFFileUtilities.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
 #include "CFInternal.h"
 #include <CoreFoundation/CFPriv.h>
+
+#include <sys/stat.h>
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+
 #if DEPLOYMENT_TARGET_WINDOWS
 #include <io.h>
 #include <fcntl.h>
-#include <sys/stat.h>
-#include <errno.h>
 
 #define close _close
 #define write _write
 #define statinfo _stat
 
 #else
-    #include <string.h>
-    #include <unistd.h>
-    #include <dirent.h>
-    #include <sys/stat.h>
-    #include <sys/types.h>
-    #include <pwd.h>
-    #include <fcntl.h>
-    #include <errno.h>
-    #include <stdio.h>
+
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <fcntl.h>
 
 #define statinfo stat
 
@@ -70,10 +71,7 @@ CF_INLINE int openAutoFSNoWait() {
 }
 
 CF_INLINE void closeAutoFSNoWait(int fd) {
-#if DEPLOYMENT_TARGET_WINDOWS
-#else
     if (-1 != fd) close(fd);
-#endif
 }
 
 __private_extern__ CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType) {
@@ -88,13 +86,6 @@ __private_extern__ Boolean _CFCreateDirectory(const char *path) {
     return ret;
 }
 
-#if DEPLOYMENT_TARGET_WINDOWS
-// todo: remove this function and make callers use _CFCreateDirectory
-__private_extern__ Boolean _CFCreateDirectoryWide(const wchar_t *path) {
-    return CreateDirectoryW(path, 0);
-}
-#endif
-
 __private_extern__ Boolean _CFRemoveDirectory(const char *path) {
     int no_hang_fd = openAutoFSNoWait();
     int ret = ((rmdir(path) == 0) ? true : false);
@@ -109,34 +100,30 @@ __private_extern__ Boolean _CFDeleteFile(const char *path) {
     return ret;
 }
 
-__private_extern__ Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength) {
-    // maxLength is the number of bytes desired, or 0 if the whole file is desired regardless of length.
-    int fd = -1;
+__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.
     struct statinfo statBuf;
-    char path[CFMaxPathSize];
-    if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize)) {
-        return false;
-    }
-
+    
     *bytes = NULL;
-
+    
     
     int no_hang_fd = openAutoFSNoWait();
-    fd = open(path, O_RDONLY|CF_OPENFLGS, 0666);
-
-    if (fd < 0) {
+    *fd = open(path, O_RDONLY|extraOpenFlags|CF_OPENFLGS, 0666);
+    
+    if (*fd < 0) {
         closeAutoFSNoWait(no_hang_fd);
         return false;
     }
-    if (fstat(fd, &statBuf) < 0) {
+    if (fstat(*fd, &statBuf) < 0) {
         int saveerr = thread_errno();
-        close(fd);
+        close(*fd);
+        *fd = -1;
         closeAutoFSNoWait(no_hang_fd);
         thread_set_errno(saveerr);
         return false;
     }
     if ((statBuf.st_mode & S_IFMT) != S_IFREG) {
-        close(fd);
+        close(*fd);
+        *fd = -1;
         closeAutoFSNoWait(no_hang_fd);
         thread_set_errno(EACCES);
         return false;
@@ -154,20 +141,38 @@ __private_extern__ Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef u
         }
         *bytes = CFAllocatorAllocate(alloc, desiredLength, 0);
        if (__CFOASafe) __CFSetLastAllocationEventName(*bytes, "CFUtilities (file-bytes)");
-//     fcntl(fd, F_NOCACHE, 1);
-        if (read(fd, *bytes, desiredLength) < 0) {
+        //     fcntl(fd, F_NOCACHE, 1);
+        if (read(*fd, *bytes, desiredLength) < 0) {
             CFAllocatorDeallocate(alloc, *bytes);
-            close(fd);
-               closeAutoFSNoWait(no_hang_fd);
+            close(*fd);
+            *fd = -1;
+            closeAutoFSNoWait(no_hang_fd);
             return false;
         }
         *length = desiredLength;
     }
-    close(fd);
     closeAutoFSNoWait(no_hang_fd);
     return true;
 }
 
+__private_extern__ 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) {
+        close(fd);
+    }
+    return result;
+}
+__private_extern__ 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];
+    if (!CFURLGetFileSystemRepresentation(url, true, (uint8_t *)path, CFMaxPathSize)) {
+        return false;
+    }
+    return _CFReadBytesFromPath(alloc, (const char *)path, bytes, length, maxLength, extraOpenFlags);
+}
+
 __private_extern__ Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length) {
     int fd = -1;
     int mode;
@@ -348,7 +353,7 @@ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc
     FindClose(handle);
     pathBuf[pathLength] = '\0';
 
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
     uint8_t extBuff[CFMaxPathSize];
     int extBuffInteriorDotCount = 0; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :(
     
@@ -445,7 +450,7 @@ __private_extern__ CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc
             dirURL = CFURLCreateFromFileSystemRepresentation(alloc, (uint8_t *)dirPath, pathLength, true);
             releaseBase = true;
         }
-        if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN) {
+        if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN || dp->d_type == DT_LNK || dp->d_type == DT_WHT) {
             Boolean isDir = (dp->d_type == DT_DIR);
             if (!isDir) {
                 // Ugh; must stat.
@@ -601,13 +606,10 @@ __private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pa
 }
 
 
-// MF:!!! Should pull in the rest of the UniChar based path utils from Foundation.
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    #define UNIX_PATH_SEMANTICS
-#elif DEPLOYMENT_TARGET_WINDOWS
-    #define WINDOWS_PATH_SEMANTICS
+#if DEPLOYMENT_TARGET_WINDOWS
+#define WINDOWS_PATH_SEMANTICS
 #else
-#error Unknown platform
+#define UNIX_PATH_SEMANTICS
 #endif
 
 #if defined(WINDOWS_PATH_SEMANTICS)
@@ -636,6 +638,10 @@ __private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pa
     #define IS_SLASH(C)        ((C) == ':')
 #endif
 
+__private_extern__ UniChar _CFGetSlash(){
+    return CFPreferredSlash;
+}
+
 __private_extern__ Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length) {
     if (length < 1) {
         return false;
@@ -837,12 +843,4 @@ __private_extern__ CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars
     return ((0 < start) ? start : length);
 }
 
-#undef CF_OPENFLGS
-#undef UNIX_PATH_SEMANTICS
-#undef WINDOWS_PATH_SEMANTICS
-#undef HFS_PATH_SEMANTICS
-#undef CFPreferredSlash
-#undef HAS_DRIVE
-#undef HAS_NET
-#undef IS_SLASH
 
index 4094da4af1a4cf5a24db50086547a208f1a6cc72..3414ca33df7b6f7d32166366da08573e5bad7c16 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFICUConverters.c
-       Copyright (c) 2004-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -238,7 +238,7 @@ static CFIndex __CFStringEncodingConverterReleaseICUConverter(UConverter *conver
 #define MAX_BUFFER_SIZE (1000)
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#if (U_ICU_VERSION_MAJOR_NUM > 4) || ((U_ICU_VERSION_MAJOR_NUM == 4) && (U_ICU_VERSION_MINOR_NUM > 6))
+#if (U_ICU_VERSION_MAJOR_NUM > 49)
 #warning Unknown ICU version. Check binary compatibility issues for rdar://problem/6024743
 #endif
 #endif
index 0d6fa74f85612a4c3cb68df3bb97e2c15b30b1ed..cffc26cbd38e684b75066f478a2c03de371398b5 100644 (file)
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by Aki Inoue on 07/12/04.
- *  Copyright (c) 2007-2011, Apple Inc. All rights reserved.
+ *  Copyright (c) 2007-2012, Apple Inc. All rights reserved.
  *
  */
 
index 4c0c22e1469fa81ffa63e7e09d605e4a4dd79eac..dffc01683810a0a5f62ad55bd6fcb5fa717100cb 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFInternal.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 /*
@@ -87,18 +87,13 @@ CF_EXTERN_C_BEGIN
 #include <CoreFoundation/CFLogUtilities.h>
 #include <CoreFoundation/CFRuntime.h>
 #include <limits.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <xlocale.h>
 #include <unistd.h>
-#endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 #include <sys/time.h>
-#include <pthread.h>
 #include <signal.h>
 #endif
-#if DEPLOYMENT_TARGET_WINDOWS
 #include <pthread.h>
-#endif
 
 
 #if defined(__BIG_ENDIAN__)
@@ -123,16 +118,14 @@ CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void);
 
 CF_EXPORT CFStringRef _CFStringCreateHostName(void);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <CoreFoundation/CFRunLoop.h>
 CF_EXPORT void _CFMachPortInstallNotifyPort(CFRunLoopRef rl, CFStringRef mode);
 #endif
 
 __private_extern__ CFIndex __CFActiveProcessorCount();
 
-#if defined(__ppc__)
-    #define HALT do {asm __volatile__("trap"); kill(getpid(), 9); } while (0)
-#elif defined(__i386__) || defined(__x86_64__)
+#if defined(__i386__) || defined(__x86_64__)
     #if defined(__GNUC__)
         #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); } while (0)
     #elif defined(_MSC_VER)
@@ -141,9 +134,7 @@ __private_extern__ CFIndex __CFActiveProcessorCount();
         #error Compiler not supported
     #endif
 #endif
-#if defined(__arm__)
-    #define HALT do {asm __volatile__("bkpt 0xCF"); kill(getpid(), 9); } while (0)
-#endif
+
 
 #if defined(DEBUG)
     #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5)   \
@@ -284,6 +275,11 @@ extern CFTimeInterval __CFTSRToTimeInterval(SInt64 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);
 
 /* result is long long or int, depending on doLonglong
 */
@@ -293,12 +289,11 @@ extern Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, un
 
 extern const char *__CFgetenv(const char *n);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
-#define STACK_BUFFER_DECL(T, N, C) T N[C]
-#elif DEPLOYMENT_TARGET_WINDOWS
+// 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))
 #else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+#define STACK_BUFFER_DECL(T, N, C) T N[C]
 #endif
 
 
@@ -321,40 +316,28 @@ CF_EXPORT int __CFConstantStringClassReference[];
 
 /* CFNetwork also has a copy of the CONST_STRING_DECL macro (for use on platforms without constant string support in cc); please warn cfnetwork-core@group.apple.com of any necessary changes to this macro. -- REW, 1/28/2002 */
 
-#if __CF_BIG_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
+#if __CF_BIG_ENDIAN__
+
 #define CONST_STRING_DECL(S, V)                        \
 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
 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 ## __;
-#elif __CF_LITTLE_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
-#define CONST_STRING_DECL(S, V)                        \
-static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)V, sizeof(V) - 1}; \
-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 ## __;
-#elif DEPLOYMENT_TARGET_WINDOWS
+
+#elif __CF_LITTLE_ENDIAN__
+
 #define CONST_STRING_DECL(S, V)                        \
 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
 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 ## __;
-#endif // __BIG_ENDIAN__
-#endif // __CONSTANT_CFSTRINGS__
-
 
-/* Buffer size for file pathname */
-#if DEPLOYMENT_TARGET_WINDOWS
-    #define CFMaxPathSize ((CFIndex)262)
-    #define CFMaxPathLength ((CFIndex)260)
-#else
-    #define CFMaxPathSize ((CFIndex)1026)
-    #define CFMaxPathLength ((CFIndex)1024)
 #endif
 
+#endif // __CONSTANT_CFSTRINGS__
+
 CF_EXPORT bool __CFOASafe;
 CF_EXPORT void __CFSetLastAllocationEventName(void *ptr, const char *classname);
 
@@ -414,7 +397,7 @@ typedef OSSpinLock CFSpinLock_t;
     } \
     OSSpinLockTry(__lockp__); })
 
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
 typedef OSSpinLock CFSpinLock_t;
 
@@ -461,7 +444,7 @@ typedef int32_t CFSpinLock_t;
 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
 
 CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) {
-    while (__sync_val_compare_and_swap(lock, ~0, 0) != 0) {
+    while (__sync_val_compare_and_swap(lock, 0, ~0) != 0) {
        sleep(0);
     }
 }
@@ -472,7 +455,7 @@ CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) {
 }
 
 CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
-    return (__sync_val_compare_and_swap(lock, ~0, 0) == 0);
+    return (__sync_val_compare_and_swap(lock, 0, ~0) == 0);
 }
 
 #else
@@ -484,7 +467,7 @@ CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
 #endif
 
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 extern uint8_t __CF120293;
 extern uint8_t __CF120290;
 extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void);
@@ -505,11 +488,7 @@ extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNC
 #define HAS_FORKED() 0
 #endif
 
-#if DEPLOYMENT_TARGET_WINDOWS
 #include <errno.h>
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
-#include <sys/errno.h>
-#endif
 
 #define thread_errno() errno
 #define thread_set_errno(V) do {errno = (V);} while (0)
@@ -525,20 +504,16 @@ CF_EXPORT CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType);
 /* These functions all act on a c-strings which must be in the file system encoding. */
     
 CF_EXPORT Boolean _CFCreateDirectory(const char *path);
-#if DEPLOYMENT_TARGET_WINDOWS
-CF_EXPORT Boolean _CFCreateDirectoryWide(const wchar_t *path);
-#endif
 CF_EXPORT Boolean _CFRemoveDirectory(const char *path);
 CF_EXPORT Boolean _CFDeleteFile(const char *path);
 
-CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength);
+CF_EXPORT Boolean _CFReadBytesFromPathAndGetFD(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags, int *fd);
+CF_EXPORT Boolean _CFReadBytesFromPath(CFAllocatorRef alloc, const char *path, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags);
+CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength, int extraOpenFlags);
     /* resulting bytes are allocated from alloc which MUST be non-NULL. */
     /* maxLength of zero means the whole file.  Otherwise it sets a limit on the number of bytes read. */
 
 CF_EXPORT Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-CF_EXPORT Boolean _CFWriteBytesToFileWithAtomicity(CFURLRef url, const void *bytes, unsigned int length, SInt32 mode, Boolean atomic);
-#endif
 
 CF_EXPORT CFMutableArrayRef _CFContentsOfDirectory(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 */
@@ -559,6 +534,7 @@ CF_EXPORT SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Bo
 /* ==================== Simple path manipulation ==================== */
 /* These functions all act on a UniChar buffers. */
 
+CF_EXPORT UniChar _CFGetSlash();
 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);
@@ -584,7 +560,7 @@ CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex
 // to release (that's why this stuff is in CF*Internal*.h),
 // as can the definition of type info vs payload above.
 //
-#if defined(__x86_64__)
+#if __LP64__
 #define CF_IS_TAGGED_OBJ(PTR)  ((uintptr_t)(PTR) & 0x1)
 #define CF_TAGGED_OBJ_TYPE(PTR)        ((uintptr_t)(PTR) & 0xF)
 #else
@@ -594,14 +570,14 @@ CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex
  
 enum {
     kCFTaggedObjectID_Invalid = 0,
-    kCFTaggedObjectID_Undefined0 = (0 << 1) + 1,
-    kCFTaggedObjectID_Integer = (1 << 1) + 1,
+    kCFTaggedObjectID_Atom = (0 << 1) + 1,
+    kCFTaggedObjectID_Undefined3 = (1 << 1) + 1,
     kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
-    kCFTaggedObjectID_Undefined3 = (3 << 1) + 1,
-    kCFTaggedObjectID_Undefined4 = (4 << 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_DateTS = (7 << 1) + 1,
+    kCFTaggedObjectID_Undefined7 = (7 << 1) + 1,
 };
 
 
@@ -613,6 +589,7 @@ CF_INLINE uintptr_t __CFISAForTypeID(CFTypeID typeID) {
 }
 
 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;
@@ -634,45 +611,18 @@ CF_INLINE Boolean CF_IS_OBJC(CFTypeID typeID, const void *obj) {
     uintptr_t type_isa = (uintptr_t)(typeID < __CFRuntimeClassTableSize ? __CFRuntimeObjCClassTable[typeID] : 0);
     if (cfisa == type_isa) return false;
     return true;
+#else
+    return false;
+#endif
 }
 
-#define STUB_CF_OBJC 1
-
-#if STUB_CF_OBJC
-
-#define CF_IS_OBJC(typeID, obj)        (false)
-
-#define CF_OBJC_VOIDCALL0(obj, sel) do { } while (0)
-#define CF_OBJC_VOIDCALL1(obj, sel, a1) do { } while (0)
-#define CF_OBJC_VOIDCALL2(obj, sel, a1, a2) do { } while (0)
 
-#define CF_OBJC_CALL0(rettype, retvar, obj, sel) do { } while (0)
-#define CF_OBJC_CALL1(rettype, retvar, obj, sel, a1) do { } while (0)
-#define CF_OBJC_CALL2(rettype, retvar, obj, sel, a1, a2) do { } while (0)
-
-#define CF_OBJC_FUNCDISPATCH0(typeID, rettype, obj, sel) do { } while (0)
-#define CF_OBJC_FUNCDISPATCH1(typeID, rettype, obj, sel, a1) do { } while (0)
-#define CF_OBJC_FUNCDISPATCH2(typeID, rettype, obj, sel, a1, a2) do { } while (0)
-#define CF_OBJC_FUNCDISPATCH3(typeID, rettype, obj, sel, a1, a2, a3) do { } while (0)
-#define CF_OBJC_FUNCDISPATCH4(typeID, rettype, obj, sel, a1, a2, a3, a4) do { } while (0)
-#define CF_OBJC_FUNCDISPATCH5(typeID, rettype, obj, sel, a1, a2, a3, a4, a5) do { } while (0)
-
-#endif // STUB_CF_OBJC
+#define CF_OBJC_FUNCDISPATCHV(typeID, obj, ...) do { } while (0)
+#define CF_OBJC_CALLV(obj, ...) (0)
 
 
 /* See comments in CFBase.c
 */
-#if SUPPORT_CFM
-extern void __CF_FAULT_CALLBACK(void **ptr);
-extern void *__CF_INVOKE_CALLBACK(void *, ...);
-#define FAULT_CALLBACK(V) __CF_FAULT_CALLBACK(V)
-#define INVOKE_CALLBACK1(P, A) (__CF_INVOKE_CALLBACK(P, A))
-#define INVOKE_CALLBACK2(P, A, B) (__CF_INVOKE_CALLBACK(P, A, B))
-#define INVOKE_CALLBACK3(P, A, B, C) (__CF_INVOKE_CALLBACK(P, A, B, C))
-#define INVOKE_CALLBACK4(P, A, B, C, D) (__CF_INVOKE_CALLBACK(P, A, B, C, D))
-#define INVOKE_CALLBACK5(P, A, B, C, D, E) (__CF_INVOKE_CALLBACK(P, A, B, C, D, E))
-#define UNFAULT_CALLBACK(V) do { V = (void *)((uintptr_t)V & ~0x3); } while (0)
-#else
 #define FAULT_CALLBACK(V)
 #define INVOKE_CALLBACK1(P, A) (P)(A)
 #define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
@@ -680,7 +630,6 @@ extern void *__CF_INVOKE_CALLBACK(void *, ...);
 #define INVOKE_CALLBACK4(P, A, B, C, D) (P)(A, B, C, D)
 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (P)(A, B, C, D, E)
 #define UNFAULT_CALLBACK(V) do { } while (0)
-#endif
 
 /* For the support of functionality which needs CarbonCore or other frameworks */
 // These macros define an upcall or weak "symbol-lookup" wrapper function.
@@ -727,17 +676,30 @@ static R __CFNetwork_ ## N P {                                  \
 }
 
 #else
-
 #define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...)
 #define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, ...)
-
 #endif
 
-
-#if !defined(DEFINE_WEAK_CARBONCORE_FUNC)
 #define DEFINE_WEAK_CARBONCORE_FUNC(R, N, P, A, ...)
-#endif
-#if !defined(DEFINE_WEAK_CORESERVICESINTERNAL_FUNC)
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+
+extern void *__CFLookupCoreServicesInternalFunction(const char *name);
+
+#define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...)              \
+    static R __CFCoreServicesInternal_ ## N P {                             \
+        typedef R (*dyfuncptr)P;                                            \
+        static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0);               \
+        if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) {                         \
+            dyfunc = (dyfuncptr)__CFLookupCoreServicesInternalFunction(#N); \
+        }                                                                   \
+        if (dyfunc) {                                                       \
+            return dyfunc A ;                                               \
+        }                                                                   \
+        return __VA_ARGS__ ;                                                \
+    }
+
+#else
 #define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...)
 #endif
 
@@ -760,15 +722,6 @@ CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) {  // !!! Use with CF typ
     return *(CFAllocatorRef *)((char *)cf - sizeof(CFAllocatorRef));
 }
 
-
-#if DEPLOYMENT_TARGET_WINDOWS
-__private_extern__ const wchar_t *_CFDLLPath(void);
-__private_extern__ void __CFStringCleanup(void);
-__private_extern__ void __CFSocketCleanup(void);
-__private_extern__ void __CFUniCharCleanup(void);
-__private_extern__ void __CFStreamCleanup(void);
-#endif
-
 /* !!! Avoid #importing objc.h; e.g. converting this to a .m file */
 struct __objcFastEnumerationStateEquivalent {
     unsigned long state;
@@ -777,6 +730,57 @@ struct __objcFastEnumerationStateEquivalent {
     unsigned long extra[5];
 };
 
+#pragma mark -
+#pragma mark Windows Compatability
+
+// Need to use the _O_BINARY flag on Windows to get the correct behavior
+#if DEPLOYMENT_TARGET_WINDOWS
+#define CF_OPENFLGS    (_O_BINARY|_O_NOINHERIT)
+#else
+#define CF_OPENFLGS    (0)
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+
+// These are replacements for pthread calls on Windows
+CF_EXPORT int _NS_pthread_main_np();
+CF_EXPORT int _NS_pthread_setspecific(pthread_key_t key, const void *val);
+CF_EXPORT void* _NS_pthread_getspecific(pthread_key_t key);
+CF_EXPORT int _NS_pthread_key_init_np(int key, void (*destructor)(void *));
+CF_EXPORT void _NS_pthread_setname_np(const char *name);
+
+// map use of pthread_set/getspecific to internal API
+#define pthread_setspecific _NS_pthread_setspecific
+#define pthread_getspecific _NS_pthread_getspecific
+#define pthread_key_init_np _NS_pthread_key_init_np
+#define pthread_main_np _NS_pthread_main_np
+#define pthread_setname_np _NS_pthread_setname_np
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+// replacement for DISPATCH_QUEUE_OVERCOMMIT until we get a bug fix in dispatch on Windows
+// <rdar://problem/7923891> dispatch on Windows: Need queue_private.h
+#define DISPATCH_QUEUE_OVERCOMMIT 2
+#endif
+
+#if DEPLOYMENT_TARGET_WINDOWS
+__private_extern__ const wchar_t *_CFDLLPath(void);
+#endif
+
+/* Buffer size for file pathname */
+#if DEPLOYMENT_TARGET_WINDOWS
+#define CFMaxPathSize ((CFIndex)262)
+#define CFMaxPathLength ((CFIndex)260)
+#define PATH_SEP '\\'
+#define PATH_SEP_STR CFSTR("\\")
+#define PATH_MAX MAX_PATH
+#else
+#define CFMaxPathSize ((CFIndex)1026)
+#define CFMaxPathLength ((CFIndex)1024)
+#define PATH_SEP '/'
+#define PATH_SEP_STR CFSTR("/")
+#endif
+
 CF_EXTERN_C_END
 
 #endif /* ! __COREFOUNDATION_CFINTERNAL__ */
index d8d356cfed9fcbd0fc5e96afa108ebfe6ba9f5fa..d6eb54d140bfe6dba89f295d01a3fa09d2ff3958 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*  CFLocale.c
-    Copyright (c) 2002-2011, Apple Inc. All rights reserved.
+    Copyright (c) 2002-2012, Apple Inc. All rights reserved.
     Responsibility: David Smith
 */
 
@@ -37,6 +37,7 @@
 #include <CoreFoundation/CFNumber.h>
 #include "CFInternal.h"
 #include "CFLocaleInternal.h"
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #include <unicode/uloc.h>           // ICU locales
 #include <unicode/ulocdata.h>       // ICU locale data
 #include <unicode/ucal.h>
 #include <unicode/uset.h>           // ICU Unicode sets
 #include <unicode/putil.h>          // ICU low-level utilities
 #include <unicode/umsg.h>           // ICU message formatting
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#include <unicode/ucol.h>
+#endif
 #include <CoreFoundation/CFNumberFormatter.h>
 #include <stdlib.h>
 #include <stdio.h>
-#include <unicode/ucol.h>
-#elif DEPLOYMENT_TARGET_WINDOWS
-#include <stdio.h>
-#endif
 #include <string.h>
 
+#if DEPLOYMENT_TARGET_EMBEDDED_MINI
+// Some compatability definitions
+#define ULOC_FULLNAME_CAPACITY 157
+#define ULOC_KEYWORD_AND_VALUES_CAPACITY 100
+
+//typedef long UErrorCode;
+//#define U_BUFFER_OVERFLOW_ERROR 15
+//#define U_ZERO_ERROR 0
+//
+//typedef uint16_t UChar;
+#endif
+
+
 CONST_STRING_DECL(kCFLocaleCurrentLocaleDidChangeNotification, "kCFLocaleCurrentLocaleDidChangeNotification")
 
 static const char *kCalendarKeyword = "calendar";
@@ -282,23 +293,45 @@ static CFLocaleRef __CFLocaleCurrent = NULL;
 
 #if DEPLOYMENT_TARGET_MACOSX
 #define FALLBACK_LOCALE_NAME CFSTR("")
-#elif DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define FALLBACK_LOCALE_NAME CFSTR("en_US")
 #elif DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #define FALLBACK_LOCALE_NAME CFSTR("en_US")
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
 CFLocaleRef CFLocaleCopyCurrent(void) {
 
+    CFStringRef name = NULL, 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 0 // DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+    name = (CFStringRef)CFPreferencesCopyAppValue(CFSTR("AppleLocale"), kCFPreferencesCurrentApplication);
+#endif
+    if (name && (CFStringGetTypeID() == CFGetTypeID(name))) {
+        ident = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, name);
+    }
+    if (name) CFRelease(name);
+    CFLocaleRef oldLocale = NULL;
     __CFLocaleLockGlobal();
     if (__CFLocaleCurrent) {
-       CFRetain(__CFLocaleCurrent);
-       __CFLocaleUnlockGlobal();
-       return __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);
+    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;
@@ -332,7 +365,7 @@ CFLocaleRef CFLocaleCopyCurrent(void) {
 }
 
 __private_extern__ CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale) {
-    CF_OBJC_FUNCDISPATCH0(CFLocaleGetTypeID(), CFDictionaryRef, locale, "_prefs");
+    CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFDictionaryRef, (NSLocale *)locale, _prefs);
     return locale->_prefs;
 }
 
@@ -390,7 +423,7 @@ CFLocaleRef CFLocaleCreateCopy(CFAllocatorRef allocator, CFLocaleRef locale) {
 }
 
 CFStringRef CFLocaleGetIdentifier(CFLocaleRef locale) {
-    CF_OBJC_FUNCDISPATCH0(CFLocaleGetTypeID(), CFStringRef, locale, "localeIdentifier");
+    CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFStringRef, (NSLocale *)locale, localeIdentifier);
     return locale->_identifier;
 }
 
@@ -404,7 +437,7 @@ CFTypeRef CFLocaleGetValue(CFLocaleRef locale, CFStringRef key) {
        }
     }
 #endif
-    CF_OBJC_FUNCDISPATCH1(CFLocaleGetTypeID(), CFTypeRef, locale, "objectForKey:", key);
+    CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFTypeRef, (NSLocale *)locale, objectForKey:(id)key);
     CFIndex idx, slot = -1;
     for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) {
        if (__CFLocaleKeyTable[idx].key == key) {
@@ -449,7 +482,7 @@ CFTypeRef CFLocaleGetValue(CFLocaleRef locale, CFStringRef key) {
 }
 
 CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, CFStringRef key, CFStringRef value) {
-    CF_OBJC_FUNCDISPATCH2(CFLocaleGetTypeID(), CFStringRef, displayLocale, "_copyDisplayNameForKey:value:", key, value);
+    CF_OBJC_FUNCDISPATCHV(CFLocaleGetTypeID(), CFStringRef, (NSLocale *)displayLocale, _copyDisplayNameForKey:(id)key value:(id)value);
     CFIndex idx, slot = -1;
     for (idx = 0; idx < __kCFLocaleKeyTableCount; idx++) {
        if (__CFLocaleKeyTable[idx].key == key) {
@@ -478,12 +511,14 @@ CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, C
         }
 
         // We could not find a result using the requested language. Fall back through all preferred languages.
-        CFArrayRef langPref;
+        CFArrayRef langPref = NULL;
        if (displayLocale->_prefs) {
            langPref = (CFArrayRef)CFDictionaryGetValue(displayLocale->_prefs, CFSTR("AppleLanguages"));
            if (langPref) CFRetain(langPref);
        } else {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
            langPref = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication);
+#endif
        }
         if (langPref != NULL) {
             CFIndex count = CFArrayGetCount(langPref);
@@ -506,6 +541,7 @@ CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, C
 }
 
 CFArrayRef CFLocaleCopyAvailableLocaleIdentifiers(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     int32_t locale, localeCount = uloc_countAvailable();
     CFMutableSetRef working = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeSetCallBacks);
     for (locale = 0; locale < localeCount; ++locale) {
@@ -521,8 +557,12 @@ CFArrayRef CFLocaleCopyAvailableLocaleIdentifiers(void) {
     CFArrayRef result = CFArrayCreate(kCFAllocatorSystemDefault, buffer, cnt, &kCFTypeArrayCallBacks);
     CFRelease(working);
     return result;
+#else
+    return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
+#endif
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 static CFArrayRef __CFLocaleCopyCStringsAsArray(const char* const* p) {
     CFMutableArrayRef working = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
     for (; *p; ++p) {
@@ -559,34 +599,52 @@ static CFArrayRef __CFLocaleCopyUEnumerationAsArray(UEnumeration *enumer, UError
     }
     return result;
 }
+#endif
 
 CFArrayRef CFLocaleCopyISOLanguageCodes(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     const char* const* p = uloc_getISOLanguages();
     return __CFLocaleCopyCStringsAsArray(p);
+#else
+    return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
+#endif
 }
 
 CFArrayRef CFLocaleCopyISOCountryCodes(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     const char* const* p = uloc_getISOCountries();
     return __CFLocaleCopyCStringsAsArray(p);
+#else
+    return CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
+#endif
 }
 
 CFArrayRef CFLocaleCopyISOCurrencyCodes(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     UErrorCode icuStatus = U_ZERO_ERROR;
     UEnumeration *enumer = ucurr_openISOCurrencies(UCURR_ALL, &icuStatus);
     CFArrayRef result = __CFLocaleCopyUEnumerationAsArray(enumer, &icuStatus);
     uenum_close(enumer);
+#else
+    CFArrayRef result = CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
+#endif
     return result;
 }
 
 CFArrayRef CFLocaleCopyCommonISOCurrencyCodes(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     UErrorCode icuStatus = U_ZERO_ERROR;
     UEnumeration *enumer = ucurr_openISOCurrencies(UCURR_COMMON|UCURR_NON_DEPRECATED, &icuStatus);
     CFArrayRef result = __CFLocaleCopyUEnumerationAsArray(enumer, &icuStatus);
     uenum_close(enumer);
+#else
+    CFArrayRef result = CFArrayCreate(kCFAllocatorSystemDefault, NULL, 0, &kCFTypeArrayCallBacks);
+#endif
     return result;
 }
 
 CFStringRef CFLocaleCreateLocaleIdentifierFromWindowsLocaleCode(CFAllocatorRef allocator, uint32_t lcid) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char buffer[kMaxICUNameSize];
     UErrorCode status = U_ZERO_ERROR;
     int32_t ret = uloc_getLocaleForLCID(lcid, buffer, kMaxICUNameSize, &status);
@@ -595,19 +653,27 @@ CFStringRef CFLocaleCreateLocaleIdentifierFromWindowsLocaleCode(CFAllocatorRef a
     CFStringRef ident = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, str);
     CFRelease(str);
     return ident;
+#else
+    return CFSTR("");
+#endif
 }
 
 uint32_t CFLocaleGetWindowsLocaleCodeFromLocaleIdentifier(CFStringRef localeIdentifier) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     CFStringRef ident = CFLocaleCreateCanonicalLocaleIdentifierFromString(kCFAllocatorSystemDefault, localeIdentifier);
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
-    Boolean b = CFStringGetCString(ident, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII);
-    CFRelease(ident);
+    Boolean b = ident ? CFStringGetCString(ident, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII) : false;
+    if (ident) CFRelease(ident);
     return b ? uloc_getLCID(localeID) : 0;
+#else
+    return 0;
+#endif
 }
 
 CFLocaleLanguageDirection CFLocaleGetLanguageCharacterDirection(CFStringRef isoLangCode) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
-    Boolean b = CFStringGetCString(isoLangCode, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII);
+    Boolean b = isoLangCode ? CFStringGetCString(isoLangCode, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII) : false;
     CFLocaleLanguageDirection dir;
     UErrorCode status = U_ZERO_ERROR;
     ULayoutType idir = b ? uloc_getCharacterOrientation(localeID, &status) : ULOC_LAYOUT_UNKNOWN;
@@ -619,11 +685,15 @@ CFLocaleLanguageDirection CFLocaleGetLanguageCharacterDirection(CFStringRef isoL
     default: dir = kCFLocaleLanguageDirectionUnknown; break;
     }
     return dir;
+#else
+    return kCFLocaleLanguageDirectionLeftToRight;
+#endif
 }
 
 CFLocaleLanguageDirection CFLocaleGetLanguageLineDirection(CFStringRef isoLangCode) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
-    Boolean b = CFStringGetCString(isoLangCode, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII);
+    Boolean b = isoLangCode ? CFStringGetCString(isoLangCode, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII) : false;
     CFLocaleLanguageDirection dir;
     UErrorCode status = U_ZERO_ERROR;
     ULayoutType idir = b ? uloc_getLineOrientation(localeID, &status) : ULOC_LAYOUT_UNKNOWN;
@@ -635,10 +705,14 @@ CFLocaleLanguageDirection CFLocaleGetLanguageLineDirection(CFStringRef isoLangCo
     default: dir = kCFLocaleLanguageDirectionUnknown; break;
     }
     return dir;
+#else
+    return kCFLocaleLanguageDirectionLeftToRight;
+#endif
 }
 
 CFArrayRef CFLocaleCopyPreferredLanguages(void) {
     CFMutableArrayRef newArray = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
     CFArrayRef languagesArray = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication);
     if (languagesArray && (CFArrayGetTypeID() == CFGetTypeID(languagesArray))) {
        for (CFIndex idx = 0, cnt = CFArrayGetCount(languagesArray); idx < cnt; idx++) {
@@ -651,6 +725,7 @@ CFArrayRef CFLocaleCopyPreferredLanguages(void) {
        }
     }
     if (languagesArray)        CFRelease(languagesArray);
+#endif
     return newArray;
 }
 
@@ -686,6 +761,7 @@ static bool __CFLocaleCopyCodes(CFLocaleRef locale, bool user, CFTypeRef *cf, CF
     return false;
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 CFCharacterSetRef _CFCreateCharacterSetFromUSet(USet *set) {
     UErrorCode icuErr = U_ZERO_ERROR;
     CFMutableCharacterSetRef working = CFCharacterSetCreateMutable(NULL);
@@ -738,9 +814,10 @@ CFCharacterSetRef _CFCreateCharacterSetFromUSet(USet *set) {
     CFRelease(working);
     return result;
 }
-
+#endif
 
 static bool __CFLocaleCopyExemplarCharSet(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
     if (CFStringGetCString(locale->_identifier, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII)) {
         UErrorCode icuStatus = U_ZERO_ERROR;
@@ -755,11 +832,13 @@ static bool __CFLocaleCopyExemplarCharSet(CFLocaleRef locale, bool user, CFTypeR
         uset_close(set);
         return (*cf != NULL);
     }
+#endif
     return false;
 }
 
 static bool __CFLocaleCopyICUKeyword(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context, const char *keyword)
 {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
     if (CFStringGetCString(locale->_identifier, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII))
     {
@@ -771,11 +850,13 @@ static bool __CFLocaleCopyICUKeyword(CFLocaleRef locale, bool user, CFTypeRef *c
             return true;
         }
     }
+#endif
     *cf = NULL;
     return false;
 }
 
 static bool __CFLocaleCopyICUCalendarID(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context, const char *keyword) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char localeID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
     if (CFStringGetCString(locale->_identifier, localeID, sizeof(localeID)/sizeof(char), kCFStringEncodingASCII)) {
         UErrorCode icuStatus = U_ZERO_ERROR;
@@ -789,6 +870,7 @@ static bool __CFLocaleCopyICUCalendarID(CFLocaleRef locale, bool user, CFTypeRef
         }
        uenum_close(en);
     }
+#endif
     *cf = NULL;
     return false;
 }
@@ -853,6 +935,7 @@ static bool __CFLocaleCopyCalendarID(CFLocaleRef locale, bool user, CFTypeRef *c
 }
 
 static bool __CFLocaleCopyCalendar(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (__CFLocaleCopyCalendarID(locale, user, cf, context)) {
        CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorSystemDefault, (CFStringRef)*cf);
        CFCalendarSetLocale(calendar, locale);
@@ -881,10 +964,12 @@ static bool __CFLocaleCopyCalendar(CFLocaleRef locale, bool user, CFTypeRef *cf,
        *cf = calendar;
        return true;
     }
+#endif
     return false;
 }
 
 static bool __CFLocaleCopyDelimiter(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     ULocaleDataDelimiterType type = (ULocaleDataDelimiterType)0;
     if (context == kCFLocaleQuotationBeginDelimiterKey) {
        type = ULOCDATA_QUOTATION_START;
@@ -914,6 +999,14 @@ static bool __CFLocaleCopyDelimiter(CFLocaleRef locale, bool user, CFTypeRef *cf
 
     *cf = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)buffer, len);
     return (*cf != NULL);
+#else
+    if (context == kCFLocaleQuotationBeginDelimiterKey || context == kCFLocaleQuotationEndDelimiterKey || context == kCFLocaleAlternateQuotationBeginDelimiterKey || context == kCFLocaleAlternateQuotationEndDelimiterKey) {
+       *cf = CFRetain(CFSTR("\""));
+        return true;
+    } else {
+        return false;
+    }
+#endif
 }
 
 static bool __CFLocaleCopyCollationID(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
@@ -922,7 +1015,7 @@ static bool __CFLocaleCopyCollationID(CFLocaleRef locale, bool user, CFTypeRef *
 
 static bool __CFLocaleCopyCollatorID(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
     CFStringRef canonLocaleCFStr = NULL;
-    if (user) {
+    if (user && locale->_prefs) {
        CFStringRef pref = (CFStringRef)CFDictionaryGetValue(locale->_prefs, CFSTR("AppleCollationOrder"));
        if (pref) {
            // Canonicalize pref string in case it's not in the canonical format.
@@ -948,6 +1041,7 @@ static bool __CFLocaleCopyCollatorID(CFLocaleRef locale, bool user, CFTypeRef *c
 }
 
 static bool __CFLocaleCopyUsesMetric(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     bool us = false;    // Default is Metric
     bool done = false;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
@@ -981,6 +1075,10 @@ static bool __CFLocaleCopyUsesMetric(CFLocaleRef locale, bool user, CFTypeRef *c
         us = false;
     *cf = us ? CFRetain(kCFBooleanFalse) : CFRetain(kCFBooleanTrue);
     return true;
+#else
+    *cf = CFRetain(kCFBooleanFalse);
+    return true;
+#endif
 }
 
 static bool __CFLocaleCopyMeasurementSystem(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
@@ -995,13 +1093,10 @@ static bool __CFLocaleCopyMeasurementSystem(CFLocaleRef locale, bool user, CFTyp
 
 static bool __CFLocaleCopyNumberFormat(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
     CFStringRef str = NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorSystemDefault, locale, kCFNumberFormatterDecimalStyle);
-    str = nf ? CFNumberFormatterCopyProperty(nf, context) : NULL;
+    str = nf ? (CFStringRef)CFNumberFormatterCopyProperty(nf, context) : NULL;
     if (nf) CFRelease(nf);
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     if (str) {
        *cf = str;
@@ -1014,13 +1109,10 @@ static bool __CFLocaleCopyNumberFormat(CFLocaleRef locale, bool user, CFTypeRef
 // so we have to have another routine here which creates a Currency number formatter.
 static bool __CFLocaleCopyNumberFormat2(CFLocaleRef locale, bool user, CFTypeRef *cf, CFStringRef context) {
     CFStringRef str = NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     CFNumberFormatterRef nf = CFNumberFormatterCreate(kCFAllocatorSystemDefault, locale, kCFNumberFormatterCurrencyStyle);
-    str = nf ? CFNumberFormatterCopyProperty(nf, context) : NULL;
+    str = nf ? (CFStringRef)CFNumberFormatterCopyProperty(nf, context) : NULL;
     if (nf) CFRelease(nf);
-#elif DEPLOYMENT_TARGET_WINDOWS
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     if (str) {
        *cf = str;
@@ -1029,6 +1121,7 @@ static bool __CFLocaleCopyNumberFormat2(CFLocaleRef locale, bool user, CFTypeRef
     return false;
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 typedef int32_t (*__CFICUFunction)(const char *, const char *, UChar *, int32_t, UErrorCode *);
 
 static bool __CFLocaleICUName(const char *locale, const char *valLocale, CFStringRef *out, __CFICUFunction icu) {
@@ -1097,8 +1190,10 @@ static bool __CFLocaleICUCurrencyName(const char *locale, const char *value, UCu
     *out = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)name, size);
     return (*out != NULL);
 }
+#endif
 
 static bool __CFLocaleFullName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     UErrorCode icuStatus = U_ZERO_ERROR;
     int32_t size;
     UChar name[kMaxICUNameSize];
@@ -1124,13 +1219,23 @@ static bool __CFLocaleFullName(const char *locale, const char *value, CFStringRe
     // This locale is OK, so use the result.
     *out = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)name, size);
     return (*out != NULL);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleLanguageName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     return __CFLocaleICUName(locale, value, out, uloc_getDisplayLanguage);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleCountryName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     // Need to make a fake locale ID
     char lid[ULOC_FULLNAME_CAPACITY];
     if (strlen(value) < sizeof(lid) - 3) {
@@ -1139,9 +1244,14 @@ static bool __CFLocaleCountryName(const char *locale, const char *value, CFStrin
         return __CFLocaleICUName(locale, lid, out, uloc_getDisplayCountry);
     }
     return false;
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleScriptName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     // Need to make a fake locale ID
     char lid[ULOC_FULLNAME_CAPACITY];
     if (strlen(value) == 4) {
@@ -1151,9 +1261,14 @@ static bool __CFLocaleScriptName(const char *locale, const char *value, CFString
         return __CFLocaleICUName(locale, lid, out, uloc_getDisplayScript);
     }
     return false;
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleVariantName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     // Need to make a fake locale ID
     char lid[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
     if (strlen(value) < sizeof(lid) - 6) {
@@ -1162,22 +1277,46 @@ static bool __CFLocaleVariantName(const char *locale, const char *value, CFStrin
         return __CFLocaleICUName(locale, lid, out, uloc_getDisplayVariant);
     }
     return false;
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleCalendarName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     return __CFLocaleICUKeywordValueName(locale, value, kCalendarKeyword, out);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleCollationName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     return __CFLocaleICUKeywordValueName(locale, value, kCollationKeyword, out);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleCurrencyShortName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     return __CFLocaleICUCurrencyName(locale, value, UCURR_SYMBOL_NAME, out);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleCurrencyFullName(const char *locale, const char *value, CFStringRef *out) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     return __CFLocaleICUCurrencyName(locale, value, UCURR_LONG_NAME, out);
+#else
+    *out = CFRetain(CFSTR("(none)"));
+    return true;
+#endif
 }
 
 static bool __CFLocaleNoName(const char *locale, const char *value, CFStringRef *out) {
index ef192a3fcae0364660f84a894cc8d9b5c7224265..3f575fc4611be8cf7b33e6181daa147d9f23c6e1 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFLocale.h
-       Copyright (c) 2002-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFLOCALE__)
@@ -32,6 +32,7 @@
 #include <CoreFoundation/CFArray.h>
 #include <CoreFoundation/CFDictionary.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef const struct __CFLocale *CFLocaleRef;
@@ -108,14 +109,13 @@ CF_EXPORT
 uint32_t CFLocaleGetWindowsLocaleCodeFromLocaleIdentifier(CFStringRef localeIdentifier) CF_AVAILABLE(10_6, 4_0);
        // Map a locale identifier to a Windows LCID.
 
-enum {
+typedef CF_ENUM(CFIndex, CFLocaleLanguageDirection) {
     kCFLocaleLanguageDirectionUnknown = 0,
     kCFLocaleLanguageDirectionLeftToRight = 1,
     kCFLocaleLanguageDirectionRightToLeft = 2,
     kCFLocaleLanguageDirectionTopToBottom = 3,
     kCFLocaleLanguageDirectionBottomToTop = 4
 };
-typedef CFIndex CFLocaleLanguageDirection;
 
 CF_EXPORT
 CFLocaleLanguageDirection CFLocaleGetLanguageCharacterDirection(CFStringRef isoLangCode) CF_AVAILABLE(10_6, 4_0);
@@ -208,6 +208,7 @@ CF_EXPORT const CFStringRef kCFIndianCalendar CF_AVAILABLE(10_6, 4_0);
 CF_EXPORT const CFStringRef kCFISO8601Calendar CF_AVAILABLE(10_6, 4_0);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFLOCALE__ */
 
index 8b81a057be2f64fe40034ad1b5f180ac2cbd0c0b..9da7ecda6425eed5b443958bc15c4d73a03d8a9f 100644 (file)
@@ -23,7 +23,7 @@
 
 /*
     CFLocaleIdentifier.c
-       Copyright (c) 2002-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
     Responsibility: David Smith
     
     CFLocaleIdentifier.c defines
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #include <unicode/uloc.h>
+#else
+#define ULOC_KEYWORD_SEPARATOR '@'
+#define ULOC_FULLNAME_CAPACITY 56
+#define ULOC_KEYWORD_AND_VALUES_CAPACITY 100
+#endif
 #include "CFInternal.h"
 #include "CFLocaleInternal.h"
 
@@ -1369,6 +1375,7 @@ static void _UpdateFullLocaleString(char inLocaleString[], int locStringMaxLen,
     // If so, copy the keywords to varKeyValueString and delete the variant tag
     // from the original string (but don't otherwise use the ICU canonicalization).
     varKeyValueString[0] = 0;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (variantTag) {
                UErrorCode      icuStatus;
                int                     icuCanonStringLen;
@@ -1397,6 +1404,7 @@ static void _UpdateFullLocaleString(char inLocaleString[], int locStringMaxLen,
                *varKeyValueStringPtr = 0;
                }
     }
+#endif
     
     // 4. Handle special cases of updating region codes, or updating language codes based on
     // region code.
@@ -1494,6 +1502,7 @@ static void _GetKeyValueString(char inLocaleString[], char keyValueString[]) {
 }
 
 static void _AppendKeyValueString(char inLocaleString[], int locStringMaxLen, char keyValueString[]) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
        if (keyValueString[0] != 0) {
                UErrorCode              uerr = U_ZERO_ERROR;
                UEnumeration *  uenum = uloc_openKeywords(keyValueString, &uerr);
@@ -1512,6 +1521,7 @@ static void _AppendKeyValueString(char inLocaleString[], int locStringMaxLen, ch
                        uenum_close(uenum);
                }
        }
+#endif
 }
 
 // __private_extern__ CFStringRef _CFLocaleCreateCanonicalLanguageIdentifierForCFBundle(CFAllocatorRef allocator, CFStringRef localeIdentifier) {}
@@ -1711,9 +1721,12 @@ SPI:  CFLocaleGetLanguageRegionEncodingForLocaleIdentifier gets the appropriate
  preferred localization in the current context (this function returns NO for a NULL localeIdentifier); and in this function
  langCode, regCode, and scriptCode are all SInt16* (not SInt32* like the equivalent parameters in CFBundleGetLocalizationInfoForLocalization).
 */
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 static int CompareLocaleToLegacyCodesEntries( const void *entry1, const void *entry2 );
+#endif
 
 Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeIdentifier, LangCode *langCode, RegionCode *regCode, ScriptCode *scriptCode, CFStringEncoding *stringEncoding) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
        Boolean         returnValue = false;
        CFStringRef     canonicalIdentifier = CFLocaleCreateCanonicalLocaleIdentifierFromString(NULL, localeIdentifier);
        if (canonicalIdentifier) {
@@ -1786,23 +1799,30 @@ Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeI
                CFRelease(canonicalIdentifier);
        }
        return returnValue;
+#else
+    return false;
+#endif
 }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 static int CompareLocaleToLegacyCodesEntries( const void *entry1, const void *entry2 ) {
        const char *    localeString1 = ((const LocaleToLegacyCodes *)entry1)->locale;
        const char *    localeString2 = ((const LocaleToLegacyCodes *)entry2)->locale;
        return strcmp(localeString1, localeString2);
 }
-
+#endif
 
 CFDictionaryRef CFLocaleCreateComponentsFromLocaleIdentifier(CFAllocatorRef allocator, CFStringRef localeID) {
+    CFMutableDictionaryRef working = CFDictionaryCreateMutable(allocator, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     char cLocaleID[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
     char buffer[ULOC_FULLNAME_CAPACITY+ULOC_KEYWORD_AND_VALUES_CAPACITY];
-    CFMutableDictionaryRef working = CFDictionaryCreateMutable(allocator, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
 
     UErrorCode icuStatus = U_ZERO_ERROR;
     int32_t length = 0;
-    
+
+    if (!localeID) goto out;
+
     // Extract the C string locale ID, for ICU
     CFIndex outBytes = 0;
     CFStringGetBytes(localeID, CFRangeMake(0, CFStringGetLength(localeID)), kCFStringEncodingASCII, (UInt8) '?', true, (unsigned char *)cLocaleID, sizeof(cLocaleID)/sizeof(char) - 1, &outBytes);
@@ -1869,6 +1889,8 @@ CFDictionaryRef CFLocaleCreateComponentsFromLocaleIdentifier(CFAllocatorRef allo
     }
     uenum_close(iter);
     
+    out:;
+#endif
     // Convert to an immutable dictionary and return
     CFDictionaryRef result = CFDictionaryCreateCopy(allocator, working);
     CFRelease(working);
@@ -1887,6 +1909,8 @@ static char *__CStringFromString(CFStringRef str) {
 }
 
 CFStringRef CFLocaleCreateLocaleIdentifierFromComponents(CFAllocatorRef allocator, CFDictionaryRef dictionary) {
+    if (!dictionary) return NULL;
+
     CFIndex cnt = CFDictionaryGetCount(dictionary);
     STACK_BUFFER_DECL(CFStringRef, values, cnt);
     STACK_BUFFER_DECL(CFStringRef, keys, cnt);
@@ -1920,6 +1944,7 @@ CFStringRef CFLocaleCreateLocaleIdentifierFromComponents(CFAllocatorRef allocato
     free(variant);
     free(buf1);
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     for (CFIndex idx = 0; idx < cnt; idx++) {
        if (keys[idx]) {
            char *key = __CStringFromString(keys[idx]);
@@ -1943,7 +1968,8 @@ CFStringRef CFLocaleCreateLocaleIdentifierFromComponents(CFAllocatorRef allocato
            free(value);
        }
     }
-
+#endif
+    
     return CFStringCreateWithCString(allocator, cLocaleID, kCFStringEncodingASCII);
 }
 
index edb0ece72cfd13cb41f9de6082b63ab940c87a38..c1b5b982be51a94e865950affa4abcbd963c7c6b 100644 (file)
@@ -23,7 +23,7 @@
 
 /*     
  CFLocaleInternal.h
- Copyright (c) 2008-2011, Apple Inc. All rights reserved.
+ Copyright (c) 2008-2012, Apple Inc. All rights reserved.
  */
 
 /*
@@ -65,6 +65,7 @@ CF_EXPORT CFStringRef const kCFDateFormatterIsLenientKey;
 CF_EXPORT CFStringRef const kCFDateFormatterLongEraSymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterMonthSymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterPMSymbolKey;
+CF_EXPORT CFStringRef const kCFDateFormatterAmbiguousYearStrategyKey;
 CF_EXPORT CFStringRef const kCFDateFormatterQuarterSymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterShortMonthSymbolsKey;
 CF_EXPORT CFStringRef const kCFDateFormatterShortQuarterSymbolsKey;
index 5c6b9c34830f36c396aa900bd5f76716cf196194..425c9af74da8095c4efd573c80ed1b0e0a40f744 100644 (file)
  */
 
 /*     CFLocaleKeys.c
-       Copyright (c) 2008-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
-#include <CoreFoundation/CFInternal.h>
+#include "CFInternal.h"
 
 CONST_STRING_DECL(kCFLocaleAlternateQuotationBeginDelimiterKey, "kCFLocaleAlternateQuotationBeginDelimiterKey");
 CONST_STRING_DECL(kCFLocaleAlternateQuotationEndDelimiterKey, "kCFLocaleAlternateQuotationEndDelimiterKey");
@@ -62,6 +62,7 @@ CONST_STRING_DECL(kCFDateFormatterIsLenientKey, "kCFDateFormatterIsLenientKey");
 CONST_STRING_DECL(kCFDateFormatterLongEraSymbolsKey, "kCFDateFormatterLongEraSymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterMonthSymbolsKey, "kCFDateFormatterMonthSymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterPMSymbolKey, "kCFDateFormatterPMSymbolKey");
+CONST_STRING_DECL(kCFDateFormatterAmbiguousYearStrategyKey, "kCFDateFormatterAmbiguousYearStrategyKey");
 CONST_STRING_DECL(kCFDateFormatterQuarterSymbolsKey, "kCFDateFormatterQuarterSymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterShortMonthSymbolsKey, "kCFDateFormatterShortMonthSymbolsKey");
 CONST_STRING_DECL(kCFDateFormatterShortQuarterSymbolsKey, "kCFDateFormatterShortQuarterSymbolsKey");
index 90e556e2b4bfaa1672d2131f6f55d9c00fbad75e..b4b06239fd06acf9e1502e6e306ab9956e19a29b 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFLogUtilities.h
-       Copyright (c) 2004-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2004-2012, Apple Inc. All rights reserved.
 */
 
 /*
index 0f2add4dc64c8c5654cd56b8dbc2198b751f363e..d5df91efd829b4dd578c9a1fa57eb3de94774dd4 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFMachPort.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
 #include <CoreFoundation/CFRunLoop.h>
 #include <CoreFoundation/CFArray.h>
 #include <dispatch/dispatch.h>
+#include <dispatch/private.h>
 #include <mach/mach.h>
 #include <dlfcn.h>
 #include "CFInternal.h"
 
-#define AVOID_WEAK_COLLECTIONS 1
 
-#if DEPLOYMENT_TARGET_EMBEDDED
 #define AVOID_WEAK_COLLECTIONS 1
-#endif
 
-#if !defined(AVOID_WEAK_COLLECTIONS)
+#if !AVOID_WEAK_COLLECTIONS
 #import "CFPointerArray.h"
 #endif
 
-DISPATCH_HELPER_FUNCTIONS(port, CFMachPort)
+static dispatch_queue_t _CFMachPortQueue() {
+    static volatile dispatch_queue_t __CFMachPortQueue = NULL;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{ __CFMachPortQueue = dispatch_queue_create("CFMachPort Queue", NULL); });
+    return __CFMachPortQueue;
+}
 
 
 enum {
@@ -57,15 +60,16 @@ enum {
 struct __CFMachPort {
     CFRuntimeBase _base;
     int32_t _state;
-    mach_port_t _port;            /* immutable */
-    dispatch_source_t _dsrc;
-    dispatch_source_t _dsrc2;
-    dispatch_semaphore_t _dsrc_sem;
-    dispatch_semaphore_t _dsrc2_sem;
-    CFMachPortInvalidationCallBack _icallout;
-    CFRunLoopSourceRef _source;   /* immutable, once created */
-    CFMachPortCallBack _callout;  /* immutable */
-    CFMachPortContext _context;   /* immutable */
+    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;
 };
 
 /* Bit 1 in the base reserved bits is used for has-receive-ref state */
@@ -134,51 +138,55 @@ static CFStringRef __CFMachPortCopyDescription(CFTypeRef cf) {
     return result;
 }
 
+// Only call with mp->_lock locked
+CF_INLINE void __CFMachPortInvalidateLocked(CFRunLoopSourceRef source, CFMachPortRef mp) {
+    CFMachPortInvalidationCallBack cb = mp->_icallout;
+    if (cb) {
+        __CFSpinUnlock(&mp->_lock);
+        cb(mp, mp->_context.info);
+        __CFSpinLock(&mp->_lock);
+    }
+    if (NULL != source) {
+        __CFSpinUnlock(&mp->_lock);
+        CFRunLoopSourceInvalidate(source);
+        CFRelease(source);
+        __CFSpinLock(&mp->_lock);
+    }
+    void *info = mp->_context.info;
+    mp->_context.info = NULL;
+    if (mp->_context.release) {
+        __CFSpinUnlock(&mp->_lock);
+        mp->_context.release(info);
+        __CFSpinLock(&mp->_lock);
+    }
+    mp->_state = kCFMachPortStateInvalid;
+    OSMemoryBarrier();
+}
+
 static void __CFMachPortDeallocate(CFTypeRef cf) {
     CHECK_FOR_FORK_RET();
     CFMachPortRef mp = (CFMachPortRef)cf;
 
     // CFMachPortRef is invalid before we get here, except under GC
-    __block CFRunLoopSourceRef source = NULL;
-    __block Boolean wasReady = false;
-    void (^block)(void) = ^{
-            wasReady = (mp->_state == kCFMachPortStateReady);
-            if (wasReady) {
-                mp->_state = kCFMachPortStateInvalidating;
-                OSMemoryBarrier();
-                if (mp->_dsrc) {
-                    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;
-            }
-        };
-    if (!__portSyncDispatchIsSafe(__portQueue())) {
-        block();
-    } else {
-        dispatch_sync(__portQueue(), block);
-    }
+    __CFSpinLock(&mp->_lock);
+    CFRunLoopSourceRef source = NULL;
+    Boolean wasReady = (mp->_state == kCFMachPortStateReady);
     if (wasReady) {
-        CFMachPortInvalidationCallBack cb = mp->_icallout;
-        if (cb) {
-            cb(mp, mp->_context.info);
-        }
-        if (NULL != source) {
-            CFRunLoopSourceInvalidate(source);
-            CFRelease(source);
+        mp->_state = kCFMachPortStateInvalidating;
+        OSMemoryBarrier();
+        if (mp->_dsrc) {
+            dispatch_source_cancel(mp->_dsrc);
+            mp->_dsrc = NULL;
         }
-        void *info = mp->_context.info;
-        mp->_context.info = NULL;
-        if (mp->_context.release) {
-            mp->_context.release(info);
+        if (mp->_dsrc2) {
+            dispatch_source_cancel(mp->_dsrc2);
+            mp->_dsrc2 = NULL;
         }
-        mp->_state = kCFMachPortStateInvalid;
-        OSMemoryBarrier();
+        source = mp->_source;
+        mp->_source = NULL;
+    }    
+    if (wasReady) {
+        __CFMachPortInvalidateLocked(source, mp);
     }
     mp->_state = kCFMachPortStateDeallocating;
 
@@ -188,6 +196,8 @@ static void __CFMachPortDeallocate(CFTypeRef cf) {
     dispatch_semaphore_t sem2 = mp->_dsrc2_sem;
     Boolean doSend2 = __CFMachPortHasSend2(mp), doSend = __CFMachPortHasSend(mp), doReceive = __CFMachPortHasReceive(mp);
 
+    __CFSpinUnlock(&mp->_lock);
+
     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
             if (sem1) {
                 dispatch_semaphore_wait(sem1, DISPATCH_TIME_FOREVER);
@@ -215,7 +225,10 @@ static void __CFMachPortDeallocate(CFTypeRef cf) {
         });
 }
 
-#if defined(AVOID_WEAK_COLLECTIONS)
+// This lock protects __CFAllMachPorts. Take before any instance-specific lock.
+static CFSpinLock_t __CFAllMachPortsLock = CFSpinLockInit;
+
+#if AVOID_WEAK_COLLECTIONS
 static CFMutableArrayRef __CFAllMachPorts = NULL;
 #else
 static __CFPointerArray *__CFAllMachPorts = nil;
@@ -227,8 +240,9 @@ static Boolean __CFMachPortCheck(mach_port_t port) {
     return (KERN_SUCCESS != ret || (0 == (type & MACH_PORT_TYPE_PORT_RIGHTS))) ? false : true;
 }
 
-static void __CFMachPortChecker(Boolean fromTimer) { // only call on __portQueue()
-#if defined(AVOID_WEAK_COLLECTIONS)
+static void __CFMachPortChecker(Boolean fromTimer) {
+    __CFSpinLock(&__CFAllMachPortsLock); // take this lock first before any instance-specific lock
+#if AVOID_WEAK_COLLECTIONS
     for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) {
         CFMachPortRef mp = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx);
 #else
@@ -241,6 +255,7 @@ static void __CFMachPortChecker(Boolean fromTimer) { // only call on __portQueue
             CFRunLoopSourceRef source = NULL;
             Boolean wasReady = (mp->_state == kCFMachPortStateReady);
             if (wasReady) {
+                __CFSpinLock(&mp->_lock); // take this lock second
                 mp->_state = kCFMachPortStateInvalidating;
                 OSMemoryBarrier();
                 if (mp->_dsrc) {
@@ -254,27 +269,17 @@ static void __CFMachPortChecker(Boolean fromTimer) { // only call on __portQueue
                 source = mp->_source;
                 mp->_source = NULL;
                 CFRetain(mp);
+                __CFSpinUnlock(&mp->_lock);
                 dispatch_async(dispatch_get_main_queue(), ^{
-                        CFMachPortInvalidationCallBack cb = mp->_icallout;
-                        if (cb) {
-                            cb(mp, mp->_context.info);
-                        }
-                        if (NULL != source) {
-                            CFRunLoopSourceInvalidate(source);
-                            CFRelease(source);
-                        }
-                        void *info = mp->_context.info;
-                        mp->_context.info = NULL;
-                        if (mp->_context.release) {
-                            mp->_context.release(info);
-                        }
-                        // For hashing and equality purposes, cannot get rid of _port here
-                        mp->_state = kCFMachPortStateInvalid;
-                        OSMemoryBarrier();
-                        CFRelease(mp);
-                    });
+                    // We can grab the mach port-specific spin lock here since we're no longer on the same thread as the one taking the all mach ports spin lock.
+                    // But be sure to release it during callouts
+                    __CFSpinLock(&mp->_lock);
+                    __CFMachPortInvalidateLocked(source, mp);
+                    __CFSpinUnlock(&mp->_lock);
+                    CFRelease(mp);
+                });
             }
-#if defined(AVOID_WEAK_COLLECTIONS)
+#if AVOID_WEAK_COLLECTIONS
             CFArrayRemoveValueAtIndex(__CFAllMachPorts, idx);
 #else
             [__CFAllMachPorts removePointerAtIndex:idx];
@@ -283,9 +288,10 @@ static void __CFMachPortChecker(Boolean fromTimer) { // only call on __portQueue
             cnt--;
         }
     }
-#if !defined(AVOID_WEAK_COLLECTIONS)
+#if !AVOID_WEAK_COLLECTIONS
     [__CFAllMachPorts compact];
 #endif
+    __CFSpinUnlock(&__CFAllMachPortsLock);
 };
 
 
@@ -328,96 +334,103 @@ CFMachPortRef _CFMachPortCreateWithPort2(CFAllocatorRef allocator, mach_port_t p
         return NULL;
     }
 
-    __block CFMachPortRef mp = NULL;
-    dispatch_sync(__portQueue(), ^{
-            static dispatch_source_t timerSource = NULL;
-            if (timerSource == NULL) {
-                uint64_t nanos = 63 * 1000 * 1000 * 1000ULL;
-                uint64_t leeway = 9 * 1000ULL;
-                timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, __portQueue());
-                dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, nanos), nanos, leeway);
-                dispatch_source_set_event_handler(timerSource, ^{
-                    __CFMachPortChecker(true);
-                });
-                dispatch_resume(timerSource);
-            }
+    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);
+        dispatch_source_set_event_handler(timerSource, ^{
+            __CFMachPortChecker(true);
+        });
+        dispatch_resume(timerSource);
+    });
 
-#if defined(AVOID_WEAK_COLLECTIONS)
-            for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) {
-                CFMachPortRef p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx);
-                if (p && p->_port == port) {
-                    CFRetain(p);
-                    mp = p;
-                    return;
-                }
-            }
+    CFMachPortRef mp = NULL;
+    __CFSpinLock(&__CFAllMachPortsLock);
+#if AVOID_WEAK_COLLECTIONS
+    for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) {
+        CFMachPortRef p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx);
+        if (p && p->_port == port) {
+            CFRetain(p);
+            mp = p;
+            break;
+        }
+    }
 #else                
-            for (CFIndex idx = 0, cnt = __CFAllMachPorts ? [__CFAllMachPorts count] : 0; idx < cnt; idx++) {
-                CFMachPortRef p = (CFMachPortRef)[__CFAllMachPorts pointerAtIndex:idx];
-                if (p && p->_port == port) {
-                    CFRetain(p);
-                    mp = p;
-                    return;
-                }
-            }
-#endif
-
-            CFIndex size = sizeof(struct __CFMachPort) - sizeof(CFRuntimeBase);
-            CFMachPortRef memory = (CFMachPortRef)_CFRuntimeCreateInstance(allocator, CFMachPortGetTypeID(), size, NULL);
-            if (NULL == memory) {
-                return;
-            }
-            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->_callout = callout;
-            if (NULL != context) {
-                objc_memmove_collectable(&memory->_context, context, sizeof(CFMachPortContext));
-                memory->_context.info = context->retain ? (void *)context->retain(context->info) : context->info;
-            }
-            memory->_state = kCFMachPortStateReady;
-#if defined(AVOID_WEAK_COLLECTIONS)
-            if (!__CFAllMachPorts) __CFAllMachPorts = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-            CFArrayAppendValue(__CFAllMachPorts, memory);
-#else
-            if (!__CFAllMachPorts) __CFAllMachPorts = [[__CFPointerArray alloc] initWithOptions:(kCFUseCollectableAllocator ? CFPointerFunctionsZeroingWeakMemory : CFPointerFunctionsStrongMemory)];
-            [__CFAllMachPorts addPointer:memory];
+    for (CFIndex idx = 0, cnt = __CFAllMachPorts ? [__CFAllMachPorts count] : 0; idx < cnt; idx++) {
+        CFMachPortRef p = (CFMachPortRef)[__CFAllMachPorts pointerAtIndex:idx];
+        if (p && p->_port == port) {
+            CFRetain(p);
+            mp = p;
+            break;
+        }
+    }
 #endif
-            mp = memory;
-            if (shouldFreeInfo) *shouldFreeInfo = false;
-
-            if (type & MACH_PORT_TYPE_SEND_RIGHTS) {
-                dispatch_source_t theSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, port, DISPATCH_MACH_SEND_DEAD, __portQueue());
-                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); });
-            }
-        });
+    __CFSpinUnlock(&__CFAllMachPortsLock);
+    
+    if (!mp) {
+        CFIndex size = sizeof(struct __CFMachPort) - sizeof(CFRuntimeBase);
+        CFMachPortRef memory = (CFMachPortRef)_CFRuntimeCreateInstance(allocator, CFMachPortGetTypeID(), size, NULL);
+        if (NULL == memory) {
+            return NULL;
+        }
+        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->_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->_state = kCFMachPortStateReady;
+        __CFSpinLock(&__CFAllMachPortsLock);
+    #if AVOID_WEAK_COLLECTIONS
+        if (!__CFAllMachPorts) __CFAllMachPorts = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
+        CFArrayAppendValue(__CFAllMachPorts, memory);
+    #else
+        if (!__CFAllMachPorts) __CFAllMachPorts = [[__CFPointerArray alloc] initWithOptions:(kCFUseCollectableAllocator ? CFPointerFunctionsZeroingWeakMemory : CFPointerFunctionsStrongMemory)];
+        [__CFAllMachPorts addPointer:memory];
+    #endif
+        __CFSpinUnlock(&__CFAllMachPortsLock);
+        mp = memory;
+        if (shouldFreeInfo) *shouldFreeInfo = false;
+
+        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 (mp && !CFMachPortIsValid(mp)) { // must do this outside lock to avoid deadlock
         CFRelease(mp);
         mp = NULL;
@@ -453,69 +466,58 @@ CFMachPortRef CFMachPortCreate(CFAllocatorRef allocator, CFMachPortCallBack call
 
 void CFMachPortInvalidate(CFMachPortRef mp) {
     CHECK_FOR_FORK_RET();
-    CF_OBJC_FUNCDISPATCH0(CFMachPortGetTypeID(), void, mp, "invalidate");
+    CF_OBJC_FUNCDISPATCHV(CFMachPortGetTypeID(), void, (NSMachPort *)mp, invalidate);
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
     CFRetain(mp);
-    __block CFRunLoopSourceRef source = NULL;
-    __block Boolean wasReady = false;
-    dispatch_sync(__portQueue(), ^{
-            wasReady = (mp->_state == kCFMachPortStateReady);
-            if (wasReady) {
-                mp->_state = kCFMachPortStateInvalidating;
-                OSMemoryBarrier();
-#if defined(AVOID_WEAK_COLLECTIONS)
-                for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) {
-                    CFMachPortRef p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx);
-                    if (p == mp) {
-                        CFArrayRemoveValueAtIndex(__CFAllMachPorts, idx);
-                        break;
-                    }
-                }
+    CFRunLoopSourceRef source = NULL;
+    Boolean wasReady = false;
+    __CFSpinLock(&__CFAllMachPortsLock); // take this lock first
+    __CFSpinLock(&mp->_lock);
+    wasReady = (mp->_state == kCFMachPortStateReady);
+    if (wasReady) {
+        mp->_state = kCFMachPortStateInvalidating;
+        OSMemoryBarrier();
+#if AVOID_WEAK_COLLECTIONS
+        for (CFIndex idx = 0, cnt = __CFAllMachPorts ? CFArrayGetCount(__CFAllMachPorts) : 0; idx < cnt; idx++) {
+            CFMachPortRef p = (CFMachPortRef)CFArrayGetValueAtIndex(__CFAllMachPorts, idx);
+            if (p == mp) {
+                CFArrayRemoveValueAtIndex(__CFAllMachPorts, idx);
+                break;
+            }
+        }
 #else
-                for (CFIndex idx = 0, cnt = __CFAllMachPorts ? [__CFAllMachPorts count] : 0; idx < cnt; idx++) {
-                    CFMachPortRef p = (CFMachPortRef)[__CFAllMachPorts pointerAtIndex:idx];
-                    if (p == mp) {
-                        [__CFAllMachPorts removePointerAtIndex:idx];
-                        break;
-                    }
-                }
-#endif
-                if (mp->_dsrc) {
-                    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;
+        for (CFIndex idx = 0, cnt = __CFAllMachPorts ? [__CFAllMachPorts count] : 0; idx < cnt; idx++) {
+            CFMachPortRef p = (CFMachPortRef)[__CFAllMachPorts pointerAtIndex:idx];
+            if (p == mp) {
+                [__CFAllMachPorts removePointerAtIndex:idx];
+                break;
             }
-        });
-    if (wasReady) {
-        CFMachPortInvalidationCallBack cb = mp->_icallout;
-        if (cb) {
-            cb(mp, mp->_context.info);
         }
-        if (NULL != source) {
-            CFRunLoopSourceInvalidate(source);
-            CFRelease(source);
+#endif        
+        if (mp->_dsrc) {
+            dispatch_source_cancel(mp->_dsrc);
+            mp->_dsrc = NULL;
         }
-        void *info = mp->_context.info;
-        mp->_context.info = NULL;
-        if (mp->_context.release) {
-            mp->_context.release(info);
+        if (mp->_dsrc2) {
+            dispatch_source_cancel(mp->_dsrc2);
+            mp->_dsrc2 = NULL;
         }
-        // For hashing and equality purposes, cannot get rid of _port here
-        mp->_state = kCFMachPortStateInvalid;
-        OSMemoryBarrier();
+        source = mp->_source;
+        mp->_source = NULL;
+    }
+    __CFSpinUnlock(&mp->_lock);
+    __CFSpinUnlock(&__CFAllMachPortsLock); // release this lock last
+    if (wasReady) {
+        __CFSpinLock(&mp->_lock);
+        __CFMachPortInvalidateLocked(source, mp);
+        __CFSpinUnlock(&mp->_lock);
     }
     CFRelease(mp);
 }
 
 mach_port_t CFMachPortGetPort(CFMachPortRef mp) {
     CHECK_FOR_FORK_RET(0);
-    CF_OBJC_FUNCDISPATCH0(CFMachPortGetTypeID(), mach_port_t, mp, "machPort");
+    CF_OBJC_FUNCDISPATCHV(CFMachPortGetTypeID(), mach_port_t, (NSMachPort *)mp, machPort);
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
     return mp->_port;
 }
@@ -527,7 +529,7 @@ void CFMachPortGetContext(CFMachPortRef mp, CFMachPortContext *context) {
 }
 
 Boolean CFMachPortIsValid(CFMachPortRef mp) {
-    CF_OBJC_FUNCDISPATCH0(CFMachPortGetTypeID(), Boolean, mp, "isValid");
+    CF_OBJC_FUNCDISPATCHV(CFMachPortGetTypeID(), Boolean, (NSMachPort *)mp, isValid);
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
     if (!__CFMachPortIsValid(mp)) return false;
     mach_port_type_t type = 0;
@@ -540,7 +542,10 @@ Boolean CFMachPortIsValid(CFMachPortRef mp) {
 
 CFMachPortInvalidationCallBack CFMachPortGetInvalidationCallBack(CFMachPortRef mp) {
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
-    return mp->_icallout;
+    __CFSpinLock(&mp->_lock);
+    CFMachPortInvalidationCallBack cb = mp->_icallout;
+    __CFSpinUnlock(&mp->_lock);
+    return cb;
 }
 
 /* After the CFMachPort has started going invalid, or done invalid, you can't change this, and
@@ -548,13 +553,17 @@ CFMachPortInvalidationCallBack CFMachPortGetInvalidationCallBack(CFMachPortRef m
 void CFMachPortSetInvalidationCallBack(CFMachPortRef mp, CFMachPortInvalidationCallBack callout) {
     CHECK_FOR_FORK_RET();
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
+    __CFSpinLock(&mp->_lock);
     if (__CFMachPortIsValid(mp) || !callout) {
         mp->_icallout = callout;
     } else if (!mp->_icallout && callout) {
+        __CFSpinUnlock(&mp->_lock);
         callout(mp, mp->_context.info);
+        __CFSpinLock(&mp->_lock);
     } else {
         CFLog(kCFLogLevelWarning, CFSTR("CFMachPortSetInvalidationCallBack(): attempt to set invalidation callback (%p) on invalid CFMachPort (%p) thwarted"), callout, mp);
     }
+    __CFSpinUnlock(&mp->_lock);
 }
 
 /* Returns the number of messages queued for a receive port. */
@@ -575,19 +584,19 @@ static mach_port_t __CFMachPortGetPort(void *info) {
 static void *__CFMachPortPerform(void *msg, CFIndex size, CFAllocatorRef allocator, void *info) {
     CHECK_FOR_FORK_RET(NULL);
     CFMachPortRef mp = (CFMachPortRef)info;
-    __block Boolean isValid = false;
-    __block void *context_info = NULL;
-    __block void (*context_release)(const void *) = NULL;
-    dispatch_sync(__portQueue(), ^{
-            isValid = __CFMachPortIsValid(mp);
-            if (!isValid) return;
-            if (mp->_context.retain) {
-                context_info = (void *)mp->_context.retain(mp->_context.info);
-                context_release = mp->_context.release;
-            } else {
-                context_info = mp->_context.info;
-            }
-        });
+    __CFSpinLock(&mp->_lock);
+    Boolean isValid = __CFMachPortIsValid(mp);
+    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;
+        } else {
+            context_info = mp->_context.info;
+        }
+    }
+    __CFSpinUnlock(&mp->_lock);
     if (!isValid) return NULL;
 
     mp->_callout(mp, msg, size, context_info);
@@ -603,28 +612,29 @@ CFRunLoopSourceRef CFMachPortCreateRunLoopSource(CFAllocatorRef allocator, CFMac
     CHECK_FOR_FORK_RET(NULL);
     __CFGenericValidateType(mp, CFMachPortGetTypeID());
     if (!CFMachPortIsValid(mp)) return NULL;
-    __block CFRunLoopSourceRef result = NULL;
-    dispatch_sync(__portQueue(), ^{
-            if (!__CFMachPortIsValid(mp)) return;
-            if (NULL != mp->_source && !CFRunLoopSourceIsValid(mp->_source)) {
-                CFRelease(mp->_source);
-                mp->_source = NULL;
-            }
-            if (NULL == mp->_source) {
-                CFRunLoopSourceContext1 context;
-                context.version = 1;
-                context.info = (void *)mp;
-                context.retain = (const void *(*)(const void *))CFRetain;
-                context.release = (void (*)(const void *))CFRelease;
-                context.copyDescription = (CFStringRef (*)(const void *))__CFMachPortCopyDescription;
-                context.equal = (Boolean (*)(const void *, const void *))__CFMachPortEqual;
-                context.hash = (CFHashCode (*)(const void *))__CFMachPortHash;
-                context.getPort = __CFMachPortGetPort;
-                context.perform = __CFMachPortPerform;
-                mp->_source = CFRunLoopSourceCreate(allocator, order, (CFRunLoopSourceContext *)&context);
-            }
-            result = mp->_source ? (CFRunLoopSourceRef)CFRetain(mp->_source) : NULL;
-        });
+    CFRunLoopSourceRef result = NULL;
+    __CFSpinLock(&mp->_lock);
+    if (__CFMachPortIsValid(mp)) {
+        if (NULL != mp->_source && !CFRunLoopSourceIsValid(mp->_source)) {
+            CFRelease(mp->_source);
+            mp->_source = NULL;
+        }
+        if (NULL == mp->_source) {
+            CFRunLoopSourceContext1 context;
+            context.version = 1;
+            context.info = (void *)mp;
+            context.retain = (const void *(*)(const void *))CFRetain;
+            context.release = (void (*)(const void *))CFRelease;
+            context.copyDescription = (CFStringRef (*)(const void *))__CFMachPortCopyDescription;
+            context.equal = (Boolean (*)(const void *, const void *))__CFMachPortEqual;
+            context.hash = (CFHashCode (*)(const void *))__CFMachPortHash;
+            context.getPort = __CFMachPortGetPort;
+            context.perform = __CFMachPortPerform;
+            mp->_source = CFRunLoopSourceCreate(allocator, order, (CFRunLoopSourceContext *)&context);
+        }
+        result = mp->_source ? (CFRunLoopSourceRef)CFRetain(mp->_source) : NULL;
+    }
+    __CFSpinUnlock(&mp->_lock);
     return result;
 }
 
index fa1d9fbfdcd448bc804298debb9bfc391e319d0e..de872627ed0be47fd0571a6cd3e4491bda523f1e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFMachPort.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFMACHPORT__)
index 620f509f1303052f9010afdacfe8dd294f66834e..f28a81f00fab76b73d60f601c176573c12095896 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFMessagePort.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -41,6 +41,7 @@
 #include <mach/mach_time.h>
 #include <dlfcn.h>
 #include <dispatch/dispatch.h>
+#include <dispatch/private.h>
 
 extern pid_t getpid(void);
 
@@ -59,12 +60,6 @@ extern pid_t getpid(void);
 
 #define __CFMessagePortMaxDataSize 0x60000000L
 
-//#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-DISPATCH_HELPER_FUNCTIONS(mport, CFMessagePort)
-//#pragma GCC diagnostic pop
-
-
 static CFSpinLock_t __CFAllMessagePortsLock = CFSpinLockInit;
 static CFMutableDictionaryRef __CFAllLocalMessagePorts = NULL;
 static CFMutableDictionaryRef __CFAllRemoteMessagePorts = NULL;
@@ -321,7 +316,7 @@ static CFStringRef __CFMessagePortSanitizeStringName(CFStringRef name, uint8_t *
     utfname = CFAllocatorAllocate(kCFAllocatorSystemDefault, __kCFMessagePortMaxNameLength + 1, 0);
     CFStringGetBytes(name, CFRangeMake(0, CFStringGetLength(name)), kCFStringEncodingUTF8, 0, false, utfname, __kCFMessagePortMaxNameLength, &utflen);
     utfname[utflen] = '\0';
-    if (strlen(utfname) != utflen) {
+    if (strlen((const char *)utfname) != utflen) {
        /* PCA 9194709: refuse to sanitize a string with an embedded nul character */
        CFAllocatorDeallocate(kCFAllocatorSystemDefault, utfname);
        utfname = NULL;
@@ -576,6 +571,7 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF
        }
        CFDictionaryAddValue(__CFAllRemoteMessagePorts, name, memory);
     }
+    CFRetain(native);
     __CFSpinUnlock(&__CFAllMessagePortsLock);
     CFMachPortSetInvalidationCallBack(native, __CFMessagePortInvalidationCallBack);
     // that set-invalidation-callback might have called back into us
@@ -584,8 +580,10 @@ static CFMessagePortRef __CFMessagePortCreateRemote(CFAllocatorRef allocator, CF
     // went invalid; so check for validity manually and react
     if (!CFMachPortIsValid(native)) {
         CFRelease(memory); // does the invalidate
+        CFRelease(native);
         return NULL;
     }
+    CFRelease(native);
     return (CFMessagePortRef)memory;
 }
 
@@ -740,7 +738,7 @@ void CFMessagePortInvalidate(CFMessagePortRef ms) {
        __CFMessagePortUnlock(ms);
 
        __CFSpinLock(&__CFAllMessagePortsLock);
-       if (0 == ms->_perPID && NULL != (__CFMessagePortIsRemote(ms) ? __CFAllRemoteMessagePorts : __CFAllLocalMessagePorts)) {
+       if (0 == ms->_perPID && NULL != name && NULL != (__CFMessagePortIsRemote(ms) ? __CFAllRemoteMessagePorts : __CFAllLocalMessagePorts)) {
            CFDictionaryRemoveValue(__CFMessagePortIsRemote(ms) ? __CFAllRemoteMessagePorts : __CFAllLocalMessagePorts, name);
        }
        __CFSpinUnlock(&__CFAllMessagePortsLock);
@@ -787,14 +785,18 @@ void CFMessagePortInvalidate(CFMessagePortRef ms) {
 Boolean CFMessagePortIsValid(CFMessagePortRef ms) {
     __CFGenericValidateType(ms, __kCFMessagePortTypeID);
     if (!__CFMessagePortIsValid(ms)) return false;
+    CFRetain(ms);
     if (NULL != ms->_port && !CFMachPortIsValid(ms->_port)) {
        CFMessagePortInvalidate(ms);
+        CFRelease(ms);
        return false;
     }
     if (NULL != ms->_replyPort && !CFMachPortIsValid(ms->_replyPort)) {
        CFMessagePortInvalidate(ms);
+        CFRelease(ms);
        return false;
     }
+    CFRelease(ms);
     return true;
 }
 
@@ -927,7 +929,9 @@ SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CFDataRef
        if (sendTimeout < 1.0) sendTimeout = 0.0;
        sendTimeOut = floor(sendTimeout);
     }
+    __CFMessagePortUnlock(remote);
     ret = mach_msg((mach_msg_header_t *)sendmsg, MACH_SEND_MSG|sendOpts, sendmsg->header.msgh_size, 0, MACH_PORT_NULL, sendTimeOut, MACH_PORT_NULL);
+    __CFMessagePortLock(remote);
     if (KERN_SUCCESS != ret) {
        // need to deallocate the send-once right that might have been created
        if (replyMode != NULL) mach_port_deallocate(mach_task_self(), ((mach_msg_header_t *)sendmsg)->msgh_local_port);
@@ -1155,44 +1159,49 @@ void CFMessagePortSetDispatchQueue(CFMessagePortRef ms, dispatch_queue_t queue)
     if (queue) {
         mach_port_t port = __CFMessagePortGetPort(ms);
         if (MACH_PORT_NULL != port) {
-               dispatch_source_t theSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, port, 0, __mportQueue());
-               dispatch_source_set_cancel_handler(theSource, ^{
-                   dispatch_release(queue);
-                   dispatch_release(theSource);
-               });
-               dispatch_source_set_event_handler(theSource, ^{
-                   CFRetain(ms);
-                   mach_msg_header_t *msg = (mach_msg_header_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2048, 0);
-                   msg->msgh_size = 2048;
-
-                   for (;;) {
-                       msg->msgh_bits = 0;
-                       msg->msgh_local_port = port;
-                       msg->msgh_remote_port = MACH_PORT_NULL;
-                       msg->msgh_id = 0;
-
-                       kern_return_t ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, 0, MACH_PORT_NULL);
-                       if (MACH_MSG_SUCCESS == ret) break;
-                       if (MACH_RCV_TOO_LARGE != ret) HALT;
-
-                       uint32_t newSize = round_msg(msg->msgh_size + MAX_TRAILER_SIZE);
-                       msg = CFAllocatorReallocate(kCFAllocatorSystemDefault, msg, newSize, 0);
-                       msg->msgh_size = newSize;
-                   }
-
-                   dispatch_async(queue, ^{
-                       mach_msg_header_t *reply = __CFMessagePortPerform(msg, msg->msgh_size, kCFAllocatorSystemDefault, ms);
-                       if (NULL != reply) {
-                           kern_return_t ret = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
-                           if (KERN_SUCCESS != ret) mach_msg_destroy(reply);
-                           CFAllocatorDeallocate(kCFAllocatorSystemDefault, reply);
-                       }
-                       CFAllocatorDeallocate(kCFAllocatorSystemDefault, msg);
-                       CFRelease(ms);
-                   });
-               });
-               ms->_dispatchSource = theSource;
-           }
+            static dispatch_queue_t mportQueue = NULL;
+            static dispatch_once_t once;
+            dispatch_once(&once, ^{
+                mportQueue = dispatch_queue_create("CFMessagePort Queue", NULL);
+            });
+            dispatch_source_t theSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, port, 0, mportQueue);
+            dispatch_source_set_cancel_handler(theSource, ^{
+                dispatch_release(queue);
+                dispatch_release(theSource);
+            });
+            dispatch_source_set_event_handler(theSource, ^{
+                CFRetain(ms);
+                mach_msg_header_t *msg = (mach_msg_header_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 2048, 0);
+                msg->msgh_size = 2048;
+
+                for (;;) {
+                    msg->msgh_bits = 0;
+                    msg->msgh_local_port = port;
+                    msg->msgh_remote_port = MACH_PORT_NULL;
+                    msg->msgh_id = 0;
+
+                    kern_return_t ret = mach_msg(msg, MACH_RCV_MSG|MACH_RCV_LARGE|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, 0, MACH_PORT_NULL);
+                    if (MACH_MSG_SUCCESS == ret) break;
+                    if (MACH_RCV_TOO_LARGE != ret) HALT;
+
+                    uint32_t newSize = round_msg(msg->msgh_size + MAX_TRAILER_SIZE);
+                    msg = CFAllocatorReallocate(kCFAllocatorSystemDefault, msg, newSize, 0);
+                    msg->msgh_size = newSize;
+                }
+
+                dispatch_async(queue, ^{
+                    mach_msg_header_t *reply = __CFMessagePortPerform(msg, msg->msgh_size, kCFAllocatorSystemDefault, ms);
+                    if (NULL != reply) {
+                        kern_return_t ret = mach_msg(reply, MACH_SEND_MSG, reply->msgh_size, 0, MACH_PORT_NULL, 0, MACH_PORT_NULL);
+                        if (KERN_SUCCESS != ret) mach_msg_destroy(reply);
+                        CFAllocatorDeallocate(kCFAllocatorSystemDefault, reply);
+                    }
+                    CFAllocatorDeallocate(kCFAllocatorSystemDefault, msg);
+                    CFRelease(ms);
+                });
+            });
+            ms->_dispatchSource = theSource;
+        }
         if (ms->_dispatchSource) {
             dispatch_retain(queue);
             ms->_dispatchQ = queue;
index e55cf829fb48c7c10b87204ffc37d7064dc2700a..4d8f9b74706932ca147e56b341eadfeae01d4df4 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFMessagePort.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFMESSAGEPORT__)
index 2c6a70afc6fa659eebce5fb672ff343510c58786..4ddbcc0e30801013d4b60b9279faa2c1de9798eb 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumber.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
@@ -32,6 +32,7 @@
 #include <math.h>
 #include <float.h>
 
+
 #if DEPLOYMENT_TARGET_WINDOWS
 #define isnan(A) _isnan(A)
 #define isinf(A) !_finite(A)
@@ -100,7 +101,7 @@ CFTypeID CFBooleanGetTypeID(void) {
 }
 
 Boolean CFBooleanGetValue(CFBooleanRef boolean) {
-    CF_OBJC_FUNCDISPATCH0(__kCFBooleanTypeID, Boolean, boolean, "boolValue");
+    CF_OBJC_FUNCDISPATCHV(__kCFBooleanTypeID, Boolean, (NSNumber *)boolean, boolValue);
     return (boolean == kCFBooleanTrue) ? true : false;
 }
 
@@ -111,6 +112,8 @@ Boolean CFBooleanGetValue(CFBooleanRef boolean) {
 
 #if OLD_CRAP_TOO
 
+// old implementation, for runtime comparison purposes
+
 typedef union {
     SInt32 valSInt32;
     int64_t valSInt64;
@@ -150,7 +153,7 @@ static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, s
 #define BITSFORDOUBLEPOSINF    ((uint64_t)0x7ff0000000000000ULL)
 #define BITSFORDOUBLENEGINF    ((uint64_t)0xfff0000000000000ULL)
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #define FLOAT_POSITIVE_2_TO_THE_64     0x1.0p+64L
 #define FLOAT_NEGATIVE_2_TO_THE_127    -0x1.0p+127L
 #define FLOAT_POSITIVE_2_TO_THE_127    0x1.0p+127L
@@ -1025,6 +1028,7 @@ static const CFRuntimeClass __CFNumberClass = {
     __CFNumberCopyDescription
 };
 
+
 __private_extern__ void __CFNumberInitialize(void) {
     __kCFNumberTypeID = _CFRuntimeRegisterClass(&__CFNumberClass);
 
@@ -1076,22 +1080,30 @@ CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const vo
        case kCFNumberSInt32Type: {
             int32_t value = *(int32_t *)valuePtr;
 #if !__LP64__
-            // We don't bother allowing the min 24-bit integer -2^24 to also be fast-pathed;
+            // 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.
-            if ((1L << 23) <= -value || (1L << 23) <= value) break;
+            int32_t limit = (1L << 23);
+            if (value <= -limit || limit <= value) break;
 #endif
-            return (CFNumberRef)((uintptr_t)((intptr_t)value << 8) | (2 << 6) | kCFTaggedObjectID_Integer);
+            uintptr_t ptr_val = ((uintptr_t)((intptr_t)value << 8) | (2 << 6) | kCFTaggedObjectID_Integer);
+            return (CFNumberRef)ptr_val;
         }
-#if __LP64__
        case kCFNumberSInt64Type: {
             int64_t value = *(int64_t *)valuePtr;
-            // We don't bother allowing the min 56-bit integer -2^56 to also be fast-pathed;
+#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.
-            if ((1L << 55) <= -value || (1L << 55) <= value) break;
-            uintptr_t ptr_val = ((uintptr_t)(value << 8) | (3 << 6) | kCFTaggedObjectID_Integer);
+            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;
        }
-#endif
        }
     }
 
@@ -1185,7 +1197,7 @@ CFNumberType CFNumberGetType(CFNumberRef number) {
     if (CF_IS_TAGGED_INT(number)) {
         return __CFNumberGetType(number);
     }
-    CF_OBJC_FUNCDISPATCH0(__kCFNumberTypeID, CFNumberType, number, "_cfNumberType");
+    CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, CFNumberType, (NSNumber *)number, _cfNumberType);
     __CFAssertIsNumber(number);
     CFNumberType type = __CFNumberGetType(number);
     if (kCFNumberSInt128Type == type) type = kCFNumberSInt64Type; // must hide this type, since it is not public
@@ -1291,7 +1303,7 @@ Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr)
         Boolean r = __CFNumberGetValueCompat(number, type, valuePtr);
         return r;
     }
-    CF_OBJC_FUNCDISPATCH2(__kCFNumberTypeID, Boolean, number, "_getValue:forType:", valuePtr, __CFNumberTypeTable[type].canonicalType);
+    CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, Boolean, (NSNumber *)number, _getValue:(void *)valuePtr forType:(CFNumberType)__CFNumberTypeTable[type].canonicalType);
     __CFAssertIsNumber(number);
     __CFAssertIsValidNumberType(type);
     uint8_t localMemory[128];
@@ -1315,8 +1327,8 @@ CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL 2 in CFNumberGetValue: BYTES NOT
 }
 
 static CFComparisonResult CFNumberCompare_new(CFNumberRef number1, CFNumberRef number2, void *context) {
-    CF_OBJC_FUNCDISPATCH1(__kCFNumberTypeID, CFComparisonResult, number1, "compare:", number2);
-    CF_OBJC_FUNCDISPATCH1(__kCFNumberTypeID, CFComparisonResult, number2, "_reverseCompare:", number1);
+    CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, CFComparisonResult, (NSNumber *)number1, compare:(NSNumber *)number2);
+    CF_OBJC_FUNCDISPATCHV(__kCFNumberTypeID, CFComparisonResult, (NSNumber *)number2, _reverseCompare:(NSNumber *)number1);
     __CFAssertIsNumber(number1);
     __CFAssertIsNumber(number2);
 
index 5e1f5e384440209d332d625304f70edf17d187f7..5cddcbb464ec50e179a751ae4a306a58aaeafd3c 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumber.h
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFNUMBER__)
@@ -30,6 +30,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef const struct __CFBoolean * CFBooleanRef;
@@ -45,7 +46,7 @@ CFTypeID CFBooleanGetTypeID(void);
 CF_EXPORT
 Boolean CFBooleanGetValue(CFBooleanRef boolean);
 
-enum {
+typedef CF_ENUM(CFIndex, CFNumberType) {
     /* Fixed-width types */
     kCFNumberSInt8Type = 1,
     kCFNumberSInt16Type = 2,
@@ -63,15 +64,10 @@ enum {
     kCFNumberDoubleType = 13,
     /* Other */
     kCFNumberCFIndexType = 14,
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    kCFNumberNSIntegerType = 15,
-    kCFNumberCGFloatType = 16,
+    kCFNumberNSIntegerType CF_ENUM_AVAILABLE(10_5, 2_0) = 15,
+    kCFNumberCGFloatType CF_ENUM_AVAILABLE(10_5, 2_0) = 16,
     kCFNumberMaxType = 16
-#else
-    kCFNumberMaxType = 14
-#endif
 };
-typedef CFIndex CFNumberType;
 
 typedef const struct __CFNumber * CFNumberRef;
 
@@ -145,6 +141,7 @@ CF_EXPORT
 CFComparisonResult CFNumberCompare(CFNumberRef number, CFNumberRef otherNumber, void *context);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFNUMBER__ */
 
index 8007b1ebaffbf6f3198ef2d54df0852eb0690bed..2a3fc8c8c2f4acdfed47bc8cde4154643fe0698b 100644 (file)
  */
 
 /*     CFNumberFormatter.c
-       Copyright (c) 2002-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2002-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
 #include <CoreFoundation/CFNumberFormatter.h>
 #include <CoreFoundation/ForFoundationOnly.h>
+#include <CoreFoundation/CFBigNumber.h>
 #include "CFInternal.h"
 #include "CFLocaleInternal.h"
 #include <unicode/unum.h>
@@ -35,6 +36,7 @@
 #include <math.h>
 #include <float.h>
 
+
 static void __CFNumberFormatterCustomize(CFNumberFormatterRef formatter);
 static CFStringRef __CFNumberFormatterCreateCompressedString(CFStringRef inString, Boolean isFormat, CFRange *rangep);
 static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter, CFStringRef pattern);
@@ -406,6 +408,18 @@ void CFNumberFormatterSetFormat(CFNumberFormatterRef formatter, CFStringRef form
     }
 }
 
+#define GET_MULTIPLIER                      \
+        double multiplier = 1.0;            \
+        double dummy = 0.0;                 \
+        if (formatter->_multiplier) {       \
+            if (!CFNumberGetValue(formatter->_multiplier, kCFNumberFloat64Type, &multiplier)) { \
+                multiplier = 1.0;           \
+            }                               \
+        }                                   \
+        if (modf(multiplier, &dummy) < FLT_EPSILON) {   \
+            multiplier = floor(multiplier);             \
+        }
+
 CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFNumberRef number) {
     if (allocator == NULL) allocator = __CFGetDefaultAllocator();
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
@@ -417,16 +431,11 @@ CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CF
     return CFNumberFormatterCreateStringWithValue(allocator, formatter, type, buffer);
 }
 
-#define FORMAT(T, FUNC)                                                        \
+#define FORMAT_FLT(T, FUNC)                                                    \
        T value = *(T *)valuePtr;                                       \
        if (0 == value && formatter->_zeroSym) { return (CFStringRef)CFRetain(formatter->_zeroSym); }   \
        if (1.0 != multiplier) {                                        \
-               double dummy;                                           \
-               if (modf(multiplier, &dummy) < FLT_EPSILON) { /* float epsilon specifically chosen cuz it is a bit bigger */    \
-                       value = value * (T)floor(multiplier);           \
-               } else {                                                \
-                       value = (T)(value * multiplier);                \
-               }                                                       \
+               value = (T)(value * multiplier);                     \
        }                                                               \
        status = U_ZERO_ERROR;                                          \
        used = FUNC(formatter->_nf, value, ubuffer, cnt, NULL, &status); \
@@ -437,37 +446,51 @@ CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CF
            used = FUNC(formatter->_nf, value, ustr, cnt, NULL, &status); \
        }
 
+#define FORMAT_INT(T, FUN)                                                   \
+        T value = *(T *)valuePtr;                                      \
+        if (0 == value && formatter->_zeroSym) { return (CFStringRef)CFRetain(formatter->_zeroSym); }  \
+        if (1.0 != multiplier) {                                       \
+            value = (T)(value * multiplier);                        \
+        }                                                           \
+        _CFBigNum bignum;                                           \
+        FUN(&bignum, value);                                        \
+        char buffer[BUFFER_SIZE];                                           \
+        _CFBigNumToCString(&bignum, false, true, buffer, BUFFER_SIZE);      \
+        status = U_ZERO_ERROR;                                      \
+        used = unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ubuffer, BUFFER_SIZE, NULL, &status);     \
+        if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {      \
+            cnt = used + 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);            \
+        }                                                           \
+
 CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFNumberType numberType, const void *valuePtr) {
     if (allocator == NULL) allocator = __CFGetDefaultAllocator();
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
-    double multiplier = 1.0;
-    if (formatter->_multiplier) {
-       if (!CFNumberGetValue(formatter->_multiplier, kCFNumberFloat64Type, &multiplier)) {
-           multiplier = 1.0;
-       }
-    }
+    GET_MULTIPLIER;
     UChar *ustr = NULL, ubuffer[BUFFER_SIZE];
     UErrorCode status = U_ZERO_ERROR;
     CFIndex used, cnt = BUFFER_SIZE;
     if (numberType == kCFNumberFloat64Type || numberType == kCFNumberDoubleType) {
-       FORMAT(double, unum_formatDouble)
+       FORMAT_FLT(double, unum_formatDouble)
     } else if (numberType == kCFNumberFloat32Type || numberType == kCFNumberFloatType) {
-       FORMAT(float, unum_formatDouble)
+       FORMAT_FLT(float, unum_formatDouble)
     } else if (numberType == kCFNumberSInt64Type || numberType == kCFNumberLongLongType) {
-       FORMAT(int64_t, unum_formatInt64)
+       FORMAT_INT(int64_t, _CFBigNumInitWithInt64)
     } else if (numberType == kCFNumberLongType || numberType == kCFNumberCFIndexType) {
 #if __LP64__
-       FORMAT(int64_t, unum_formatInt64)
+       FORMAT_INT(int64_t, _CFBigNumInitWithInt64)
 #else
-       FORMAT(int32_t, unum_formatInt64)
+       FORMAT_INT(int32_t, _CFBigNumInitWithInt32)
 #endif
     } else if (numberType == kCFNumberSInt32Type || numberType == kCFNumberIntType) {
-       FORMAT(int32_t, unum_formatInt64)
+       FORMAT_INT(int32_t, _CFBigNumInitWithInt32)
     } else if (numberType == kCFNumberSInt16Type || numberType == kCFNumberShortType) {
-       FORMAT(int16_t, unum_formatInt64)
+       FORMAT_INT(int16_t, _CFBigNumInitWithInt16)
     } else if (numberType == kCFNumberSInt8Type || numberType == kCFNumberCharType) {
-       FORMAT(int8_t, unum_formatInt64)
+       FORMAT_INT(int8_t, _CFBigNumInitWithInt8)
     } else {
        CFAssert2(0, __kCFLogAssertion, "%s(): unknown CFNumberType (%d)", __PRETTY_FUNCTION__, numberType);
        return NULL;
@@ -480,17 +503,92 @@ CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFN
     return string;
 }
 
-#undef FORMAT
+#undef FORMAT_FLT
+#undef FORMAT_INT
+#undef GET_MULTIPLIER
 
 CFNumberRef CFNumberFormatterCreateNumberFromString(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFStringRef string, CFRange *rangep, CFOptionFlags options) {
     if (allocator == NULL) allocator = __CFGetDefaultAllocator();
     __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
     __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
     __CFGenericValidateType(string, CFStringGetTypeID());
-    CFNumberType type = (options & kCFNumberFormatterParseIntegersOnly) ? kCFNumberSInt64Type : kCFNumberFloat64Type;
-    char buffer[16];
-    if (CFNumberFormatterGetValueFromString(formatter, string, rangep, type, buffer)) {
-       return CFNumberCreate(allocator, type, buffer);
+    char buffer[16] __attribute__ ((aligned (8)));
+    CFRange r = rangep ? *rangep : CFRangeMake(0, CFStringGetLength(string));
+    CFNumberRef multiplierRef = formatter->_multiplier;
+    formatter->_multiplier = NULL;
+    Boolean b = CFNumberFormatterGetValueFromString(formatter, string, &r, kCFNumberSInt64Type, buffer);
+    formatter->_multiplier = multiplierRef;
+    if (b) {
+        Boolean passedMultiplier = true;
+        // We handle the multiplier case here manually; the final
+        // result is supposed to be (parsed value) / (multiplier), but
+        // the int case here should only succeed if the parsed value
+        // is an exact multiple of the multiplier.
+        if (multiplierRef) {
+            int64_t tmp = *(int64_t *)buffer;
+            double multiplier = 1.0;
+            if (!CFNumberGetValue(multiplierRef, kCFNumberFloat64Type, &multiplier)) {
+                multiplier = 1.0;
+            }
+            double dummy;
+            if (llabs(tmp) < fabs(multiplier)) {
+                passedMultiplier = false;
+            } else if (fabs(multiplier) < 1.0) { // We can't handle this math yet
+                passedMultiplier = false;
+            } else if (modf(multiplier, &dummy) == 0.0) { // multiplier is an integer
+                int64_t imult = (int64_t)multiplier;
+                int64_t rem = tmp % imult;
+                if (rem != 0) passedMultiplier = false;
+                if (passedMultiplier) {
+                    tmp = tmp / imult;
+                    *(int64_t *)buffer = tmp;
+                }
+            } else if (multiplier == -1.0) { // simple
+                tmp = tmp * -1;
+                *(int64_t *)buffer = tmp;
+            } else if (multiplier != 1.0) {
+                // First, throw away integer multiples of the multiplier to
+                // bring the value down to less than 2^53, so that we can
+                // cast it to double without losing any precision, important
+                // for the "remainder is zero" test.
+                // Find power of two which, when multiplier is multiplied by it,
+                // results in an integer value. pwr will be <= 52 since multiplier
+                // is at least 1.
+                int pwr = 0;
+                double intgrl;
+                while (modf(scalbn(multiplier, pwr), &intgrl) != 0.0) pwr++;
+                int64_t i2 = (int64_t)intgrl;
+                // scale pwr and i2 up to a reasonably large value so the next loop doesn't take forever
+                while (llabs(i2) < (1LL << 50)) { i2 *= 2; pwr++; }
+                int64_t cnt = 0;
+                while ((1LL << 53) <= llabs(tmp)) {
+                   // subtract (multiplier * 2^pwr) each time
+                    tmp -= i2; // move tmp toward zero
+                    cnt += (1LL << pwr); // remember how many 2^pwr we subtracted
+                }
+                // If the integer is less than 2^53, there is no loss
+                // in converting it to double, so we can just do the
+                // direct operation now.
+                double rem = fmod((double)tmp, multiplier);
+                if (rem != 0.0) passedMultiplier = false;
+                if (passedMultiplier) {
+                   // The original tmp, which we need to divide by multiplier, is at this point:
+                    //   tmp + k * 2^n * multiplier, where k is the number of loop iterations
+                    // That original value needs to be divided by multiplier and put back in the
+                    // buffer.  Noting that k * 2^n == cnt, and after some algebra, we have:
+                    tmp = (int64_t)((double)tmp / multiplier) + cnt;
+                    *(int64_t *)buffer = tmp;
+                }
+            }
+        }
+        if (passedMultiplier && ((r.length == CFStringGetLength(string)) || (options & kCFNumberFormatterParseIntegersOnly))) {
+            if (rangep) *rangep = r;
+           return CFNumberCreate(allocator, kCFNumberSInt64Type, buffer);
+        }
+    }
+    if (options & kCFNumberFormatterParseIntegersOnly) return NULL;
+    if (CFNumberFormatterGetValueFromString(formatter, string, rangep, kCFNumberFloat64Type, buffer)) {
+       return CFNumberCreate(allocator, kCFNumberFloat64Type, buffer);
     }
     return NULL;
 }
@@ -532,7 +630,13 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
     } else if (!formatter->_isLenient) {
        ustr += range.location;
     }
-    if (formatter->_isLenient) __CFNumberFormatterApplyPattern(formatter, formatter->_compformat);
+    CFNumberRef multiplierRef = formatter->_multiplier;
+    formatter->_multiplier = NULL;
+    if (formatter->_isLenient) {
+        __CFNumberFormatterApplyPattern(formatter, formatter->_compformat);
+        if (formatter->_multiplier) CFRelease(formatter->_multiplier);
+        formatter->_multiplier = NULL;
+    }
     Boolean integerOnly = 1;
     switch (numberType) {
     case kCFNumberSInt8Type: case kCFNumberCharType:
@@ -554,10 +658,20 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
     if (isZero) {
        dpos = rangep ? rangep->length : 0;
     } else {
-       if (integerOnly) {
-           dreti = unum_parseInt64(formatter->_nf, ustr, range.length, &dpos, &status);
-       } else {
-           dretd = unum_parseDouble(formatter->_nf, ustr, range.length, &dpos, &status);
+       char buffer[1024];
+        memset(buffer, 0, sizeof(buffer));
+       int32_t len = unum_parseDecimal(formatter->_nf, ustr, range.length, &dpos, buffer, sizeof(buffer), &status);
+        if (!U_FAILURE(status) && 0 < len && integerOnly) {
+           char *endptr = NULL;
+           errno = 0;
+           dreti = strtoll_l(buffer, &endptr, 10, NULL);
+           if (!(errno == 0 && *endptr == '\0')) status = U_INVALID_FORMAT_ERROR;
+       }
+       if (!U_FAILURE(status) && 0 < len) {
+           char *endptr = NULL;
+           errno = 0;
+           dretd = strtod_l(buffer, &endptr, NULL);
+           if (!(errno == 0 && *endptr == '\0')) status = U_INVALID_FORMAT_ERROR;
        }
     }
     if (formatter->_isLenient) {
@@ -570,9 +684,12 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
            rangep->length = uncompIdx - rangep->location;
        }
        __CFNumberFormatterApplyPattern(formatter, formatter->_format);
+        if (formatter->_multiplier) CFRelease(formatter->_multiplier);
+        formatter->_multiplier = NULL;
     } else if (rangep) {
         rangep->length = dpos + (range.location - rangep->location);
     }
+    formatter->_multiplier = multiplierRef;
     CFRelease(stringToParse);
     if (U_FAILURE(status)) {
        return false;
@@ -582,7 +699,7 @@ Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFSt
         if (!CFNumberGetValue(formatter->_multiplier, kCFNumberFloat64Type, &multiplier)) {
             multiplier = 1.0;
         }
-        dreti = (int64_t)((double)dreti / multiplier); // integer truncation
+        dreti = (int64_t)((double)dreti / multiplier); // integer truncation, plus double cast can be lossy for dreti > 2^53
         dretd = dretd / multiplier;
     }
     switch (numberType) {
index bce9115e4eabff28a5f8d7a408bd73f5d77ab7d4..9c17102ea58cd72dfa43d3e4db309b7e4259a324 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFNumberFormatter.h
-       Copyright (c) 2003-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2003-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFNUMBERFORMATTER__)
@@ -41,7 +41,7 @@ typedef struct __CFNumberFormatter *CFNumberFormatterRef;
 CF_EXPORT
 CFTypeID CFNumberFormatterGetTypeID(void);
 
-enum { // number format styles
+typedef CF_ENUM(CFIndex, CFNumberFormatterStyle) {     // number format styles
        kCFNumberFormatterNoStyle = 0,
        kCFNumberFormatterDecimalStyle = 1,
        kCFNumberFormatterCurrencyStyle = 2,
@@ -49,7 +49,6 @@ enum {        // number format styles
        kCFNumberFormatterScientificStyle = 4,
        kCFNumberFormatterSpellOutStyle = 5
 };
-typedef CFIndex CFNumberFormatterStyle;
 
 
 CF_EXPORT
@@ -72,7 +71,7 @@ void CFNumberFormatterSetFormat(CFNumberFormatterRef formatter, CFStringRef form
        // Set the format description string of the number formatter.  This
        // overrides the style settings.  The format of the format string
        // is as defined by the ICU library, and is similar to that found
-       // in Microsoft Excel and NSNumberFormatter (and Java I believe).
+       // in Microsoft Excel and NSNumberFormatter.
        // The number formatter starts with a default format string defined
        // by the style argument with which it was created.
 
@@ -86,10 +85,9 @@ CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFN
        // using the current state of the number formatter.
 
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFNumberFormatterOptionFlags) {
     kCFNumberFormatterParseIntegersOnly = 1    /* only parse integers */
 };
-typedef CFOptionFlags CFNumberFormatterOptionFlags;
 
 CF_EXPORT
 CFNumberRef CFNumberFormatterCreateNumberFromString(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFStringRef string, CFRange *rangep, CFOptionFlags options);
@@ -154,7 +152,7 @@ CF_EXPORT const CFStringRef kCFNumberFormatterUseSignificantDigits CF_AVAILABLE(
 CF_EXPORT const CFStringRef kCFNumberFormatterMinSignificantDigits CF_AVAILABLE(10_5, 2_0);    // CFNumber
 CF_EXPORT const CFStringRef kCFNumberFormatterMaxSignificantDigits CF_AVAILABLE(10_5, 2_0);    // CFNumber
 
-enum {
+typedef CF_ENUM(CFIndex, CFNumberFormatterRoundingMode) {
     kCFNumberFormatterRoundCeiling = 0,
     kCFNumberFormatterRoundFloor = 1,
     kCFNumberFormatterRoundDown = 2,
@@ -163,15 +161,13 @@ enum {
     kCFNumberFormatterRoundHalfDown = 5,
     kCFNumberFormatterRoundHalfUp = 6
 };
-typedef CFIndex CFNumberFormatterRoundingMode;
 
-enum {
+typedef CF_ENUM(CFIndex, CFNumberFormatterPadPosition) {
     kCFNumberFormatterPadBeforePrefix = 0,
     kCFNumberFormatterPadAfterPrefix = 1,
     kCFNumberFormatterPadBeforeSuffix = 2,
     kCFNumberFormatterPadAfterSuffix = 3
 };
-typedef CFIndex CFNumberFormatterPadPosition;
 
 
 CF_EXPORT
diff --git a/CFOldStylePList.c b/CFOldStylePList.c
new file mode 100644 (file)
index 0000000..3881788
--- /dev/null
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2012 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@
+ */
+
+/*     CFOldStylePList.c
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
+       Responsibility: Tony Parker
+*/
+
+#include <CoreFoundation/CFPropertyList.h>
+#include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFError.h>
+#include <CoreFoundation/CFStringEncodingConverter.h>
+#include "CFInternal.h"
+#include <CoreFoundation/CFCalendar.h>
+#include <CoreFoundation/CFSet.h>
+
+#include <ctype.h>
+
+//
+// Old NeXT-style property lists
+//
+
+CF_INLINE void __CFPListRelease(CFTypeRef cf, CFAllocatorRef allocator) {
+    if (cf && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(cf);
+}
+
+__private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);
+
+typedef struct {
+    const UniChar *begin;
+    const UniChar *curr;
+    const UniChar *end;
+    CFErrorRef error;
+    CFAllocatorRef allocator;
+    UInt32 mutabilityOption;
+    CFMutableSetRef stringSet;  // set of all strings involved in this parse; allows us to share non-mutable strings in the returned plist
+} _CFStringsFileParseInfo;
+
+// warning: doesn't have a good idea of Unicode line separators
+static UInt32 lineNumberStrings(_CFStringsFileParseInfo *pInfo) {
+    const UniChar *p = pInfo->begin;
+    UInt32 count = 1;
+    while (p < pInfo->curr) {
+        if (*p == '\r') {
+            count ++;
+            if (*(p + 1) == '\n')
+                p ++;
+        } else if (*p == '\n') {
+            count ++;
+        }
+        p ++;
+    }
+    return count;
+}
+
+static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireObject);
+
+#define isValidUnquotedStringCharacter(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') || ((x) >= '0' && (x) <= '9') || (x) == '_' || (x) == '$' || (x) == '/' || (x) == ':' || (x) == '.' || (x) == '-')
+
+// Returns true if the advance found something before the end of the buffer, false otherwise
+static Boolean advanceToNonSpace(_CFStringsFileParseInfo *pInfo) {
+    UniChar ch2;
+    while (pInfo->curr < pInfo->end) {
+       ch2 = *(pInfo->curr);
+        pInfo->curr ++;
+        if (ch2 >= 9 && ch2 <= 0x0d) continue; // tab, newline, vt, form feed, carriage return
+        if (ch2 == ' ' || ch2 == 0x2028 || ch2 == 0x2029) continue;    // space and Unicode line sep, para sep
+       if (ch2 == '/') {
+            if (pInfo->curr >= pInfo->end) {
+                // whoops; back up and return
+                pInfo->curr --;
+                return true;
+            } else if (*(pInfo->curr) == '/') {
+                pInfo->curr ++;
+                while (pInfo->curr < pInfo->end) {     // go to end of comment line
+                    UniChar ch3 = *(pInfo->curr);
+                    if (ch3 == '\n' || ch3 == '\r' || ch3 == 0x2028 || ch3 == 0x2029) break;
+                    pInfo->curr ++;
+               }
+           } else if (*(pInfo->curr) == '*') {         // handle /* ... */
+                pInfo->curr ++;
+               while (pInfo->curr < pInfo->end) {
+                   ch2 = *(pInfo->curr);
+                    pInfo->curr ++;
+                   if (ch2 == '*' && pInfo->curr < pInfo->end && *(pInfo->curr) == '/') {
+                        pInfo->curr ++; // advance past the '/'
+                        break;
+                    }
+                }
+            } else {
+                pInfo->curr --;
+                return true;
+           }
+        } else {
+            pInfo->curr --;
+            return true;
+        }
+    }
+    return false;
+}
+
+static UniChar getSlashedChar(_CFStringsFileParseInfo *pInfo) {
+    UniChar ch = *(pInfo->curr);
+    pInfo->curr ++;
+    switch (ch) {
+       case '0':
+       case '1':       
+       case '2':       
+       case '3':       
+       case '4':       
+       case '5':       
+       case '6':       
+       case '7':  {
+            uint8_t num = ch - '0';
+            UniChar result;
+            CFIndex usedCharLen;
+           /* three digits maximum to avoid reading \000 followed by 5 as \5 ! */
+           if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { // we use in this test the fact that the buffer is zero-terminated
+                pInfo->curr ++;
+               num = (num << 3) + ch - '0';
+               if ((pInfo->curr < pInfo->end) && (ch = *(pInfo->curr)) >= '0' && ch <= '7') {
+                    pInfo->curr ++;
+                   num = (num << 3) + ch - '0';
+               }
+           }
+            CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, 0, &num, sizeof(uint8_t), NULL,  &result, 1, &usedCharLen);
+            return (usedCharLen == 1) ? result : 0;
+       }
+       case 'U': {
+           unsigned num = 0, numDigits = 4;    /* Parse four digits */
+           while (pInfo->curr < pInfo->end && numDigits--) {
+                if (((ch = *(pInfo->curr)) < 128) && isxdigit(ch)) { 
+                    pInfo->curr ++;
+                   num = (num << 4) + ((ch <= '9') ? (ch - '0') : ((ch <= 'F') ? (ch - 'A' + 10) : (ch - 'a' + 10)));
+               }
+           }
+           return num;
+       }
+       case 'a':       return '\a';    // Note: the meaning of '\a' varies with -traditional to gcc
+       case 'b':       return '\b';
+       case 'f':       return '\f';
+       case 'n':       return '\n';
+       case 'r':       return '\r';
+       case 't':       return '\t';
+       case 'v':       return '\v';
+       case '"':       return '\"';
+       case '\n':      return '\n';
+    }
+    return ch;
+}
+
+static CFStringRef _uniqueStringForCharacters(_CFStringsFileParseInfo *pInfo, const UniChar *base, CFIndex length) {
+    if (0 == length) return !_CFAllocatorIsGCRefZero(pInfo->allocator) ? (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;
+    Boolean use_stack = (length < 2048);
+    STACK_BUFFER_DECL(uint8_t, buffer, use_stack ? length + 1 : 1);
+    uint8_t *ascii = use_stack ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, length + 1, 0);
+    for (CFIndex idx = 0; idx < length; idx++) {
+        UniChar ch = base[idx];
+       if (ch < 0x80) {
+           ascii[idx] = (uint8_t)ch;
+        } else {
+           stringToUnique = CFStringCreateWithCharacters(pInfo->allocator, base, length);
+           break;
+       }
+    }
+    if (!stringToUnique) {
+        ascii[length] = '\0';
+        stringToUnique = CFStringCreateWithBytes(pInfo->allocator, ascii, length, kCFStringEncodingASCII, false);
+    }
+    if (ascii != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ascii);
+    CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique);
+    if (!uniqued) {
+        CFSetAddValue(pInfo->stringSet, stringToUnique);
+       uniqued = stringToUnique;
+    }
+    __CFPListRelease(stringToUnique, pInfo->allocator);
+    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
+    return uniqued;
+}
+
+static CFStringRef _uniqueStringForString(_CFStringsFileParseInfo *pInfo, CFStringRef stringToUnique) {
+    CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique);
+    if (!uniqued) {
+        uniqued = (CFStringRef)__CFStringCollectionCopy(pInfo->allocator, stringToUnique);
+        CFSetAddValue(pInfo->stringSet, uniqued);
+        __CFTypeCollectionRelease(pInfo->allocator, uniqued);
+    }
+    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
+    return uniqued;
+}
+
+static CFStringRef parseQuotedPlistString(_CFStringsFileParseInfo *pInfo, UniChar quote) {
+    CFMutableStringRef str = NULL;
+    const UniChar *startMark = pInfo->curr;
+    const UniChar *mark = pInfo->curr;
+    while (pInfo->curr < pInfo->end) {
+       UniChar ch = *(pInfo->curr);
+        if (ch == quote) break;
+        if (ch == '\\') {
+            if (!str) str = CFStringCreateMutable(pInfo->allocator, 0);
+            CFStringAppendCharacters(str, mark, pInfo->curr - mark);
+            pInfo->curr ++;
+            ch = getSlashedChar(pInfo);
+            CFStringAppendCharacters(str, &ch, 1);
+            mark = pInfo->curr;
+       } else {
+            // Note that the original NSParser code was much more complex at this point, but it had to deal with 8-bit characters in a non-UniChar stream.  We always have UniChar (we translated the data by the system encoding at the very beginning, hopefully), so this is safe.
+            pInfo->curr ++;
+        }
+    }
+    if (pInfo->end <= pInfo->curr) {
+        __CFPListRelease(str, pInfo->allocator);
+        pInfo->curr = startMark;
+        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated quoted string starting on line %d"), lineNumberStrings(pInfo));
+        return NULL;
+    }
+    if (!str) {
+        if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+            str = CFStringCreateMutable(pInfo->allocator, 0);
+            CFStringAppendCharacters(str, mark, pInfo->curr - mark);
+        } else {
+            str = (CFMutableStringRef)_uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark);
+        }
+    } else {
+        if (mark != pInfo->curr) {
+            CFStringAppendCharacters(str, mark, pInfo->curr - mark);
+        }
+        if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
+            CFStringRef uniqueString = _uniqueStringForString(pInfo, str);
+            __CFPListRelease(str, pInfo->allocator);
+            str = (CFMutableStringRef)uniqueString;
+        }
+    }
+    pInfo->curr ++;  // Advance past the quote character before returning.
+    if (pInfo->error) {
+        CFRelease(pInfo->error);
+        pInfo->error = NULL;
+    }
+    return str;
+}
+
+static CFStringRef parseUnquotedPlistString(_CFStringsFileParseInfo *pInfo) {
+    const UniChar *mark = pInfo->curr;
+    while (pInfo->curr < pInfo->end) {
+        UniChar ch = *pInfo->curr;
+        if (isValidUnquotedStringCharacter(ch))
+            pInfo->curr ++;
+        else break;
+    }
+    if (pInfo->curr != mark) {
+        if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
+            CFStringRef str = _uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark);
+            return str;
+        } else {
+            CFMutableStringRef str = CFStringCreateMutable(pInfo->allocator, 0);
+            CFStringAppendCharacters(str, mark, pInfo->curr - mark);
+            return str;
+        }
+    }
+    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF"));
+    return NULL;
+}
+
+static CFStringRef parsePlistString(_CFStringsFileParseInfo *pInfo, bool requireObject) {
+    UniChar ch;
+    Boolean foundChar = advanceToNonSpace(pInfo);
+    if (!foundChar) {
+        if (requireObject) {
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing string"));
+        }
+        return NULL;
+    }
+    ch = *(pInfo->curr);
+    if (ch == '\'' || ch == '\"') {
+        pInfo->curr ++;
+        return parseQuotedPlistString(pInfo, ch);
+    } else if (isValidUnquotedStringCharacter(ch)) {
+        return parseUnquotedPlistString(pInfo);
+    } else {
+        if (requireObject) {
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid string character at line %d"), lineNumberStrings(pInfo));
+       }
+        return NULL;
+    }
+}
+
+static CFTypeRef parsePlistArray(_CFStringsFileParseInfo *pInfo) {
+    CFMutableArrayRef array = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
+    CFTypeRef tmp = parsePlistObject(pInfo, false);
+    Boolean foundChar;
+    while (tmp) {
+        CFArrayAppendValue(array, tmp);
+        __CFPListRelease(tmp, pInfo->allocator);
+        foundChar = advanceToNonSpace(pInfo);
+       if (!foundChar) {
+           __CFPListRelease(array, pInfo->allocator);
+           pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected ',' for array at line %d"), lineNumberStrings(pInfo));
+           return NULL;
+       }
+        if (*pInfo->curr != ',') {
+            tmp = NULL;
+        } else {
+            pInfo->curr ++;
+            tmp = parsePlistObject(pInfo, false);
+        }
+    }
+    foundChar = advanceToNonSpace(pInfo);
+    if (!foundChar || *pInfo->curr != ')') {
+        __CFPListRelease(array, pInfo->allocator);
+        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating ')' for array at line %d"), lineNumberStrings(pInfo));
+        return NULL;
+    }
+    if (pInfo->error) {
+        CFRelease(pInfo->error);
+        pInfo->error = NULL;
+    }
+    pInfo->curr ++;
+    return array;
+}
+
+__attribute__((noinline)) void _CFPropertyListMissingSemicolon(UInt32 line) {
+    CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon in dictionary on line %d. Parsing will be abandoned. Break on _CFPropertyListMissingSemicolon to debug."), line);
+}
+
+__attribute__((noinline)) void _CFPropertyListMissingSemicolonOrValue(UInt32 line) {
+    CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon or value in dictionary on line %d. Parsing will be abandoned. Break on _CFPropertyListMissingSemicolonOrValue to debug."), line);
+}
+
+static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo) {
+    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFStringRef key = NULL;
+    Boolean failedParse = false;
+    key = parsePlistString(pInfo, false);
+    while (key) {
+        CFTypeRef value;
+        Boolean foundChar = advanceToNonSpace(pInfo);
+        if (!foundChar) {
+            UInt32 line = lineNumberStrings(pInfo);
+            _CFPropertyListMissingSemicolonOrValue(line);
+            failedParse = true;
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), line);
+            break;
+        }
+       
+       if (*pInfo->curr == ';') {
+           /* This is a strings file using the shortcut format */
+           /* although this check here really applies to all plists. */
+           value = CFRetain(key);
+       } else if (*pInfo->curr == '=') {
+           pInfo->curr ++;
+           value = parsePlistObject(pInfo, true);
+           if (!value) {
+               failedParse = true;
+               break;
+           }
+       } else {
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected ';' or '=' after key at line %d"), lineNumberStrings(pInfo));
+           failedParse = true;
+           break;
+       }
+       CFDictionarySetValue(dict, key, value);
+       __CFPListRelease(key, pInfo->allocator);
+       key = NULL;
+       __CFPListRelease(value, pInfo->allocator);
+       value = NULL;
+       foundChar = advanceToNonSpace(pInfo);
+       if (foundChar && *pInfo->curr == ';') {
+           pInfo->curr ++;
+           key = parsePlistString(pInfo, false);
+       } else if (true || !foundChar) {
+            UInt32 line = lineNumberStrings(pInfo);
+            _CFPropertyListMissingSemicolon(line);
+           failedParse = true;
+           pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), line);
+       }
+    }
+    
+    if (failedParse) {
+        __CFPListRelease(key, pInfo->allocator);
+        __CFPListRelease(dict, pInfo->allocator);
+        return NULL;
+    }
+    if (pInfo->error) {
+        CFRelease(pInfo->error);
+        pInfo->error = NULL;
+    }
+    return dict;
+}
+
+static CFTypeRef parsePlistDict(_CFStringsFileParseInfo *pInfo) {
+    CFDictionaryRef dict = parsePlistDictContent(pInfo);
+    if (!dict) return NULL;
+    Boolean foundChar = advanceToNonSpace(pInfo);
+    if (!foundChar || *pInfo->curr != '}') {
+        __CFPListRelease(dict, pInfo->allocator);
+        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '}' for dictionary at line %d"), lineNumberStrings(pInfo));
+        return NULL;
+    }
+    pInfo->curr ++;
+    return dict;
+}
+
+CF_INLINE unsigned char fromHexDigit(unsigned char ch) {
+    if (isdigit(ch)) return ch - '0';
+    if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10;
+    if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10;
+    return 0xff; // Just choose a large number for the error code
+}
+
+/* Gets up to bytesSize bytes from a plist data. Returns number of bytes actually read. Leaves cursor at first non-space, non-hex character.
+ -1 is returned for unexpected char, -2 for uneven number of hex digits
+ */
+static int getDataBytes(_CFStringsFileParseInfo *pInfo, unsigned char *bytes, int bytesSize) {
+    int numBytesRead = 0;
+    while ((pInfo->curr < pInfo->end) && (numBytesRead < bytesSize)) {
+       int first, second;
+       UniChar ch1 = *pInfo->curr;
+       if (ch1 == '>') return numBytesRead;  // Meaning we're done
+       first = fromHexDigit((unsigned char)ch1);
+       if (first != 0xff) {    // If the first char is a hex, then try to read a second hex
+           pInfo->curr++;
+           if (pInfo->curr >= pInfo->end) return -2;   // Error: uneven number of hex digits
+           UniChar ch2 = *pInfo->curr;
+           second = fromHexDigit((unsigned char)ch2);
+           if (second == 0xff) return -2;  // Error: uneven number of hex digits
+           bytes[numBytesRead++] = (first << 4) + second;
+           pInfo->curr++;
+       } else if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t' || ch1 == '\r' || ch1 == 0x2028 || ch1 == 0x2029) {
+           pInfo->curr++;
+       } else {
+           return -1;  // Error: unexpected character
+       }
+    }
+    return numBytesRead;    // This does likely mean we didn't encounter a '>', but we'll let the caller deal with that
+}
+
+#define numBytes 400
+static CFTypeRef parsePlistData(_CFStringsFileParseInfo *pInfo) {
+    CFMutableDataRef result = CFDataCreateMutable(pInfo->allocator, 0);
+    
+    // Read hex bytes and append them to result
+    while (1) {
+       unsigned char bytes[numBytes];
+       int numBytesRead = getDataBytes(pInfo, bytes, numBytes);
+       if (numBytesRead < 0) {
+           __CFPListRelease(result, pInfo->allocator);
+            switch (numBytesRead) {
+                case -2: 
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; uneven length"), lineNumberStrings(pInfo));
+                    break;
+                default: 
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; invalid hex"), lineNumberStrings(pInfo));
+                    break;
+            }
+           return NULL;
+       }
+       if (numBytesRead == 0) break;
+       CFDataAppendBytes(result, bytes, numBytesRead);
+    }
+    
+    if (pInfo->error) {
+        CFRelease(pInfo->error);
+        pInfo->error = NULL;
+    }
+    
+    if (*(pInfo->curr) == '>') {
+        pInfo->curr ++; // Move past '>'
+        return result;
+    } else {
+        __CFPListRelease(result, pInfo->allocator);
+        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '>' for data at line %d"), lineNumberStrings(pInfo));
+        return NULL;
+    }
+}
+#undef numBytes
+
+// Returned object is retained; caller must free.
+static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireObject) {
+    UniChar ch;
+    Boolean foundChar = advanceToNonSpace(pInfo);
+    if (!foundChar) {
+        if (requireObject) {
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"));
+        }
+        return NULL;
+    }
+    ch = *(pInfo->curr);
+    pInfo->curr ++;
+    if (ch == '{') {
+        return parsePlistDict(pInfo);
+    } else if (ch == '(') {
+        return parsePlistArray(pInfo);
+    } else if (ch == '<') {
+        return parsePlistData(pInfo);
+    } else if (ch == '\'' || ch == '\"') {
+        return parseQuotedPlistString(pInfo, ch);
+    } else if (isValidUnquotedStringCharacter(ch)) {
+        pInfo->curr --;
+        return parseUnquotedPlistString(pInfo);
+    } else {
+        pInfo->curr --;  // Must back off the charcter we just read
+        if (requireObject) {
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character '0x%x' at line %d"), ch, lineNumberStrings(pInfo));
+        }
+        return NULL;
+    }
+}
+
+// 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) {
+    
+    // Convert the string to UTF16 for parsing old-style
+    if (originalString) {
+        // Ensure that originalString is not collected while we are using it
+        CFRetain(originalString);
+    } else {
+        originalString = CFStringCreateWithBytes(kCFAllocatorSystemDefault, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData), guessedEncoding, NO);
+        if (!originalString) {
+            // Couldn't convert
+            if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed."));
+            return NULL;
+        }
+    }
+        
+    UInt32 length;
+    Boolean createdBuffer = false;
+    length = CFStringGetLength(originalString);
+    if (!length) {
+        if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty."));
+        return NULL;
+    }
+    
+    UniChar *buf = (UniChar *)CFStringGetCharactersPtr(originalString);
+    if (!buf) {
+        buf = (UniChar *)CFAllocatorAllocate(allocator, length * sizeof(UniChar), 0);
+        if (!buf) {
+            CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage.");
+            return NULL;
+        }
+        CFStringGetCharacters(originalString, CFRangeMake(0, length), buf);
+        createdBuffer = true;
+    }
+    
+    _CFStringsFileParseInfo stringsPInfo;
+    stringsPInfo.begin = buf;
+    stringsPInfo.end = buf+length;
+    stringsPInfo.curr = buf;
+    stringsPInfo.allocator = allocator;
+    stringsPInfo.mutabilityOption = option;
+    stringsPInfo.stringSet = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
+    stringsPInfo.error = NULL;
+    
+    const UniChar *begin = stringsPInfo.curr;
+    CFTypeRef result = NULL;
+    Boolean foundChar = advanceToNonSpace(&stringsPInfo);
+    if (!foundChar) {
+        // A file consisting only of whitespace (or empty) is now defined to be an empty dictionary
+        result = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    } else {
+        result = parsePlistObject(&stringsPInfo, true);
+        if (result) {
+            foundChar = advanceToNonSpace(&stringsPInfo);
+            if (foundChar) {
+                if (CFGetTypeID(result) != CFStringGetTypeID()) {
+                    __CFPListRelease(result, allocator);
+                    result = NULL;
+                    if (stringsPInfo.error) CFRelease(stringsPInfo.error);
+                    stringsPInfo.error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Junk after plist at line %d"), lineNumberStrings(&stringsPInfo));
+                } else {
+                    // Reset info and keep parsing
+                    __CFPListRelease(result, allocator);
+                    if (stringsPInfo.error) CFRelease(stringsPInfo.error);
+                    stringsPInfo.error = NULL;
+                    
+                    // Check for a strings file (looks like a dictionary without the opening/closing curly braces)
+                    stringsPInfo.curr = begin;
+                    result = parsePlistDictContent(&stringsPInfo);
+                }
+            }
+        }
+    }
+    
+    if (!result) {
+        // Must return some kind of error if requested
+        if (outError) {
+            if (stringsPInfo.error) {
+                // Transfer ownership
+                *outError = stringsPInfo.error;
+            } else {
+                *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unknown error parsing property list around line %d"), lineNumberStrings(&stringsPInfo));
+            }
+        } else if (stringsPInfo.error) {
+            // Caller doesn't want it, so we need to free it
+            CFRelease(stringsPInfo.error);
+        }
+    }
+    
+    if (result && format) *format = kCFPropertyListOpenStepFormat;
+    
+    if (createdBuffer && !_CFAllocatorIsGCRefZero(allocator)) CFAllocatorDeallocate(allocator, buf);
+    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(stringsPInfo.stringSet);
+    CFRelease(originalString);
+    return result;
+}
+
+#undef isValidUnquotedStringCharacter
index 1170cd10d00295c20ca295f45d0cc8e9ff11a913..7d51cfa1e567fd5a958715b806da0c66ed87feea 100644 (file)
  */
 
 /*     CFPlatform.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
 #include "CFInternal.h"
 #include <CoreFoundation/CFPriv.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     #include <stdlib.h>
     #include <sys/stat.h>
     #include <string.h>
 
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
 #define kCFPlatformInterfaceStringEncoding     kCFStringEncodingUTF8
 #else
 #define kCFPlatformInterfaceStringEncoding     CFStringGetSystemEncoding()
 #endif
 
-static CFStringRef _CFUserName(void);
+extern void __CFGetUGIDs(uid_t *euid, gid_t *egid);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 // CoreGraphics and LaunchServices are only projects (1 Dec 2006) that use these
 char **_CFArgv(void) { return *_NSGetArgv(); }
 int _CFArgc(void) { return *_NSGetArgc(); }
@@ -67,22 +67,6 @@ __private_extern__ Boolean _CFGetCurrentDirectory(char *path, int maxlen) {
     return getcwd(path, maxlen) != NULL;
 }
 
-#if SUPPORT_CFM
-static Boolean __CFIsCFM = false;
-
-// If called super early, we just return false
-__private_extern__ Boolean _CFIsCFM(void) {
-    return __CFIsCFM;
-}
-#endif
-
-#if DEPLOYMENT_TARGET_WINDOWS
-#define PATH_SEP '\\'
-#else
-#define PATH_SEP '/'
-#endif
-
-
 #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;
@@ -155,7 +139,7 @@ const char *_CFProcessPath(void) {
 }
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 const char *_CFProcessPath(void) {
     if (__CFProcessPath) return __CFProcessPath;
 #if DEPLOYMENT_TARGET_MACOSX
@@ -172,20 +156,6 @@ const char *_CFProcessPath(void) {
     uint32_t size = CFMaxPathSize;
     char buffer[size];
     if (0 == _NSGetExecutablePath(buffer, &size)) {
-#if SUPPORT_CFM
-       size_t len = strlen(buffer);
-       if (12 <= len && 0 == strcmp("LaunchCFMApp", buffer + len - 12)) {
-           struct stat exec, lcfm;
-           const char *launchcfm = "/System/Library/Frameworks/Carbon.framework/Versions/Current/Support/LaunchCFMApp";
-           if (0 == stat(launchcfm, &lcfm) && 0 == stat(buffer, &exec) && (lcfm.st_dev == exec.st_dev) && (lcfm.st_ino == exec.st_ino)) {
-               // Executable is LaunchCFMApp, take special action
-               __CFIsCFM = true;
-               if ((*_NSGetArgv())[1] && '/' == *((*_NSGetArgv())[1])) {
-                   strlcpy(buffer, (*_NSGetArgv())[1], sizeof(buffer));
-               }
-           }
-       }
-#endif
        __CFProcessPath = strdup(buffer);
        __CFprogname = strrchr(__CFProcessPath, PATH_SEP);
        __CFprogname = (__CFprogname ? __CFprogname + 1 : __CFProcessPath);
@@ -233,104 +203,95 @@ __private_extern__ CFStringRef _CFProcessNameString(void) {
     return __CFProcessNameString;
 }
 
-static CFStringRef __CFUserName = NULL;
-static CFSpinLock_t __CFPlatformCacheLock = CFSpinLockInit;
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 
 #include <pwd.h>
+#include <sys/param.h>
 
-static CFURLRef __CFHomeDirectory = NULL;
-static uint32_t __CFEUID = -1;
-static uint32_t __CFUID = -1;
-
-static CFURLRef _CFCopyHomeDirURLForUser(struct passwd *upwd) { // __CFPlatformCacheLock must be locked on entry and will be on exit
+// Set the fallBackToHome parameter to true if we should fall back to the HOME environment variable if all else fails. Otherwise return NULL.
+static CFURLRef _CFCopyHomeDirURLForUser(struct passwd *upwd, bool fallBackToHome) {
+    const char *fixedHomePath = issetugid() ? NULL : __CFgetenv("CFFIXED_USER_HOME");
+    const char *homePath = NULL;
+    
+    // Calculate the home directory we will use
+    // First try CFFIXED_USER_HOME (only if not setugid), then fall back to the upwd, then fall back to HOME environment variable
     CFURLRef home = NULL;
-    if (!issetugid()) {
-       const char *path = __CFgetenv("CFFIXED_USER_HOME");
-       if (path) {
-           home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)path, strlen(path), true);
-       }
-    }
-    if (!home) {
-        if (upwd && upwd->pw_dir) {
-            home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true);
-       }
-    }
+    if (!issetugid() && fixedHomePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)fixedHomePath, strlen(fixedHomePath), true);
+    if (!home && upwd && upwd->pw_dir) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)upwd->pw_dir, strlen(upwd->pw_dir), true);
+    if (fallBackToHome && !home) homePath = __CFgetenv("HOME");
+    if (fallBackToHome && !home && homePath) home = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)homePath, strlen(homePath), true);
+    
     return home;
 }
 
-static void _CFUpdateUserInfo(void) { // __CFPlatformCacheLock must be locked on entry and will be on exit
-    struct passwd *upwd;
-
-    __CFEUID = geteuid();
-    __CFUID = getuid();
-    if (__CFHomeDirectory)  CFRelease(__CFHomeDirectory);
-    __CFHomeDirectory = NULL;
-    if (__CFUserName) CFRelease(__CFUserName);
-    __CFUserName = NULL;
-
-    upwd = getpwuid(__CFEUID ? __CFEUID : __CFUID);
-    __CFHomeDirectory = _CFCopyHomeDirURLForUser(upwd);
-    if (!__CFHomeDirectory) {
-        const char *cpath = __CFgetenv("HOME");
-        if (cpath) {
-            __CFHomeDirectory = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)cpath, strlen(cpath), true);
-        }
-    }
+#endif
+
+
+#define CFMaxHostNameLength    256
+#define CFMaxHostNameSize      (CFMaxHostNameLength+1)
+
+__private_extern__ CFStringRef _CFStringCreateHostName(void) {
+    char myName[CFMaxHostNameSize];
+
+    // return @"" instead of nil a la CFUserName() and Ali Ozer
+    if (0 != gethostname(myName, CFMaxHostNameSize)) myName[0] = '\0';
+    return CFStringCreateWithCString(kCFAllocatorSystemDefault, myName, kCFPlatformInterfaceStringEncoding);
+}
+
+/* These are sanitized versions of the above functions. We might want to eliminate the above ones someday.
+   These can return NULL.
+*/
+CF_EXPORT CFStringRef CFGetUserName(void) {
+    return CFCopyUserName();
+}
 
-    // This implies that UserManager stores directory info in CString
-    // rather than FileSystemRep.  Perhaps this is wrong & we should
-    // expect NeXTSTEP encodings.  A great test of our localized system would
-    // be to have a user "O-umlat z e r".  XXX
+CF_EXPORT CFStringRef CFCopyUserName(void) {
+    CFStringRef result = NULL;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    uid_t euid;
+    __CFGetUGIDs(&euid, NULL);
+    struct passwd *upwd = getpwuid(euid ? euid : getuid());
     if (upwd && upwd->pw_name) {
-        __CFUserName = CFStringCreateWithCString(kCFAllocatorSystemDefault, upwd->pw_name, kCFPlatformInterfaceStringEncoding);
+        result = CFStringCreateWithCString(kCFAllocatorSystemDefault, upwd->pw_name, kCFPlatformInterfaceStringEncoding);
     } else {
         const char *cuser = __CFgetenv("USER");
-        if (cuser)
-            __CFUserName = CFStringCreateWithCString(kCFAllocatorSystemDefault, cuser, kCFPlatformInterfaceStringEncoding);
+        if (cuser) {
+            result = CFStringCreateWithCString(kCFAllocatorSystemDefault, cuser, kCFPlatformInterfaceStringEncoding);
+        }
     }
-}
+#elif DEPLOYMENT_TARGET_WINDOWS
+       wchar_t username[1040];
+       DWORD size = 1040;
+       username[0] = 0;
+       if (GetUserNameW(username, &size)) {
+           // discount the extra NULL by decrementing the size
+           result = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)username, size - 1);
+       } else {
+           const char *cname = __CFgetenv("USERNAME");
+           if (cname) {
+                result = CFStringCreateWithCString(kCFAllocatorSystemDefault, cname, kCFPlatformInterfaceStringEncoding);
+            }
+       }
+#else
+#error Dont know how to compute user name on this platform
 #endif
+    if (!result)
+        result = (CFStringRef)CFRetain(CFSTR(""));
+    return result;
+}
 
-static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { // __CFPlatformCacheLock must be locked on entry and will be on exit
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    if (!uName) {
-        if (geteuid() != __CFEUID || getuid() != __CFUID || !__CFHomeDirectory)
-            _CFUpdateUserInfo();
-        if (__CFHomeDirectory) CFRetain(__CFHomeDirectory);
-        return __CFHomeDirectory;
-    } else {
-        struct passwd *upwd = NULL;
-        char buf[128], *user;
-        SInt32 len = CFStringGetLength(uName), size = CFStringGetMaximumSizeForEncoding(len, kCFPlatformInterfaceStringEncoding);
-        CFIndex usedSize;
-        if (size < 127) {
-            user = buf;
-        } else {
-            user = CFAllocatorAllocate(kCFAllocatorSystemDefault, size+1, 0);
-            if (__CFOASafe) __CFSetLastAllocationEventName(user, "CFUtilities (temp)");
-        }
-        if (CFStringGetBytes(uName, CFRangeMake(0, len), kCFPlatformInterfaceStringEncoding, 0, true, (uint8_t *)user, size, &usedSize) == len) {
-            user[usedSize] = '\0';
-            upwd = getpwnam(user);
-        }
-        if (buf != user) {
-            CFAllocatorDeallocate(kCFAllocatorSystemDefault, user);
-        }
-        return _CFCopyHomeDirURLForUser(upwd);
-    }
+CFURLRef CFCopyHomeDirectoryURL(void) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    uid_t euid;
+    __CFGetUGIDs(&euid, NULL);
+    struct passwd *upwd = getpwuid(euid ? euid : getuid());
+    return _CFCopyHomeDirURLForUser(upwd, true);
 #elif DEPLOYMENT_TARGET_WINDOWS
-    // This code can only get the directory for the current user
-    if (uName && !CFEqual(uName, _CFUserName())) {
-        CFLog(kCFLogLevelError, CFSTR("CFCopyHomeDirectoryURLForUser(): Unable to get home directory for other user"));
-        return NULL;
-    }
-    
     CFURLRef retVal = NULL;
     CFIndex len = 0;
     CFStringRef str = NULL;
-    
+   
     UniChar pathChars[MAX_PATH];
     if (S_OK == SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT, (wchar_t *)pathChars)) {
         len = (CFIndex)wcslen((wchar_t *)pathChars);
@@ -338,7 +299,7 @@ static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { // __CFPla
         retVal = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, kCFURLWindowsPathStyle, true);
         CFRelease(str);
     }
-    
+
     if (!retVal) {
         // Fall back to environment variable, but this will not be unicode compatible
         const char *cpath = __CFgetenv("HOMEPATH");
@@ -352,7 +313,7 @@ static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { // __CFPla
             CFRelease(str);
         }
     }
-    
+
     if (!retVal) {
         // Last resort: We have to get "some" directory location, so fall-back to the processes current directory.
         UniChar currDir[MAX_PATH];
@@ -364,7 +325,7 @@ static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { // __CFPla
             CFRelease(str);
         }
     }
-    
+
     // We could do more here (as in KB Article Q101507). If that article is to be believed, we should only run into this case on Win95, or through user error.
     CFStringRef testPath = CFURLCopyFileSystemPath(retVal, kCFURLWindowsPathStyle);
     if (CFStringGetLength(testPath) == 0) {
@@ -372,76 +333,54 @@ static CFURLRef _CFCreateHomeDirectoryURLForUser(CFStringRef uName) { // __CFPla
         retVal = NULL;
     }
     if (testPath) CFRelease(testPath);
-    
+
     return retVal;
 #else
 #error Dont know how to compute users home directories on this platform
 #endif
 }
 
-static CFStringRef _CFUserName(void) { // __CFPlatformCacheLock must be locked on entry and will be on exit
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
-    if (geteuid() != __CFEUID || getuid() != __CFUID)
-       _CFUpdateUserInfo();
+CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+    if (!uName) {
+        uid_t euid;
+        __CFGetUGIDs(&euid, NULL);
+        struct passwd *upwd = getpwuid(euid ? euid : getuid());
+        return _CFCopyHomeDirURLForUser(upwd, true);
+    } else {
+        struct passwd *upwd = NULL;
+        char buf[128], *user;
+        SInt32 len = CFStringGetLength(uName), size = CFStringGetMaximumSizeForEncoding(len, kCFPlatformInterfaceStringEncoding);
+        CFIndex usedSize;
+        if (size < 127) {
+            user = buf;
+        } else {
+            user = CFAllocatorAllocate(kCFAllocatorSystemDefault, size+1, 0);
+        }
+        if (CFStringGetBytes(uName, CFRangeMake(0, len), kCFPlatformInterfaceStringEncoding, 0, true, (uint8_t *)user, size, &usedSize) == len) {
+            user[usedSize] = '\0';
+            upwd = getpwnam(user);
+        }
+        if (buf != user) {
+            CFAllocatorDeallocate(kCFAllocatorSystemDefault, user);
+        }
+        return _CFCopyHomeDirURLForUser(upwd, false);
+    }
 #elif DEPLOYMENT_TARGET_WINDOWS
-    if (!__CFUserName) {
-       wchar_t username[1040];
-       DWORD size = 1040;
-       username[0] = 0;
-       if (GetUserNameW(username, &size)) {
-           // discount the extra NULL by decrementing the size
-           __CFUserName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)username, size - 1);
-       } else {
-           const char *cname = __CFgetenv("USERNAME");
-           if (cname)
-                __CFUserName = CFStringCreateWithCString(kCFAllocatorSystemDefault, cname, kCFPlatformInterfaceStringEncoding);
-       }
+    // This code can only get the directory for the current user
+    CFStringRef userName = uName ? CFCopyUserName() : NULL;
+    if (uName && !CFEqual(uName, userName)) {
+        CFLog(kCFLogLevelError, CFSTR("CFCopyHomeDirectoryURLForUser(): Unable to get home directory for other user"));
+        if (userName) CFRelease(userName);
+        return NULL;
     }
+    if (userName) CFRelease(userName);
+    return CFCopyHomeDirectoryURL();
 #else
-#error Dont know how to compute user name on this platform
+#error Dont know how to compute users home directories on this platform
 #endif
-    if (!__CFUserName)
-        __CFUserName = (CFStringRef)CFRetain(CFSTR(""));
-    return __CFUserName;
 }
 
-#define CFMaxHostNameLength    256
-#define CFMaxHostNameSize      (CFMaxHostNameLength+1)
-
-__private_extern__ CFStringRef _CFStringCreateHostName(void) {
-    char myName[CFMaxHostNameSize];
-
-    // return @"" instead of nil a la CFUserName() and Ali Ozer
-    if (0 != gethostname(myName, CFMaxHostNameSize)) myName[0] = '\0';
-    return CFStringCreateWithCString(kCFAllocatorSystemDefault, myName, kCFPlatformInterfaceStringEncoding);
-}
-
-/* These are sanitized versions of the above functions. We might want to eliminate the above ones someday.
-   These can return NULL.
-*/
-CF_EXPORT CFStringRef CFGetUserName(void) {
-    CFStringRef result = NULL;
-    __CFSpinLock(&__CFPlatformCacheLock);
-    result = CFStringCreateCopy(kCFAllocatorSystemDefault, _CFUserName());
-    __CFSpinUnlock(&__CFPlatformCacheLock);
-    return result;
-}
-
-CF_EXPORT CFStringRef CFCopyUserName(void) {
-    CFStringRef result = NULL;
-    __CFSpinLock(&__CFPlatformCacheLock);
-    result = CFStringCreateCopy(kCFAllocatorSystemDefault, _CFUserName());
-    __CFSpinUnlock(&__CFPlatformCacheLock);
-    return result;
-}
-
-CF_EXPORT CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName) {
-    CFURLRef result = NULL;
-    __CFSpinLock(&__CFPlatformCacheLock);
-    result = _CFCreateHomeDirectoryURLForUser(uName);
-    __CFSpinUnlock(&__CFPlatformCacheLock);
-    return result;
-}
 
 #undef CFMaxHostNameLength
 #undef CFMaxHostNameSize
@@ -570,7 +509,7 @@ CF_EXPORT int _NS_pthread_main_np() {
 // If thread data has been torn down, these functions should crash on CF_TSD_BAD_PTR + slot address.
 #define CF_TSD_MAX_SLOTS 70
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define CF_TSD_KEY 55
 #endif
 
@@ -627,7 +566,7 @@ __private_extern__ void __CFTSDLinuxInitialize() {
 #endif
 
 static void __CFTSDSetSpecific(void *arg) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     pthread_setspecific(CF_TSD_KEY, arg);
 #elif DEPLOYMENT_TARGET_LINUX
     pthread_setspecific(__CFTSDIndexKey, arg);
@@ -637,7 +576,7 @@ static void __CFTSDSetSpecific(void *arg) {
 }
 
 static void *__CFTSDGetSpecific() {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     return pthread_getspecific(CF_TSD_KEY);
 #elif DEPLOYMENT_TARGET_LINUX
     return pthread_getspecific(__CFTSDIndexKey);
@@ -647,7 +586,7 @@ static void *__CFTSDGetSpecific() {
 }
 
 static void __CFTSDFinalize(void *arg) {
-    // Set our TSD so we're called again by pthreads. It will call the destructor 5 times as long as a value is set in the thread specific data. We handle each case below.
+    // Set our TSD so we're called again by pthreads. It will call the destructor PTHREAD_DESTRUCTOR_ITERATIONS times as long as a value is set in the thread specific data. We handle each case below.
     __CFTSDSetSpecific(arg);
 
     if (!arg || arg == CF_TSD_BAD_PTR) {
@@ -658,12 +597,9 @@ static void __CFTSDFinalize(void *arg) {
     __CFTSDTable *table = (__CFTSDTable *)arg;
     table->destructorCount++;
         
-    // On 1st, 2nd, 3rd, 4th calls, invoke destructor
+    // On first calls invoke destructor. Later we destroy the data.
     // Note that invocation of the destructor may cause a value to be set again in the per-thread data slots. The destructor count and destructors are preserved.  
     // This logic is basically the same as what pthreads does. We just skip the 'created' flag.
-#if COCOA_ARR0
-    uintptr_t pool = _CFAutoreleasePoolPush();
-#endif
     for (int32_t i = 0; i < CF_TSD_MAX_SLOTS; i++) {
         if (table->data[i] && table->destructors[i]) {
             uintptr_t old = table->data[i];
@@ -671,11 +607,8 @@ static void __CFTSDFinalize(void *arg) {
             table->destructors[i]((void *)(old));
         }
     }
-#if COCOA_ARR0
-    _CFAutoreleasePoolPop(pool);
-#endif
     
-    if (table->destructorCount == PTHREAD_DESTRUCTOR_ITERATIONS - 1) {    // On 4th call, destroy our data
+    if (table->destructorCount == PTHREAD_DESTRUCTOR_ITERATIONS - 1) {    // On PTHREAD_DESTRUCTOR_ITERATIONS-1 call, destroy our data
         free(table);
         
         // Now if the destructor is called again we will take the shortcut at the beginning of this function.
@@ -684,7 +617,7 @@ static void __CFTSDFinalize(void *arg) {
     }
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 extern int pthread_key_init_np(int, void (*)(void *));
 #endif
 
@@ -700,7 +633,7 @@ static __CFTSDTable *__CFTSDGetTable() {
         // This memory is freed in the finalize function
         table = (__CFTSDTable *)calloc(1, sizeof(__CFTSDTable));
         // Windows and Linux have created the table already, we need to initialize it here for other platforms. On Windows, the cleanup function is called by DllMain when a thread exits. On Linux the destructor is set at init time.
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         pthread_key_init_np(CF_TSD_KEY, __CFTSDFinalize);
 #endif
         __CFTSDSetSpecific(table);
@@ -747,6 +680,7 @@ CF_EXPORT void *_CFSetTSD(uint32_t slot, void *newVal, tsdDestructor destructor)
     return oldVal;
 }
 
+
 #pragma mark -
 #pragma mark Windows Wide to UTF8 and UTF8 to Wide
 
@@ -952,9 +886,7 @@ CF_EXPORT int _NS_mkstemp(char *name, int bufSize) {
     return fd;    
 }
 
-#endif
 
-#if DEPLOYMENT_TARGET_WINDOWS
 // Utilities to convert from a volume name to a drive letter
 
 Boolean _isAFloppy(char driveLetter)
@@ -1086,6 +1018,35 @@ extern CFStringRef CFCreateWindowsDrivePathFromVolumeName(CFStringRef volNameStr
     return drivePathResult;
 }
 
+struct timezone {
+    int        tz_minuteswest; /* minutes west of Greenwich */
+    int        tz_dsttime;     /* type of dst correction */
+};
+
+__private_extern__ int _NS_gettimeofday(struct timeval *tv, struct timezone *tz) {
+    if (tv) {
+        FILETIME ft;
+        GetSystemTimeAsFileTime(&ft);
+        unsigned __int64 t = 0;
+        t |= ft.dwHighDateTime;
+        t <<= 32;
+        t |= ft.dwLowDateTime;
+        
+        // Convert to microseconds
+        t /= 10;
+        
+        // Difference between 1/1/1970 and 1/1/1601
+        t -= 11644473600000000Ui64;
+        
+        // Convert microseconds to seconds
+        tv->tv_sec = (long)(t / 1000000UL);
+        tv->tv_usec = (long)(t % 1000000UL);
+    }
+    
+    // We don't support tz
+    return 0;
+}
+
 #endif // DEPLOYMENT_TARGET_WINDOWS
 
 #pragma mark -
@@ -1175,3 +1136,4 @@ __private_extern__ int asprintf(char **ret, const char *format, ...) {
 }
 
 #endif
+
index 5c1a5addec2e8223ffebc89d082deca1cdddebe6..b4b8d09c0739b8388d8bcc8ee3c6636f57e7dfb9 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlatformConverters.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -30,7 +30,6 @@
 #include <CoreFoundation/CFString.h>
 #include "CFStringEncodingConverterExt.h"
 #include <CoreFoundation/CFStringEncodingExt.h>
-#include <CoreFoundation/CFPreferences.h>
 #include "CFUniChar.h"
 #include "CFUnicodeDecomposition.h"
 #include "CFStringEncodingConverterPriv.h"
@@ -62,7 +61,17 @@ static const CFStringEncodingConverter __CFPlatformBootstrap = {
 
 __private_extern__ const CFStringEncodingConverter *__CFStringEncodingGetExternalConverter(uint32_t encoding) {
 
-    return (__CFIsPlatformConverterAvailable(encoding) ? &__CFPlatformBootstrap : (__CFStringEncodingGetICUName(encoding) ? &__CFICUBootstrap : NULL)); // we prefer Text Encoding Converter ICU since it's more reliable
+    // we prefer Text Encoding Converter ICU since it's more reliable
+    if (__CFIsPlatformConverterAvailable(encoding)) {
+        return &__CFPlatformBootstrap;
+    } else {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+        if (__CFStringEncodingGetICUName(encoding)) {
+            return &__CFICUBootstrap;
+        }
+#endif
+        return NULL;
+    }
 }
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
@@ -173,7 +182,7 @@ __private_extern__ CFIndex __CFStringEncodingPlatformBytesToUnicode(uint32_t enc
         dwFlags |= (flags & (kCFStringEncodingUseCanonical|kCFStringEncodingUseHFSPlusCanonical) ? MB_COMPOSITE : MB_PRECOMPOSED);
     }
 
-    if ((usedLen = MultiByteToWideChar(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCSTR)bytes, numBytes, (LPWSTR)characters, maxCharLen) == 0)) {
+    if ((usedLen = MultiByteToWideChar(CFStringConvertEncodingToWindowsCodepage(encoding), dwFlags, (LPCSTR)bytes, numBytes, (LPWSTR)characters, maxCharLen)) == 0) {
         if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
             CPINFO cpInfo;
 
index 6f805fa11e86466febcb7599e34213a7bce6675b..1a28795f831589c128fc5e0a47804816418849ce 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 /*      CFPlugIn.c
-        Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
 #include "CFBundle_Internal.h"
@@ -43,35 +43,49 @@ __private_extern__ void __CFPlugInInitialize(void) {
 /* Functions for finding factories to create specific types and actually creating instances of a type. */
 
 CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInType(CFUUIDRef typeID) {
-    CFArrayRef array = _CFPFactoryFindForType(typeID);
+    CFArrayRef array = _CFPFactoryFindCopyForType(typeID);
     CFMutableArrayRef result = NULL;
     
     if (array) {
         SInt32 i, c = CFArrayGetCount(array);
         result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
-        for (i = 0; i < c; i++) CFArrayAppendValue(result, _CFPFactoryGetFactoryID((_CFPFactory *)CFArrayGetValueAtIndex(array, i)));
+        for (i = 0; i < c; i++) {
+            CFUUIDRef factoryId = _CFPFactoryCopyFactoryID((_CFPFactoryRef)CFArrayGetValueAtIndex(array, i));
+            if (factoryId) {
+                CFArrayAppendValue(result, factoryId);
+                CFRelease(factoryId);
+            }
+        }
+        CFRelease(array);
     }
     return result;
 }
 
 CF_EXPORT CFArrayRef CFPlugInFindFactoriesForPlugInTypeInPlugIn(CFUUIDRef typeID, CFPlugInRef plugIn) {
-    CFArrayRef array = _CFPFactoryFindForType(typeID);
+    CFArrayRef array = _CFPFactoryFindCopyForType(typeID);
     CFMutableArrayRef result = NULL;
 
     if (array) {
         SInt32 i, c = CFArrayGetCount(array);
-        _CFPFactory *factory;
+        _CFPFactoryRef factory;
         result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
         for (i = 0; i < c; i++) {
-            factory = (_CFPFactory *)CFArrayGetValueAtIndex(array, i);
-            if (_CFPFactoryGetPlugIn(factory) == plugIn) CFArrayAppendValue(result, _CFPFactoryGetFactoryID(factory));
+            factory = (_CFPFactoryRef )CFArrayGetValueAtIndex(array, i);
+            CFPlugInRef factoryPlugIn = _CFPFactoryCopyPlugIn(factory);
+            if (factoryPlugIn == plugIn) {
+                CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(factory);
+                CFArrayAppendValue(result, factoryId);
+                CFRelease(factoryId);
+            }
+            if (factoryPlugIn) CFRelease(factoryPlugIn);
         }
+        CFRelease(array);
     }
     return result;
 }
 
 CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFUUIDRef typeID) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
     void *result = NULL;
     if (!factory) {
         /* MF:!!! No such factory. */
@@ -94,7 +108,7 @@ CF_EXPORT void *CFPlugInInstanceCreate(CFAllocatorRef allocator, CFUUIDRef facto
 CF_EXPORT Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
     // Create factories without plugIns from default allocator
     // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists
-    // _CFPFactory *factory =
+    // _CFPFactoryRef factory =
     (void)_CFPFactoryCreate(kCFAllocatorSystemDefault, factoryID, func);
     return true;
 }
@@ -102,13 +116,13 @@ CF_EXPORT Boolean CFPlugInRegisterFactoryFunction(CFUUIDRef factoryID, CFPlugInF
 CF_EXPORT Boolean CFPlugInRegisterFactoryFunctionByName(CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef functionName) {
     // Create factories with plugIns from plugIn's allocator
     // MF:!!! Should probably check that this worked, and maybe do some pre-checking to see if it already exists
-    // _CFPFactory *factory =
+    // _CFPFactoryRef factory =
     (void)_CFPFactoryCreateByName(CFGetAllocator(plugIn), factoryID, plugIn, functionName);
     return true;
 }
 
 CF_EXPORT Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryID) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
     
     if (!factory) {
         /* MF:!!! Error.  No factory registered for this ID. */
@@ -119,7 +133,7 @@ CF_EXPORT Boolean CFPlugInUnregisterFactory(CFUUIDRef factoryID) {
 }
 
 CF_EXPORT Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
 
     if (!factory) {
         /* MF:!!! Error.  Factory must be registered (and not disabled) before types can be associated with it. */
@@ -130,7 +144,7 @@ CF_EXPORT Boolean CFPlugInRegisterPlugInType(CFUUIDRef factoryID, CFUUIDRef type
 }
 
 CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryID, CFUUIDRef typeID) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
 
     if (!factory) {
         /* MF:!!! Error.  Could not find factory. */
@@ -146,7 +160,7 @@ CF_EXPORT Boolean CFPlugInUnregisterPlugInType(CFUUIDRef factoryID, CFUUIDRef ty
 /* 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) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
 
     if (!factory) {
         /* MF:!!! Error.  Could not find factory. */
@@ -156,7 +170,7 @@ CF_EXPORT void CFPlugInAddInstanceForFactory(CFUUIDRef factoryID) {
 }
 
 CF_EXPORT void CFPlugInRemoveInstanceForFactory(CFUUIDRef factoryID) {
-    _CFPFactory *factory = _CFPFactoryFind(factoryID, true);
+    _CFPFactoryRef factory = _CFPFactoryFind(factoryID, true);
 
     if (!factory) {
         /* MF:!!! Error.  Could not find factory. */
index 318d3e4ed0d360a5ad9aa58b0eeadf85ebf29722..d51e0bef05f4516d300c8a202d914cc15fdb3c65 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGIN__)
index f48fee3868a84b02b2e13bc6913a1c77eb85ba83..cc41e52dfc1ed1a654235216182da05215f6e8ec 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugInCOM.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGINCOM__)
index 1e99031eb304bdd95943d07542c719a580073deb..b65a86a63d4c95441b644d8ab43d6d60aff88f41 100644 (file)
  */
 
 /*     CFPlugIn_Factory.c
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
 #include "CFBundle_Internal.h"
 #include "CFInternal.h"
 
-static CFSpinLock_t CFPlugInGlobalDataLock = CFSpinLockInit;
-static CFMutableDictionaryRef _factoriesByFactoryID = NULL; /* Value is _CFPFactory */
-static CFMutableDictionaryRef _factoriesByTypeID = NULL; /* Value is array of _CFPFactory */
+static CFTypeID __kCFPFactoryTypeID = _kCFRuntimeNotATypeID;
 
-static void _CFPFactoryAddToTable(_CFPFactory *factory) {
-    __CFSpinLock(&CFPlugInGlobalDataLock);
+struct __CFPFactory {
+    CFRuntimeBase _base;
+        
+    CFUUIDRef _uuid;
+    Boolean _enabled;
+    char _padding[3];
+    
+    CFPlugInFactoryFunction _func;
+    
+    CFPlugInRef _plugIn;
+    CFStringRef _funcName;
+    
+    CFMutableArrayRef _types;
+    CFSpinLock_t _lock;
+};
+
+static void _CFPFactoryDeallocate(CFTypeRef factory);
+
+static const CFRuntimeClass __CFPFactoryClass = {
+    0,
+    "_CFPFactory",
+    NULL,      // init
+    NULL,      // copy
+    _CFPFactoryDeallocate,
+    NULL,      // equal
+    NULL,      // hash
+    NULL,       // formatting desc
+    NULL,       // debug desc
+};
+
+__private_extern__ void __CFPFactoryInitialize(void) {
+    __kCFPFactoryTypeID = _CFRuntimeRegisterClass(&__CFPFactoryClass);
+}
+
+static CFTypeID _CFPFactoryGetTypeID(void) {
+    return __kCFPFactoryTypeID;
+}
+
+static CFSpinLock_t CFPlugInGlobalDataLock = CFSpinLockInit;
+static CFMutableDictionaryRef _factoriesByFactoryID = NULL; /* Value is _CFPFactoryRef */
+static CFMutableDictionaryRef _factoriesByTypeID = NULL; /* Value is array of _CFPFactoryRef */
+
+static void _CFPFactoryAddToTable(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);
+    CFUUIDRef uuid = (CFUUIDRef)CFRetain(factory->_uuid);
+    CFRetain(factory);
+    __CFSpinUnlock(&factory->_lock);
+    
+    __CFSpinLock(&CFPlugInGlobalDataLock);    
     if (!_factoriesByFactoryID) {
         CFDictionaryValueCallBacks _factoryDictValueCallbacks = {0, NULL, NULL, NULL, NULL};
         _factoriesByFactoryID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &_factoryDictValueCallbacks);
     }
-    CFDictionarySetValue(_factoriesByFactoryID, factory->_uuid, factory);
+    CFDictionarySetValue(_factoriesByFactoryID, uuid, factory);
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
+    
+    if (uuid) CFRelease(uuid);
+    CFRelease(factory);
 }
 
-static void _CFPFactoryRemoveFromTable(_CFPFactory *factory) {
+static void _CFPFactoryRemoveFromTable(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);
+    CFUUIDRef uuid = factory->_uuid;
+    if (uuid) CFRetain(uuid);
+    __CFSpinUnlock(&factory->_lock);
+    
     __CFSpinLock(&CFPlugInGlobalDataLock);
-    if (_factoriesByFactoryID) CFDictionaryRemoveValue(_factoriesByFactoryID, factory->_uuid);
+    if (uuid && _factoriesByTypeID) CFDictionaryRemoveValue(_factoriesByFactoryID, uuid);
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
+    
+    if (uuid) CFRelease(uuid);
 }
 
-__private_extern__ _CFPFactory *_CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
-    _CFPFactory *result = NULL;
+__private_extern__ _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled) {
+    _CFPFactoryRef result = NULL;
     
     __CFSpinLock(&CFPlugInGlobalDataLock);
     if (_factoriesByFactoryID) {
-        result = (_CFPFactory *)CFDictionaryGetValue(_factoriesByFactoryID, factoryID);
+        result = (_CFPFactoryRef )CFDictionaryGetValue(_factoriesByFactoryID, factoryID);
         if (result && result->_enabled != enabled) result = NULL;
     }
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
     return result;
 }
 
-static void _CFPFactoryDeallocate(_CFPFactory *factory) {
-    CFAllocatorRef allocator = factory->_allocator;
+static void _CFPFactoryDeallocate(CFTypeRef ty) {
     SInt32 c;
+    _CFPFactoryRef factory = (_CFPFactoryRef)ty;
     
     _CFPFactoryRemoveFromTable(factory);
 
-    if (factory->_plugIn) _CFPlugInRemoveFactory(factory->_plugIn, factory);
-
+    if (factory->_plugIn) {
+        _CFPlugInRemoveFactory(factory->_plugIn, factory);
+        CFRelease(factory->_plugIn);
+    }
+    
     /* Remove all types for this factory. */
     c = CFArrayGetCount(factory->_types);
     while (c-- > 0) _CFPFactoryRemoveType(factory, (CFUUIDRef)CFArrayGetValueAtIndex(factory->_types, c));
@@ -76,65 +134,70 @@ static void _CFPFactoryDeallocate(_CFPFactory *factory) {
 
     if (factory->_funcName) CFRelease(factory->_funcName);
     if (factory->_uuid) CFRelease(factory->_uuid);
-
-    CFAllocatorDeallocate(allocator, factory);
-    CFRelease(allocator);
 }
 
-static _CFPFactory *_CFPFactoryCommonCreate(CFAllocatorRef allocator, CFUUIDRef factoryID) {
-    _CFPFactory *factory;
-    UInt32 size;
-    size = sizeof(_CFPFactory);
-    allocator = (allocator ? (CFAllocatorRef)CFRetain(allocator) : (CFAllocatorRef)CFRetain(__CFGetDefaultAllocator()));
-    factory = (_CFPFactory *)CFAllocatorAllocate(allocator, size, 0);
-    if (!factory) {
-        CFRelease(allocator);
-        return NULL;
-    }
+static _CFPFactoryRef _CFPFactoryCommonCreate(CFAllocatorRef allocator, CFUUIDRef factoryID) {
+    _CFPFactoryRef factory;
+    uint32_t size;
+    size = sizeof(struct __CFPFactory) - sizeof(CFRuntimeBase);
+    factory = (_CFPFactoryRef)_CFRuntimeCreateInstance(allocator, _CFPFactoryGetTypeID(), size, NULL);
+    if (!factory) return NULL;
 
-    factory->_allocator = allocator;
     factory->_uuid = (CFUUIDRef)CFRetain(factoryID);
     factory->_enabled = true;
-    factory->_instanceCount = 0;
-
-    _CFPFactoryAddToTable(factory);
-
     factory->_types = CFArrayCreateMutable(allocator, 0, &kCFTypeArrayCallBacks);
+    factory->_lock = CFSpinLockInit; // WARNING: grab global lock before this lock
+        
+    _CFPFactoryAddToTable(factory);
 
     return factory;
 }
 
-__private_extern__ _CFPFactory *_CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
-    _CFPFactory *factory = _CFPFactoryCommonCreate(allocator, factoryID);
+__private_extern__ _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func) {
+    _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);
 
+    __CFSpinLock(&factory->_lock);    
     factory->_func = func;
     factory->_plugIn = NULL;
     factory->_funcName = NULL;
+    __CFSpinUnlock(&factory->_lock);
 
     return factory;
 }
 
-__private_extern__ _CFPFactory *_CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
-    _CFPFactory *factory = _CFPFactoryCommonCreate(allocator, factoryID);
+__private_extern__ _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName) {
+    _CFPFactoryRef factory = _CFPFactoryCommonCreate(allocator, factoryID);
 
+    __CFSpinLock(&factory->_lock);    
     factory->_func = NULL;
-    factory->_plugIn = plugIn;
+    factory->_plugIn = (CFPlugInRef)CFRetain(plugIn);
     if (plugIn) _CFPlugInAddFactory(plugIn, factory);
     factory->_funcName = (funcName ? (CFStringRef)CFStringCreateCopy(allocator, funcName) : NULL);
+    __CFSpinUnlock(&factory->_lock);
 
     return factory;
 }
 
-__private_extern__ CFUUIDRef _CFPFactoryGetFactoryID(_CFPFactory *factory) {
-    return factory->_uuid;
+__private_extern__ CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);
+    CFUUIDRef uuid = factory->_uuid;
+    if (uuid) CFRetain(uuid);
+    __CFSpinUnlock(&factory->_lock);
+    return uuid;
 }
 
-__private_extern__ CFPlugInRef _CFPFactoryGetPlugIn(_CFPFactory *factory) {
-    return factory->_plugIn;
+__private_extern__ CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);
+    CFPlugInRef result = factory->_plugIn;
+    if (result) CFRetain(result);
+    __CFSpinUnlock(&factory->_lock);
+    return result;
 }
 
-__private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactory *factory, CFUUIDRef typeID) {
+__private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID) {
     void *result = NULL;
+
+    __CFSpinLock(&factory->_lock);
     if (factory->_enabled) {
         if (!factory->_func) {
             factory->_func = (CFPlugInFactoryFunction)CFBundleGetFunctionPointerForName(factory->_plugIn, factory->_funcName);
@@ -142,40 +205,45 @@ __private_extern__ void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CF
         }
         if (factory->_func) {
             // UPPGOOP
-            FAULT_CALLBACK((void **)&(factory->_func));
-            result = (void *)INVOKE_CALLBACK2(factory->_func, allocator, typeID);
+            CFPlugInFactoryFunction f = factory->_func;
+            __CFSpinUnlock(&factory->_lock);
+            FAULT_CALLBACK((void **)&(f));
+            result = (void *)INVOKE_CALLBACK2(f, allocator, typeID);
+            __CFSpinLock(&factory->_lock);
         }
     } else {
         CFLog(__kCFLogPlugIn, CFSTR("Factory %@ is disabled"), factory->_uuid);
-    }
+    }    
+    __CFSpinUnlock(&factory->_lock);
+
     return result;
 }
 
-__private_extern__ void _CFPFactoryDisable(_CFPFactory *factory) {
+__private_extern__ void _CFPFactoryDisable(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);    
     factory->_enabled = false;
-    if (factory->_instanceCount == 0) _CFPFactoryDeallocate(factory);
-}
-
-__private_extern__ Boolean _CFPFactoryIsEnabled(_CFPFactory *factory) {
-    return factory->_enabled;
+    __CFSpinUnlock(&factory->_lock);
+    CFRelease(factory);
 }
 
-__private_extern__ void _CFPFactoryFlushFunctionCache(_CFPFactory *factory) {
+__private_extern__ 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);
     factory->_func = NULL;
+    __CFSpinUnlock(&factory->_lock);
 }
 
-__private_extern__ void _CFPFactoryAddType(_CFPFactory *factory, CFUUIDRef typeID) {
-    CFMutableArrayRef array;
-    
+__private_extern__ 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 */
     CFArrayAppendValue(factory->_types, typeID);
+    __CFSpinUnlock(&factory->_lock);
 
-    /* Add the factory to the type's array of factories */
     __CFSpinLock(&CFPlugInGlobalDataLock);
     if (!_factoriesByTypeID) _factoriesByTypeID = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
+    CFMutableArrayRef array = (CFMutableArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
     if (!array) {
         CFArrayCallBacks _factoryArrayCallbacks = {0, NULL, NULL, NULL, NULL};
         // Create this from default allocator
@@ -187,12 +255,14 @@ __private_extern__ void _CFPFactoryAddType(_CFPFactory *factory, CFUUIDRef typeI
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
 }
 
-__private_extern__ void _CFPFactoryRemoveType(_CFPFactory *factory, CFUUIDRef typeID) {
+__private_extern__ void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID) {
     /* Remove it from the factory's type list */
     SInt32 idx;
 
+    __CFSpinLock(&factory->_lock);
     idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID);
     if (idx >= 0) CFArrayRemoveValueAtIndex(factory->_types, idx);
+    __CFSpinUnlock(&factory->_lock);
 
     /* Remove the factory from the type's list of factories */
     __CFSpinLock(&CFPlugInGlobalDataLock);
@@ -209,33 +279,50 @@ __private_extern__ void _CFPFactoryRemoveType(_CFPFactory *factory, CFUUIDRef ty
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
 }
 
-__private_extern__ Boolean _CFPFactorySupportsType(_CFPFactory *factory, CFUUIDRef typeID) {
+__private_extern__ Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID) {
     SInt32 idx;
 
+    __CFSpinLock(&factory->_lock);
     idx = CFArrayGetFirstIndexOfValue(factory->_types, CFRangeMake(0, CFArrayGetCount(factory->_types)), typeID);
+    __CFSpinUnlock(&factory->_lock);
+    
     return (idx >= 0 ? true : false);
 }
 
-__private_extern__ CFArrayRef _CFPFactoryFindForType(CFUUIDRef typeID) {
+__private_extern__ CFArrayRef _CFPFactoryFindCopyForType(CFUUIDRef typeID) {
     CFArrayRef result = NULL;
-
     __CFSpinLock(&CFPlugInGlobalDataLock);
-    if (_factoriesByTypeID) result = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
+    if (_factoriesByTypeID) {
+        result = (CFArrayRef)CFDictionaryGetValue(_factoriesByTypeID, typeID);
+        if (result) CFRetain(result);
+    }
     __CFSpinUnlock(&CFPlugInGlobalDataLock);
 
     return result;
 }
 
 /* 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(_CFPFactory *factory) {
+__private_extern__ void _CFPFactoryAddInstance(_CFPFactoryRef factory) {
     /* MF:!!! Assert that factory is enabled. */
-    factory->_instanceCount++;
-    if (factory->_plugIn) _CFPlugInAddPlugInInstance(factory->_plugIn);
+    CFRetain(factory);
+    __CFSpinLock(&factory->_lock);
+    CFPlugInRef plugin = factory->_plugIn;
+    if (plugin) CFRetain(plugin);
+    __CFSpinUnlock(&factory->_lock);
+    if (plugin) {
+        _CFPlugInAddPlugInInstance(plugin);
+        CFRelease(plugin);
+    }    
 }
 
-__private_extern__ void _CFPFactoryRemoveInstance(_CFPFactory *factory) {
-    /* MF:!!! Assert that _instanceCount > 0. */
-    factory->_instanceCount--;
-    if (factory->_plugIn) _CFPlugInRemovePlugInInstance(factory->_plugIn);
-    if (factory->_instanceCount == 0 && !factory->_enabled) _CFPFactoryDeallocate(factory);
+__private_extern__ void _CFPFactoryRemoveInstance(_CFPFactoryRef factory) {
+    __CFSpinLock(&factory->_lock);
+    CFPlugInRef plugin = factory->_plugIn;
+    if (plugin) CFRetain(plugin);
+    __CFSpinUnlock(&factory->_lock);
+    if (plugin) {
+        _CFPlugInRemovePlugInInstance(factory->_plugIn);
+        CFRelease(plugin);
+    }
+    CFRelease(factory);
 }
index e4a37cdffd9a852969fa8012d5df3e84086bf6c1..2b4320a57212f7f070e1162c38e6669d0fc95e84 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPlugIn_Factory.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPLUGIN_FACTORY__)
 
 CF_EXTERN_C_BEGIN
 
-typedef struct __CFPFactory {
-    CFAllocatorRef _allocator;
+typedef struct __CFPFactory *_CFPFactoryRef;
 
-    CFUUIDRef _uuid;
-    Boolean _enabled;
-    char _padding[3];
-    SInt32 _instanceCount;
+extern _CFPFactoryRef _CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func);
+extern _CFPFactoryRef _CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName);
 
-    CFPlugInFactoryFunction _func;
-    
-    CFPlugInRef _plugIn;
-    CFStringRef _funcName;
+extern _CFPFactoryRef _CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled);
 
-    CFMutableArrayRef _types;
-} _CFPFactory;
+extern CFUUIDRef _CFPFactoryCopyFactoryID(_CFPFactoryRef factory);
+extern CFPlugInRef _CFPFactoryCopyPlugIn(_CFPFactoryRef factory);
 
-extern _CFPFactory *_CFPFactoryCreate(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInFactoryFunction func);
-extern _CFPFactory *_CFPFactoryCreateByName(CFAllocatorRef allocator, CFUUIDRef factoryID, CFPlugInRef plugIn, CFStringRef funcName);
+extern void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactoryRef factory, CFUUIDRef typeID);
+extern void _CFPFactoryDisable(_CFPFactoryRef factory);
 
-extern _CFPFactory *_CFPFactoryFind(CFUUIDRef factoryID, Boolean enabled);
+extern void _CFPFactoryFlushFunctionCache(_CFPFactoryRef factory);
 
-extern CFUUIDRef _CFPFactoryGetFactoryID(_CFPFactory *factory);
-extern CFPlugInRef _CFPFactoryGetPlugIn(_CFPFactory *factory);
+extern void _CFPFactoryAddType(_CFPFactoryRef factory, CFUUIDRef typeID);
+extern void _CFPFactoryRemoveType(_CFPFactoryRef factory, CFUUIDRef typeID);
 
-extern void *_CFPFactoryCreateInstance(CFAllocatorRef allocator, _CFPFactory *factory, CFUUIDRef typeID);
-extern void _CFPFactoryDisable(_CFPFactory *factory);
-extern Boolean _CFPFactoryIsEnabled(_CFPFactory *factory);
-
-extern void _CFPFactoryFlushFunctionCache(_CFPFactory *factory);
-
-extern void _CFPFactoryAddType(_CFPFactory *factory, CFUUIDRef typeID);
-extern void _CFPFactoryRemoveType(_CFPFactory *factory, CFUUIDRef typeID);
-
-extern Boolean _CFPFactorySupportsType(_CFPFactory *factory, CFUUIDRef typeID);
-extern CFArrayRef _CFPFactoryFindForType(CFUUIDRef typeID);
+extern Boolean _CFPFactorySupportsType(_CFPFactoryRef factory, CFUUIDRef typeID);
+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. */
-extern void _CFPFactoryAddInstance(_CFPFactory *factory);
-extern void _CFPFactoryRemoveInstance(_CFPFactory *factory);
+extern void _CFPFactoryAddInstance(_CFPFactoryRef factory);
+extern void _CFPFactoryRemoveInstance(_CFPFactoryRef factory);
 
 CF_EXTERN_C_END
 
index 62b1611683857db822a2e50b16d4eea168511e2e..afc17eb1c2231edc30549cc09566d362c032c99c 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 /*     CFPlugIn_Instance.c
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
 #include "CFBundle_Internal.h"
@@ -34,7 +34,7 @@ static CFTypeID __kCFPlugInInstanceTypeID = _kCFRuntimeNotATypeID;
 struct __CFPlugInInstance {
     CFRuntimeBase _base;
     
-    _CFPFactory *factory;
+    _CFPFactoryRef factory;
     
     CFPlugInInstanceGetInterfaceFunction getInterfaceFunction;
     CFPlugInInstanceDeallocateInstanceDataFunction deallocateInstanceDataFunction;
@@ -115,7 +115,9 @@ CF_EXPORT Boolean CFPlugInInstanceGetInterfaceFunctionTable(CFPlugInInstanceRef
 }
 
 CF_EXPORT CFStringRef CFPlugInInstanceGetFactoryName(CFPlugInInstanceRef instance) {
-    return (CFStringRef)_CFPFactoryGetFactoryID(instance->factory);
+    // This function leaks, but it's the only safe way to access the factory name
+    CFUUIDRef factoryId = _CFPFactoryCopyFactoryID(instance->factory);
+    return (CFStringRef)factoryId;
 }
 
 CF_EXPORT void *CFPlugInInstanceGetInstanceData(CFPlugInInstanceRef instance) {
index ce89300a092b0a277016aa64557958c6f0cd49f1..c922f8cf45e250fe36d6088f49203f86c3a11261 100644 (file)
@@ -22,8 +22,8 @@
  */
 
 /*      CFPlugIn_PlugIn.c
-        Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
-        Responsibility: David Smith
+        Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
+        Responsibility: Tony Parker
 */
 
 #include "CFBundle_Internal.h"
@@ -154,7 +154,7 @@ __private_extern__ void _CFBundleDeallocatePlugIn(CFBundleRef bundle) {
 
         /* Go through factories disabling them.  Disabling these factories should cause them to dealloc since we wouldn't be deallocating if any of the factories had outstanding instances.  So go backwards. */
         c = CFArrayGetCount(__CFBundleGetPlugInData(bundle)->_factories);
-        while (c-- > 0) _CFPFactoryDisable((_CFPFactory *)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(bundle)->_factories, c));
+        while (c-- > 0) _CFPFactoryDisable((_CFPFactoryRef)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(bundle)->_factories, c));
         CFRelease(__CFBundleGetPlugInData(bundle)->_factories);
 
         __CFBundleGetPlugInData(bundle)->_isPlugIn = false;
@@ -200,7 +200,7 @@ __private_extern__ 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. */
-        while (c-- > 0) _CFPFactoryFlushFunctionCache((_CFPFactory *)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, c));
+        while (c-- > 0) _CFPFactoryFlushFunctionCache((_CFPFactoryRef)CFArrayGetValueAtIndex(__CFBundleGetPlugInData(plugIn)->_factories, c));
     }
 }
 
@@ -228,11 +228,11 @@ __private_extern__ void _CFPlugInRemovePlugInInstance(CFPlugInRef plugIn) {
     }
 }
 
-__private_extern__ void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactory *factory) {
+__private_extern__ void _CFPlugInAddFactory(CFPlugInRef plugIn, _CFPFactoryRef factory) {
     if (__CFBundleGetPlugInData(plugIn)->_isPlugIn) CFArrayAppendValue(__CFBundleGetPlugInData(plugIn)->_factories, factory);
 }
 
-__private_extern__ void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactory *factory) {
+__private_extern__ 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 5f6280dbdcce4a49345044788b89df38cdadf20c..5364c3433c8bdb86bf24a247df58b95aadce8dae 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPreferences.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index 3d838862edaf7e55fb65359504af24ed6d5f0bd2..9a59a265a927f261c3994f6a293335257dab9ab3 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPreferences.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPREFERENCES__)
index 34306c464688f81c34918787cac158ecc886b3e7..3ce670281a5313c23591d936fb1a48bef60424fe 100644 (file)
--- a/CFPriv.h
+++ b/CFPriv.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFPriv.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 /*
@@ -39,6 +39,7 @@
 #include <CoreFoundation/CFURL.h>
 #include <CoreFoundation/CFLocale.h>
 #include <CoreFoundation/CFDate.h>
+#include <CoreFoundation/CFSet.h>
 #include <math.h>
 
 
@@ -64,11 +65,14 @@ CF_EXPORT const char **_CFGetProcessPath(void);
 CF_EXPORT const char **_CFGetProgname(void);
 
 
+#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX))
+CF_EXPORT void _CFRunLoopSetCurrent(CFRunLoopRef rl);
+#endif
+
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
 CF_EXPORT CFRunLoopRef CFRunLoopGetMain(void);
 CF_EXPORT SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled);
 
-CF_EXPORT void _CFRunLoopSetCurrent(CFRunLoopRef rl);
 
 CF_EXPORT void _CFRunLoopStopMode(CFRunLoopRef rl, CFStringRef modeName);
 
@@ -96,12 +100,11 @@ CFURLRef _CFCreateURLFromFSSpec(CFAllocatorRef alloc, const struct FSSpec *voids
 #endif
 #endif
 
-enum {
+typedef CF_ENUM(CFIndex, CFURLComponentDecomposition) {
        kCFURLComponentDecompositionNonHierarchical,
        kCFURLComponentDecompositionRFC1808, /* use this for RFC 1738 decompositions as well */
        kCFURLComponentDecompositionRFC2396
 };
-typedef CFIndex CFURLComponentDecomposition;
 
 typedef struct {
        CFStringRef scheme;
@@ -179,7 +182,7 @@ CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);  /* Pass NULL for the
        directories!
        ??? On MacOS 8 this function currently returns an empty array.
 */
-enum {
+typedef CF_ENUM(CFIndex, CFSearchPathDirectory) {
     kCFApplicationDirectory = 1,       /* supported applications (Applications) */
     kCFDemoApplicationDirectory,       /* unsupported applications, demonstration versions (Demos) */
     kCFDeveloperApplicationDirectory,  /* developer applications (Developer/Applications) */
@@ -189,19 +192,32 @@ enum {
     kCFUserDirectory,                  /* user home directories (Users) */
     kCFDocumentationDirectory,         /* documentation (Documentation) */
     kCFDocumentDirectory,              /* documents (Library/Documents) */
+
+    kCFCoreServiceDirectory = 10,            // location of CoreServices directory (System/Library/CoreServices)
+    kCFAutosavedInformationDirectory = 11,   // location of autosaved documents (Documents/Autosaved)
+    kCFDesktopDirectory = 12,                // location of user's desktop
+    kCFCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
+    kCFApplicationSupportDirectory = 14,     // location of application support files (plug-ins, etc) (Library/Application Support)
+    kCFDownloadsDirectory = 15,              // location of the user's "Downloads" directory
+    kCFInputMethodsDirectory = 16,           // input methods (Library/Input Methods)
+    kCFMoviesDirectory = 17,                 // location of user's Movies directory (~/Movies)
+    kCFMusicDirectory = 18,                  // location of user's Music directory (~/Music)
+    kCFPicturesDirectory = 19,               // location of user's Pictures directory (~/Pictures)
+    kCFPrinterDescriptionDirectory = 20,     // location of system's PPDs directory (Library/Printers/PPDs)
+    kCFSharedPublicDirectory = 21,           // location of user's Public sharing directory (~/Public)
+    kCFPreferencePanesDirectory = 22,        // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes)
+
     kCFAllApplicationsDirectory = 100, /* all directories where applications can occur (ie Applications, Demos, Administration, Developer/Applications) */
     kCFAllLibrariesDirectory = 101     /* all directories where resources can occur (Library, Developer) */
 };
-typedef CFIndex CFSearchPathDirectory;
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFSearchPathDomainMask) {
     kCFUserDomainMask = 1,     /* user's home directory --- place to install user's personal items (~) */
     kCFLocalDomainMask = 2,    /* local to the current machine --- place to install items available to everyone on this machine (/Local) */
     kCFNetworkDomainMask = 4,  /* publically available location in the local area network --- place to install items available on the network (/Network) */
     kCFSystemDomainMask = 8,   /* provided by Apple, unmodifiable (/System) */
     kCFAllDomainsMask = 0x0ffff        /* all domains: all of the above and more, future items */
 };
-typedef CFOptionFlags CFSearchPathDomainMask;
 
 CF_EXPORT
 CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directory, CFSearchPathDomainMask domainMask, Boolean expandTilde);
@@ -238,7 +254,7 @@ CF_EXPORT void CFQSortArray(void *list, CFIndex count, CFIndex elementSize, CFCo
 
   Note that for non-MACH this function always returns true.
 */
-enum {
+typedef CF_ENUM(CFIndex, CFSystemVersion) {
     CFSystemVersionCheetah = 0,         /* 10.0 */
     CFSystemVersionPuma = 1,            /* 10.1 */
     CFSystemVersionJaguar = 2,          /* 10.2 */
@@ -247,21 +263,20 @@ enum {
     CFSystemVersionLeopard = 5,         /* 10.5 */
     CFSystemVersionSnowLeopard = 6,    /* 10.6 */
     CFSystemVersionLion = 7,           /* 10.7 */
+    CFSystemVersionMountainLion = 8,    /* 10.8 */
     CFSystemVersionMax,                 /* This should bump up when new entries are added */
 
 };
-typedef CFIndex CFSystemVersion;
 
 CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version);
 
 
-enum {
+typedef CF_ENUM(CFIndex, CFStringCharacterClusterType) {
     kCFStringGraphemeCluster = 1, /* Unicode Grapheme Cluster */
     kCFStringComposedCharacterCluster = 2, /* Compose all non-base (including spacing marks) */
     kCFStringCursorMovementCluster = 3, /* Cluster suitable for cursor movements */
     kCFStringBackwardDeletionCluster = 4 /* Cluster suitable for backward deletion */
 };
-typedef CFIndex CFStringCharacterClusterType;
 
 CF_EXPORT CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex charIndex, CFStringCharacterClusterType type);
 
@@ -492,8 +507,19 @@ CF_INLINE struct timespec _CFFileTimeSpecFromAbsoluteTime(CFAbsoluteTime at) {
    return ts;
 }
 
+// The 'filtered' function below is preferred to this older one
 CF_EXPORT bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFStringRef keyPath, CFPropertyListRef *value, CFErrorRef *error);
 
+// 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);
+
+// 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
+} CF_ENUM_AVAILABLE(10_8, 6_0);
+
+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);
 
 #if TARGET_OS_WIN32
 #include <CoreFoundation/CFNotificationCenter.h>
@@ -521,6 +547,11 @@ CF_EXPORT void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFString
 
 CF_EXPORT CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRef allocator, CFArrayRef tmplates, CFOptionFlags options, CFLocaleRef locale);
 
+#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
+// Available for internal use on embedded
+CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
+#endif
+
 
 CF_EXTERN_C_END
 
index 7cc7f6d4f118473ebade6363bd5338a75aa2de89..b22218c5dff126678ec50a1eb8a350708992808e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPropertyList.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -34,7 +34,9 @@
 #include <CoreFoundation/CFError_Private.h>
 #include <CoreFoundation/CFPriv.h>
 #include <CoreFoundation/CFStringEncodingConverter.h>
-#include <CoreFoundation/CFInternal.h>
+#include "CFInternal.h"
+#include <CoreFoundation/CFBurstTrie.h>
+#include <CoreFoundation/CFString.h>
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
 #include <CoreFoundation/CFStream.h>
 #endif
 #define DOCTYPE_TAG_LENGTH     7
 #define CDSECT_TAG_LENGTH      9
 
-#if DEPLOYMENT_TARGET_MACOSX
-// Set for some exceptional circumstances, like running out of memory
-extern char * __crashreporter_info__;
-
-#define out_of_memory_warning() \
-    do { \
-        __crashreporter_info__ = "CFPropertyList ran out of memory while attempting to allocate temporary storage."; \
-    } while (0)
-#else
-#define out_of_memory_warning() do {} while (0)
-#endif
-
 #if !defined(new_cftype_array)
 #define new_cftype_array(N, C) \
     size_t N ## _count__ = (C); \
     if (N ## _count__ > LONG_MAX / sizeof(CFTypeRef)) { \
-        out_of_memory_warning(); \
+        CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); \
         HALT; \
     } \
     Boolean N ## _is_stack__ = (N ## _count__ <= 256); \
@@ -100,7 +90,7 @@ extern char * __crashreporter_info__;
     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); \
     if (! N) { \
-        out_of_memory_warning(); \
+        CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); \
         HALT; \
     } \
     do {} while (0)
@@ -117,42 +107,22 @@ extern char * __crashreporter_info__;
 // Used to reference an old-style plist parser error inside of a more general XML error
 #define CFPropertyListOldStyleParserErrorKey     CFSTR("kCFPropertyListOldStyleParsingError")
 
-// don't allow _CFKeyedArchiverUID here
-#define __CFAssertIsPList(cf) CFAssert2(CFGetTypeID(cf) == CFStringGetTypeID() || CFGetTypeID(cf) == CFArrayGetTypeID() || CFGetTypeID(cf) == CFBooleanGetTypeID() || CFGetTypeID(cf) == CFNumberGetTypeID() || CFGetTypeID(cf) == CFDictionaryGetTypeID() || CFGetTypeID(cf) == CFDateGetTypeID() || CFGetTypeID(cf) == CFDataGetTypeID(), __kCFLogAssertion, "%s(): %p not of a property list type", __PRETTY_FUNCTION__, cf);
-
-static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive, CFMutableSetRef set, CFPropertyListFormat format, CFStringRef *error);
-
-static CFTypeID stringtype = -1, datatype = -1, numbertype = -1, datetype = -1;
-static CFTypeID booltype = -1, nulltype = -1, dicttype = -1, arraytype = -1, settype = -1;
+static CFTypeID stringtype, datatype, numbertype, datetype;
+static CFTypeID booltype, nulltype, dicttype, arraytype, settype;
 
 static void initStatics() {
-    if ((CFTypeID)-1 == stringtype) {
+    static dispatch_once_t once;
+    dispatch_once(&once, ^{
         stringtype = CFStringGetTypeID();
-    }
-    if ((CFTypeID)-1 == datatype) {
-        datatype = CFDataGetTypeID();
-    }
-    if ((CFTypeID)-1 == numbertype) {
+        datatype = CFDataGetTypeID();        
         numbertype = CFNumberGetTypeID();
-    }
-    if ((CFTypeID)-1 == booltype) {
         booltype = CFBooleanGetTypeID();
-    }
-    if ((CFTypeID)-1 == datetype) {
         datetype = CFDateGetTypeID();
-    }
-    if ((CFTypeID)-1 == dicttype) {
         dicttype = CFDictionaryGetTypeID();
-    }
-    if ((CFTypeID)-1 == arraytype) {
         arraytype = CFArrayGetTypeID();
-    }
-    if ((CFTypeID)-1 == settype) {
         settype = CFSetGetTypeID();
-    }
-    if ((CFTypeID)-1 == nulltype) {
         nulltype = CFNullGetTypeID();
-    }
+    });
 }
 
 __private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...) {    
@@ -179,7 +149,7 @@ __private_extern__ CFErrorRef __CFPropertyListCreateError(CFIndex code, CFString
     return error;
 }
 
-CFStringRef __CFPropertyListCopyErrorDebugDescription(CFErrorRef error) {
+static CFStringRef __copyErrorDebugDescription(CFErrorRef error) {
     CFStringRef result = NULL;
     if (error) {
         CFDictionaryRef userInfo = CFErrorCopyUserInfo(error);
@@ -189,6 +159,11 @@ CFStringRef __CFPropertyListCopyErrorDebugDescription(CFErrorRef error) {
     return result;
 }
 
+#pragma mark -
+#pragma mark Property List Validation
+
+// don't allow _CFKeyedArchiverUID here
+#define __CFAssertIsPList(cf) CFAssert2(CFGetTypeID(cf) == CFStringGetTypeID() || CFGetTypeID(cf) == CFArrayGetTypeID() || CFGetTypeID(cf) == CFBooleanGetTypeID() || CFGetTypeID(cf) == CFNumberGetTypeID() || CFGetTypeID(cf) == CFDictionaryGetTypeID() || CFGetTypeID(cf) == CFDateGetTypeID() || CFGetTypeID(cf) == CFDataGetTypeID(), __kCFLogAssertion, "%s(): %p not of a property list type", __PRETTY_FUNCTION__, cf);
 
 struct context {
     bool answer;
@@ -197,6 +172,8 @@ struct context {
     CFStringRef *error;
 };
 
+static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive, CFMutableSetRef set, CFPropertyListFormat format, CFStringRef *error);
+
 static void __CFPropertyListIsArrayPlistAux(const void *value, void *context) {
     struct context *ctx = (struct context *)context;
     if (!ctx->answer) return;
@@ -263,22 +240,6 @@ static bool __CFPropertyListIsValidAux(CFPropertyListRef plist, bool recursive,
     return false;
 }
 
-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);
-    CFStringRef error = NULL;
-    bool result = __CFPropertyListIsValidAux(plist, true, set, format, &error);
-    if (error) {
-#if defined(DEBUG)
-       CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListIsValid(): %@"), error);
-#endif
-       CFRelease(error);
-    }
-    if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(set);
-    return result;
-}
-
 static Boolean _CFPropertyListIsValidWithErrorString(CFPropertyListRef plist, CFPropertyListFormat format, CFStringRef *error) {
     initStatics();
     CFAssert1(plist != NULL, __kCFLogAssertion, "%s(): NULL is not a property list", __PRETTY_FUNCTION__);
@@ -288,7 +249,10 @@ static Boolean _CFPropertyListIsValidWithErrorString(CFPropertyListRef plist, CF
     return result;
 }
 
-static const UniChar CFXMLPlistTags[13][10]= {
+#pragma mark -
+#pragma mark Writing Property Lists
+
+static const char CFXMLPlistTags[13][10]= {
 {'p', 'l', 'i', 's', 't',   '\0', '\0', '\0', '\0', '\0'},
 {'a', 'r', 'r', 'a', 'y',   '\0', '\0', '\0', '\0', '\0'},
 {'d', 'i', 'c', 't',  '\0', '\0', '\0', '\0', '\0', '\0'},
@@ -304,22 +268,40 @@ static const UniChar CFXMLPlistTags[13][10]= {
 {'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[',       '\0'}
 };
 
+static const UniChar CFXMLPlistTagsUnicode[13][10]= {
+    {'p', 'l', 'i', 's', 't',   '\0', '\0', '\0', '\0', '\0'},
+    {'a', 'r', 'r', 'a', 'y',   '\0', '\0', '\0', '\0', '\0'},
+    {'d', 'i', 'c', 't',  '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'k', 'e', 'y', '\0', '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'s', 't', 'r', 'i', 'n', 'g',    '\0', '\0', '\0', '\0'},
+    {'d', 'a', 't', 'a',  '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'d', 'a', 't', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'r', 'e', 'a', 'l',  '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'i', 'n', 't', 'e', 'g', 'e', 'r',     '\0', '\0', '\0'},
+    {'t', 'r', 'u', 'e',  '\0', '\0', '\0', '\0', '\0', '\0'},
+    {'f', 'a', 'l', 's', 'e',   '\0', '\0', '\0', '\0', '\0'},
+    {'D', 'O', 'C', 'T', 'Y', 'P', 'E',     '\0', '\0', '\0'},
+    {'<', '!', '[', 'C', 'D', 'A', 'T', 'A', '[',       '\0'}
+};
+
 typedef struct {
-    const UniChar *begin; // first character of the XML to be parsed
-    const UniChar *curr;  // current parse location
-    const UniChar *end;   // the first character _after_ the end of the XML
+    const char *begin; // first character of the XML to be parsed
+    const char *curr;  // current parse location
+    const char *end;   // the first character _after_ the end of the XML
     CFErrorRef error;
     CFAllocatorRef allocator;
     UInt32 mutabilityOption;
-    CFMutableSetRef stringSet;  // set of all strings involved in this parse; allows us to share non-mutable strings in the returned plist
+    CFBurstTrieRef stringTrie; // map of cached strings
+    CFMutableArrayRef stringCache; // retaining array of strings
     Boolean allowNewTypes; // Whether to allow the new types supported by XML property lists, but not by the old, OPENSTEP ASCII property lists (CFNumber, CFBoolean, CFDate)
-    char _padding[3];
+    CFSetRef keyPaths; // if NULL, no filtering
+    Boolean skip; // if true, do not create any objects.
 } _CFXMLPlistParseInfo;
 
-static CFTypeRef parseOldStylePropertyListOrStringsFile(_CFXMLPlistParseInfo *pInfo);
+__private_extern__ CFTypeRef __CFParseOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format);
 
-CF_INLINE void __CFPListRelease(CFTypeRef cf, _CFXMLPlistParseInfo *pInfo) {
-    if (cf && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRelease(cf);
+CF_INLINE void __CFPListRelease(CFTypeRef cf, CFAllocatorRef allocator) {
+    if (cf && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(cf);
 }
 
 
@@ -536,41 +518,41 @@ static void _CFAppendXML0(CFTypeRef object, UInt32 indentation, CFMutableDataRef
     _appendIndents(indentation, xmlString);
     if (typeID == stringtype) {
         _plistAppendUTF8CString(xmlString, "<");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[STRING_IX], STRING_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[STRING_IX], STRING_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">");
        _appendEscapedString((CFStringRef)object, xmlString);
         _plistAppendUTF8CString(xmlString, "</");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[STRING_IX], STRING_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[STRING_IX], STRING_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
     } else if (typeID == arraytype) {
         UInt32 i, count = CFArrayGetCount((CFArrayRef)object);
         if (count == 0) {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, "/>\n");
             return;
         }
         _plistAppendUTF8CString(xmlString, "<");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
         for (i = 0; i < count; i ++) {
             _CFAppendXML0(CFArrayGetValueAtIndex((CFArrayRef)object, i), indentation+1, xmlString);
         }
         _appendIndents(indentation, xmlString);
         _plistAppendUTF8CString(xmlString, "</");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[ARRAY_IX], ARRAY_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
     } else if (typeID == dicttype) {
         UInt32 i, count = CFDictionaryGetCount((CFDictionaryRef)object);
         CFMutableArrayRef keyArray;
         if (count == 0) {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, "/>\n");
             return;
         }
         _plistAppendUTF8CString(xmlString, "<");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
         new_cftype_array(keys, count);
         CFDictionaryGetKeysAndValues((CFDictionaryRef)object, keys, NULL);
@@ -583,27 +565,27 @@ static void _CFAppendXML0(CFTypeRef object, UInt32 indentation, CFMutableDataRef
             CFTypeRef key = keys[i];
             _appendIndents(indentation+1, xmlString);
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[KEY_IX], KEY_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">");
            _appendEscapedString((CFStringRef)key, xmlString);
             _plistAppendUTF8CString(xmlString, "</");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[KEY_IX], KEY_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[KEY_IX], KEY_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">\n");
             _CFAppendXML0(CFDictionaryGetValue((CFDictionaryRef)object, key), indentation+1, xmlString);
         }
         free_cftype_array(keys);
         _appendIndents(indentation, xmlString);
         _plistAppendUTF8CString(xmlString, "</");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DICT_IX], DICT_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
     } else if (typeID == datatype) {
         _plistAppendUTF8CString(xmlString, "<");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATA_IX], DATA_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
         _XMLPlistAppendDataUsingBase64(xmlString, (CFDataRef)object, indentation);       
         _appendIndents(indentation, xmlString);
         _plistAppendUTF8CString(xmlString, "</");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATA_IX], DATA_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
     } else if (typeID == datetype) {
         // YYYY '-' MM '-' DD 'T' hh ':' mm ':' ss 'Z'
@@ -625,42 +607,42 @@ static void _CFAppendXML0(CFTypeRef object, UInt32 indentation, CFMutableDataRef
        CFRelease(tz);
 #endif
         _plistAppendUTF8CString(xmlString, "<");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATE_IX], DATE_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">");
         _plistAppendFormat(xmlString, CFSTR("%04d-%02d-%02dT%02d:%02d:%02dZ"), y, M, d, H, m, s);
         _plistAppendUTF8CString(xmlString, "</");
-        _plistAppendCharacters(xmlString, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH);
+        _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[DATE_IX], DATE_TAG_LENGTH);
         _plistAppendUTF8CString(xmlString, ">\n");
     } else if (typeID == numbertype) {
         if (CFNumberIsFloatType((CFNumberRef)object)) {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[REAL_IX], REAL_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">");
                 CFStringRef s = __CFNumberCopyFormattingDescriptionAsFloat64(object);
                 _plistAppendString(xmlString, s);
                 CFRelease(s);
             _plistAppendUTF8CString(xmlString, "</");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[REAL_IX], REAL_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">\n");
         } else {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">");
 
             _plistAppendFormat(xmlString, CFSTR("%@"), object);
 
             _plistAppendUTF8CString(xmlString, "</");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[INTEGER_IX], INTEGER_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, ">\n");
         }
     } else if (typeID == booltype) {
         if (CFBooleanGetValue((CFBooleanRef)object)) {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[TRUE_IX], TRUE_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, "/>\n");
         } else {
             _plistAppendUTF8CString(xmlString, "<");
-            _plistAppendCharacters(xmlString, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH);
+            _plistAppendCharacters(xmlString, CFXMLPlistTagsUnicode[FALSE_IX], FALSE_TAG_LENGTH);
             _plistAppendUTF8CString(xmlString, "/>\n");
         }
     }
@@ -668,18 +650,22 @@ static void _CFAppendXML0(CFTypeRef object, UInt32 indentation, CFMutableDataRef
 
 static void _CFGenerateXMLPropertyListToData(CFMutableDataRef xml, CFTypeRef propertyList) {
     _plistAppendUTF8CString(xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE ");
-    _plistAppendCharacters(xml, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH);
+    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
     _plistAppendUTF8CString(xml, " PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<");
-    _plistAppendCharacters(xml, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH);
+    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
     _plistAppendUTF8CString(xml, " version=\"1.0\">\n");
 
     _CFAppendXML0(propertyList, 0, xml);
 
     _plistAppendUTF8CString(xml, "</");
-    _plistAppendCharacters(xml, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH);
+    _plistAppendCharacters(xml, CFXMLPlistTagsUnicode[PLIST_IX], PLIST_TAG_LENGTH);
     _plistAppendUTF8CString(xml, ">\n");
 }
 
+// ========================================================================
+#pragma mark -
+#pragma mark Exported Creation Functions
+
 CFDataRef _CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList, Boolean checkValidPlist) {
     initStatics();
     CFMutableDataRef xml;
@@ -701,18 +687,36 @@ CF_EXPORT CFDataRef _CFPropertyListCreateXMLDataWithExtras(CFAllocatorRef alloca
     return _CFPropertyListCreateXMLData(allocator, propertyList, false);
 }
 
+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);
+    CFStringRef error = NULL;
+    bool result = __CFPropertyListIsValidAux(plist, true, set, format, &error);
+    if (error) {
+#if defined(DEBUG)
+       CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListIsValid(): %@"), error);
+#endif
+       CFRelease(error);
+    }
+    if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(set);
+    return result;
+}
+
 // ========================================================================
+#pragma mark -
+#pragma mark Reading Plists
 
 //
 // ------------------------- Reading plists ------------------
 // 
 
 static void skipInlineDTD(_CFXMLPlistParseInfo *pInfo);
-static CFTypeRef parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey);
+static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out);
 
 // warning: doesn't have a good idea of Unicode line separators
 static UInt32 lineNumber(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *p = pInfo->begin;
+    const char *p = pInfo->begin;
     UInt32 count = 1;
     while (p < pInfo->curr) {
         if (*p == '\r') {
@@ -747,8 +751,8 @@ CF_INLINE void skipWhitespace(_CFXMLPlistParseInfo *pInfo) {
 
 // pInfo should be just past "<!--"
 static void skipXMLComment(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *p = pInfo->curr;
-    const UniChar *end = pInfo->end - 3; // Need at least 3 characters to compare against
+    const char *p = pInfo->curr;
+    const char *end = pInfo->end - 3; // Need at least 3 characters to compare against
     while (p < end) {
         if (*p == '-' && *(p+1) == '-' && *(p+2) == '>') {
             pInfo->curr = p+3;
@@ -759,27 +763,9 @@ static void skipXMLComment(_CFXMLPlistParseInfo *pInfo) {
     pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated comment started on line %d"), lineNumber(pInfo));
 }
 
-// stringToMatch and buf must both be of at least len
-static Boolean matchString(const UniChar *buf, const UniChar *stringToMatch, UInt32 len) {
-    switch (len) {
-       case 10: if (buf[9] != stringToMatch[9]) return false;
-       case 9: if (buf[8] != stringToMatch[8]) return false;
-       case 8: if (buf[7] != stringToMatch[7]) return false;
-       case 7: if (buf[6] != stringToMatch[6]) return false;
-       case 6: if (buf[5] != stringToMatch[5]) return false;
-       case 5: if (buf[4] != stringToMatch[4]) return false;
-       case 4: if (buf[3] != stringToMatch[3]) return false;
-       case 3: if (buf[2] != stringToMatch[2]) return false;
-       case 2: if (buf[1] != stringToMatch[1]) return false;
-       case 1: if (buf[0] != stringToMatch[0]) return false;
-       case 0: return true;
-    }
-    return false; // internal error
-}
-
 // pInfo should be set to the first character after "<?"
 static void skipXMLProcessingInstruction(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *begin = pInfo->curr, *end = pInfo->end - 2; // Looking for "?>" so we need at least 2 characters
+    const char *begin = pInfo->curr, *end = pInfo->end - 2; // Looking for "?>" so we need at least 2 characters
     while (pInfo->curr < end) {
         if (*(pInfo->curr) == '?' && *(pInfo->curr+1) == '>') {
             pInfo->curr += 2;
@@ -794,7 +780,7 @@ static void skipXMLProcessingInstruction(_CFXMLPlistParseInfo *pInfo) {
 // first character should be immediately after the "<!"
 static void skipDTD(_CFXMLPlistParseInfo *pInfo) {
     // First pass "DOCTYPE"
-    if (pInfo->end - pInfo->curr < DOCTYPE_TAG_LENGTH || !matchString(pInfo->curr, CFXMLPlistTags[DOCTYPE_IX], DOCTYPE_TAG_LENGTH)) {
+    if (pInfo->end - pInfo->curr < DOCTYPE_TAG_LENGTH || memcmp(pInfo->curr, CFXMLPlistTags[DOCTYPE_IX], DOCTYPE_TAG_LENGTH)) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed DTD on line %d"), lineNumber(pInfo));
         return;
     }
@@ -803,7 +789,7 @@ static void skipDTD(_CFXMLPlistParseInfo *pInfo) {
 
     // Look for either the beginning of a complex DTD or the end of the DOCTYPE structure
     while (pInfo->curr < pInfo->end) {
-        UniChar ch = *(pInfo->curr);
+        char ch = *(pInfo->curr);
         if (ch == '[') break; // inline DTD
         if (ch == '>') {  // End of the DTD
             pInfo->curr ++;
@@ -833,7 +819,7 @@ static void skipDTD(_CFXMLPlistParseInfo *pInfo) {
 }
 
 static void skipPERef(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *p = pInfo->curr;
+    const char *p = pInfo->curr;
     while (p < pInfo->end) {
         if (*p == ';') {
             pInfo->curr = p+1;
@@ -897,100 +883,24 @@ static void skipInlineDTD(_CFXMLPlistParseInfo *pInfo) {
     }
 }
 
-/* A bit wasteful to do everything with unichars (since we know all the characters we're going to see are 7-bit ASCII), but since our data is coming from or going to a CFString, this prevents the extra cost of converting formats. */
-
-static const signed char __CFPLDataDecodeTable[128] = {
-    /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
-    /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
-    /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
-    /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
-    /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
-    /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
-    /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
-    /* '8' */ 60, 61, -1, -1, -1,  0, -1, -1,
-    /* '@' */ -1,  0,  1,  2,  3,  4,  5,  6,
-    /* 'H' */  7,  8,  9, 10, 11, 12, 13, 14,
-    /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
-    /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
-    /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
-    /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
-    /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
-    /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
-};
-
-static CFDataRef __CFPLDataDecode(_CFXMLPlistParseInfo *pInfo, Boolean isMutable) {
-    int tmpbufpos = 0;
-    int tmpbuflen = 256;
-    uint8_t *tmpbuf;
-    int numeq = 0;
-    int acc = 0;
-    int cntr = 0;
-
-    tmpbuf = (uint8_t *)CFAllocatorAllocate(pInfo->allocator, tmpbuflen, 0);
-    for (; pInfo->curr < pInfo->end; pInfo->curr++) {
-        UniChar c = *(pInfo->curr);
-        if (c == '<') {
-            break;
-       }
-        if ('=' == c) {
-            numeq++;
-        } else if (!isspace(c)) {
-            numeq = 0;
-        }
-        if (__CFPLDataDecodeTable[c] < 0)
-            continue;
-        cntr++;
-        acc <<= 6;
-        acc += __CFPLDataDecodeTable[c];
-        if (0 == (cntr & 0x3)) {
-            if (tmpbuflen <= tmpbufpos + 2) {
-               if (tmpbuflen < 256 * 1024) {
-                   tmpbuflen *= 4;
-               } else if (tmpbuflen < 16 * 1024 * 1024) {
-                   tmpbuflen *= 2;
-               } else {
-                   // once in this stage, this will be really slow
-                   // and really potentially fragment memory
-                   tmpbuflen += 256 * 1024;
-               }
-                tmpbuf = (uint8_t *)CFAllocatorReallocate(pInfo->allocator, tmpbuf, tmpbuflen, 0);
-               if (!tmpbuf) HALT;
-            }
-            tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
-            if (numeq < 2)
-                tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
-            if (numeq < 1)
-                tmpbuf[tmpbufpos++] = acc & 0xff;
-        }
-    }
-    if (isMutable) {
-        CFMutableDataRef result = CFDataCreateMutable(pInfo->allocator, 0);
-        CFDataAppendBytes(result, tmpbuf, tmpbufpos);
-       CFAllocatorDeallocate(pInfo->allocator, tmpbuf);
-        return result;
-    } else {
-        return CFDataCreateWithBytesNoCopy(pInfo->allocator, tmpbuf, tmpbufpos, pInfo->allocator);
-    }
-}
-
 // content ::== (element | CharData | Reference | CDSect | PI | Comment)*
 // In the context of a plist, CharData, Reference and CDSect are not legal (they all resolve to strings).  Skipping whitespace, then, the next character should be '<'.  From there, we figure out which of the three remaining cases we have (element, PI, or Comment).
-static CFTypeRef getContentObject(_CFXMLPlistParseInfo *pInfo, Boolean *isKey) {
+static Boolean getContentObject(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out) {
     if (isKey) *isKey = false;
     while (!pInfo->error && pInfo->curr < pInfo->end) {
         skipWhitespace(pInfo);
         if (pInfo->curr >= pInfo->end) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
-            return NULL;
+            return false;
         }
         if (*(pInfo->curr) != '<') {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d"), *(pInfo->curr), lineNumber(pInfo));
-            return NULL;
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for open tag"), *(pInfo->curr), lineNumber(pInfo));
+            return false;
         }
         pInfo->curr ++;
         if (pInfo->curr >= pInfo->end) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
-            return NULL;
+            return false;
         }
         switch (*(pInfo->curr)) {
             case '?':
@@ -1001,43 +911,36 @@ static CFTypeRef getContentObject(_CFXMLPlistParseInfo *pInfo, Boolean *isKey) {
                 // Could be a comment
                 if (pInfo->curr+2 >= pInfo->end) {
                     pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
-                    return NULL;
+                    return false;
                 }
                 if (*(pInfo->curr+1) == '-' && *(pInfo->curr+2) == '-') {
                     pInfo->curr += 2;
                     skipXMLComment(pInfo);
                 } else {
                     pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
-                    return NULL;
+                    return false;
                 }
                 break;
             case '/':
                 // Whoops!  Looks like we got to the end tag for the element whose content we're parsing
                 pInfo->curr --; // Back off to the '<'
-                return NULL;
+                return false;
             default:
                 // Should be an element
-                return parseXMLElement(pInfo, isKey);
+                return parseXMLElement(pInfo, isKey, out);
         }
     }
     // Do not set the error string here; if it wasn't already set by one of the recursive parsing calls, the caller will quickly detect the failure (b/c pInfo->curr >= pInfo->end) and provide a more useful one of the form "end tag for <blah> not found"
-    return NULL;
-}
-
-static void _catFromMarkToBuf(const UniChar *mark, const UniChar *buf, CFMutableStringRef *string, _CFXMLPlistParseInfo *pInfo) {
-    if (!(*string)) {
-        *string = CFStringCreateMutable(pInfo->allocator, 0);
-    }
-    CFStringAppendCharacters(*string, mark, buf-mark);
+    return false;
 }
 
-static void parseCDSect_pl(_CFXMLPlistParseInfo *pInfo, CFMutableStringRef string) {
-    const UniChar *end, *begin;
+static void parseCDSect_pl(_CFXMLPlistParseInfo *pInfo, CFMutableDataRef stringData) {
+    const char *end, *begin;
     if (pInfo->end - pInfo->curr < CDSECT_TAG_LENGTH) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
         return;
     }
-    if (!matchString(pInfo->curr, CFXMLPlistTags[CDSECT_IX], CDSECT_TAG_LENGTH)) {
+    if (memcmp(pInfo->curr, CFXMLPlistTags[CDSECT_IX], CDSECT_TAG_LENGTH)) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered improper CDATA opening at line %d"), lineNumber(pInfo));
         return;
     }
@@ -1046,8 +949,8 @@ static void parseCDSect_pl(_CFXMLPlistParseInfo *pInfo, CFMutableStringRef strin
     end = pInfo->end-2; // So we can safely look 2 characters beyond p
     while (pInfo->curr < end) {
         if (*(pInfo->curr) == ']' && *(pInfo->curr+1) == ']' && *(pInfo->curr+2) == '>') {
-           // Found the end!
-            CFStringAppendCharacters(string, begin, pInfo->curr-begin);
+            // Found the end!
+            CFDataAppendBytes(stringData, (const UInt8 *)begin, pInfo->curr-begin);
             pInfo->curr += 3;
             return;
         }
@@ -1059,15 +962,16 @@ static void parseCDSect_pl(_CFXMLPlistParseInfo *pInfo, CFMutableStringRef strin
 }
 
 // Only legal references are {lt, gt, amp, apos, quote, #ddd, #xAAA}
-static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableStringRef string) {
+static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableDataRef stringData) {
     int len;
-    UniChar ch;
     pInfo->curr ++; // move past the '&';
-    len = pInfo->end - pInfo->curr; // how many characters we can safely scan
+    len = pInfo->end - pInfo->curr; // how many bytes we can safely scan
     if (len < 1) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
         return;
     }
+
+    char ch;
     switch (*(pInfo->curr)) {
         case 'l':  // "lt"
             if (len >= 3 && *(pInfo->curr+1) == 't' && *(pInfo->curr+2) == ';') {
@@ -1132,7 +1036,13 @@ static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableString
                 ch = *(pInfo->curr);
                 pInfo->curr ++;
                 if (ch == ';') {
-                    CFStringAppendCharacters(string, &num, 1);
+                    // The value in num always refers to the unicode code point. We'll have to convert since the calling function expects UTF8 data.
+                    CFStringRef oneChar = CFStringCreateWithBytes(pInfo->allocator, (const uint8_t *)&num, 2, kCFStringEncodingUnicode, NO);
+                    uint8_t tmpBuf[6]; // max of 6 bytes for UTF8
+                    CFIndex tmpBufLength = 0;
+                    CFStringGetBytes(oneChar, CFRangeMake(0, 1), kCFStringEncodingUTF8, 0, NO, tmpBuf, 6, &tmpBufLength);
+                    CFDataAppendBytes(stringData, tmpBuf, tmpBufLength);
+                    __CFPListRelease(oneChar, pInfo->allocator);
                     return;
                 }
                 if (!isHex) num = num*10;
@@ -1140,14 +1050,14 @@ static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableString
                 if (ch <= '9' && ch >= '0') {
                     num += (ch - '0');
                 } else if (!isHex) {
-                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(pInfo));
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d while parsing data"), ch, lineNumber(pInfo));
                     return;
                 } else if (ch >= 'a' && ch <= 'f') {
                     num += 10 + (ch - 'a');
                 } else if (ch >= 'A' && ch <= 'F') {
                     num += 10 + (ch - 'A');
                 } else {
-                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d"), ch, lineNumber(pInfo));
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c at line %d while parsing data"), ch, lineNumber(pInfo));
                     return;                    
                 }
             }
@@ -1158,71 +1068,58 @@ static void parseEntityReference_pl(_CFXMLPlistParseInfo *pInfo, CFMutableString
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown ampersand-escape sequence at line %d"), lineNumber(pInfo));
             return;
     }
-    CFStringAppendCharacters(string, &ch, 1);
+    CFDataAppendBytes(stringData, (const UInt8 *)&ch, 1);
 }
 
 extern void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex len);
 
-static CFStringRef _uniqueStringForString(_CFXMLPlistParseInfo *pInfo, CFStringRef stringToUnique) {
-    CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique);
-    if (!uniqued) {
-        uniqued = (CFStringRef)__CFStringCollectionCopy(pInfo->allocator, stringToUnique);
-        CFSetAddValue(pInfo->stringSet, uniqued);
-        __CFTypeCollectionRelease(pInfo->allocator, uniqued);
-    }
-    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
-    return uniqued;
-}
-
-static CFStringRef _uniqueStringForCharacters(_CFXMLPlistParseInfo *pInfo, const UniChar *base, CFIndex length) {
-    if (0 == length) return !_CFAllocatorIsGCRefZero(pInfo->allocator) ? (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;
-    Boolean use_stack = (length < 2048);
-    STACK_BUFFER_DECL(uint8_t, buffer, use_stack ? length + 1 : 1);
-    uint8_t *ascii = use_stack ? buffer : (uint8_t *)CFAllocatorAllocate(kCFAllocatorSystemDefault, length + 1, 0);
-    for (CFIndex idx = 0; idx < length; idx++) {
-        UniChar ch = base[idx];
-       if (ch < 0x80) {
-           ascii[idx] = (uint8_t)ch;
-        } else {
-           stringToUnique = CFStringCreateWithCharacters(pInfo->allocator, base, length);
-           break;
-       }
-    }
-    if (!stringToUnique) {
-        ascii[length] = '\0';
-        stringToUnique = CFStringCreateWithBytes(pInfo->allocator, ascii, length, kCFStringEncodingASCII, false);
-    }
-    if (ascii != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ascii);
-    CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique);
-    if (!uniqued) {
-        CFSetAddValue(pInfo->stringSet, stringToUnique);
-       uniqued = stringToUnique;
+static void _createStringMap(_CFXMLPlistParseInfo *pInfo) {
+    pInfo->stringTrie = CFBurstTrieCreate();
+    pInfo->stringCache = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
+}
+
+static void _cleanupStringMap(_CFXMLPlistParseInfo *pInfo) {
+    CFBurstTrieRelease(pInfo->stringTrie);
+    if (!_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRelease(pInfo->stringCache);
+}
+
+static CFStringRef _uniqueStringForUTF8Bytes(_CFXMLPlistParseInfo *pInfo, const char *base, CFIndex length) {
+    if (length == 0) return !_CFAllocatorIsGCRefZero(pInfo->allocator) ? (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);
+    } 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);
     }
-    __CFPListRelease(stringToUnique, pInfo);
-    if (uniqued && !_CFAllocatorIsGCRefZero(pInfo->allocator)) CFRetain(uniqued);
-    return uniqued;
+    return result;
 }
 
 // String could be comprised of characters, CDSects, or references to one of the "well-known" entities ('<', '>', '&', ''', '"')
-// returns a retained object in *string.
-static CFStringRef getString(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *mark = pInfo->curr; // At any time in the while loop below, the characters between mark and p have not yet been added to *string
-    CFMutableStringRef string = NULL;
+static Boolean parseStringTag(_CFXMLPlistParseInfo *pInfo, CFStringRef *out) {
+    const char *mark = pInfo->curr;
+    CFMutableDataRef stringData = NULL;
     while (!pInfo->error && pInfo->curr < pInfo->end) {
-        UniChar ch = *(pInfo->curr);
+        char ch = *(pInfo->curr);
         if (ch == '<') {
            if (pInfo->curr + 1 >= pInfo->end) break;
             // Could be a CDSect; could be the end of the string
             if (*(pInfo->curr+1) != '!') break; // End of the string
-            _catFromMarkToBuf(mark, pInfo->curr, &string, pInfo);
-            parseCDSect_pl(pInfo, string);
+            if (!stringData) stringData = CFDataCreateMutable(pInfo->allocator, 0);
+            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
+            parseCDSect_pl(pInfo, stringData); // TODO: move to return boolean
             mark = pInfo->curr;
         } else if (ch == '&') {
-            _catFromMarkToBuf(mark, pInfo->curr, &string, pInfo);
-            parseEntityReference_pl(pInfo, string);
+            if (!stringData) stringData = CFDataCreateMutable(pInfo->allocator, 0);
+            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
+            parseEntityReference_pl(pInfo, stringData); // TODO: move to return boolean
             mark = pInfo->curr;
         } else {
             pInfo->curr ++;
@@ -1230,29 +1127,60 @@ static CFStringRef getString(_CFXMLPlistParseInfo *pInfo) {
     }
 
     if (pInfo->error) {
-        __CFPListRelease(string, pInfo);
-        return NULL;
+        __CFPListRelease(stringData, pInfo->allocator);
+        return false;
     }
-    if (!string) {
-        if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-            CFStringRef uniqueString = _uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark);
-            return uniqueString;
+        
+    if (!stringData) {
+        if (pInfo->skip) {
+            *out = NULL;
         } else {
-            string = CFStringCreateMutable(pInfo->allocator, 0);
-            CFStringAppendCharacters(string, mark, pInfo->curr - mark);
-            return string;
+            if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
+                CFStringRef s = _uniqueStringForUTF8Bytes(pInfo, mark, pInfo->curr - mark);
+                if (!s) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
+                    return false;
+                }                    
+                *out = s;
+            } else {
+                CFStringRef s = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)mark, pInfo->curr - mark, kCFStringEncodingUTF8, NO);
+                if (!s) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
+                    return false;
+                }
+                *out = CFStringCreateMutableCopy(pInfo->allocator, 0, s);
+                __CFPListRelease(s, pInfo->allocator);
+            }
         }
+        return true;
+    } else {
+        if (pInfo->skip) {
+            *out = NULL;
+        } else {
+            CFDataAppendBytes(stringData, (const UInt8 *)mark, pInfo->curr - mark);
+            if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
+                CFStringRef s = _uniqueStringForUTF8Bytes(pInfo, (const char *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData));
+                if (!s) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
+                    return false;
+                }
+                *out = s;
+            } else {
+                CFStringRef s = CFStringCreateWithBytes(pInfo->allocator, (const UInt8 *)CFDataGetBytePtr(stringData), CFDataGetLength(stringData), kCFStringEncodingUTF8, NO);
+                if (!s) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding"));
+                    return false;
+                }
+                *out = CFStringCreateMutableCopy(pInfo->allocator, 0, s);
+                __CFPListRelease(s, pInfo->allocator);
+            }
+        }
+        __CFPListRelease(stringData, pInfo->allocator);
+        return true;
     }
-    _catFromMarkToBuf(mark, pInfo->curr, &string, pInfo);
-    if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-        CFStringRef uniqueString = _uniqueStringForString(pInfo, string);
-        __CFPListRelease(string, pInfo);
-        return uniqueString;
-    }
-    return string;
 }
 
-static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const UniChar *tag, CFIndex tagLen) {
+static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const char *tag, CFIndex tagLen) {
     if (pInfo->end - pInfo->curr < tagLen + 3) {
         if (!pInfo->error) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
@@ -1261,13 +1189,13 @@ static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const UniChar *tag,
     }
     if (*(pInfo->curr) != '<' || *(++pInfo->curr) != '/') {
         if (!pInfo->error) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d"), *(pInfo->curr), lineNumber(pInfo));
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for close tag"), *(pInfo->curr), lineNumber(pInfo));
         }
         return false;
     }
     pInfo->curr ++;
-    if (!matchString(pInfo->curr, tag, tagLen)) {
-        CFStringRef str = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, tag, tagLen, kCFAllocatorNull);
+    if (memcmp(pInfo->curr, tag, tagLen)) {
+        CFStringRef str = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const UInt8 *)tag, tagLen, kCFStringEncodingUTF8, NO);
         if (!pInfo->error) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Close tag on line %d does not match open tag %@"), lineNumber(pInfo), str);
         }
@@ -1284,7 +1212,7 @@ static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const UniChar *tag,
     }
     if (*(pInfo->curr) != '>') {
         if (!pInfo->error) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d"), *(pInfo->curr), lineNumber(pInfo));
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected character %c on line %d while looking for close tag"), *(pInfo->curr), lineNumber(pInfo));
         }
         return false;
     }
@@ -1293,34 +1221,33 @@ static Boolean checkForCloseTag(_CFXMLPlistParseInfo *pInfo, const UniChar *tag,
 }
 
 // pInfo should be set to the first content character of the <plist>
-static CFTypeRef parsePListTag(_CFXMLPlistParseInfo *pInfo) {
-    CFTypeRef result, tmp = NULL;
-    const UniChar *save;
-    result = getContentObject(pInfo, NULL);
-    if (!result) {
+static Boolean parsePListTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
+    CFTypeRef result = NULL;
+    if (!getContentObject(pInfo, NULL, &result)) {
         if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty plist tag"));
-        return NULL;
+        return false;
     }
-    save = pInfo->curr; // Save this in case the next step fails
-    tmp = getContentObject(pInfo, NULL);
-    if (tmp) {
+    const char *save = pInfo->curr; // Save this in case the next step fails
+    CFTypeRef tmp = NULL;
+    if (getContentObject(pInfo, NULL, &tmp)) {
         // Got an extra object
-        __CFPListRelease(tmp, pInfo);
-        __CFPListRelease(result, pInfo);
+        __CFPListRelease(tmp, pInfo->allocator);
+        __CFPListRelease(result, pInfo->allocator);
         pInfo->curr = save;
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected element at line %d (plist can only include one object)"), lineNumber(pInfo));
-        return NULL;
+        return false;
     }
     if (pInfo->error) {
         // Parse failed catastrophically
-        __CFPListRelease(result, pInfo);
-        return NULL;
+        __CFPListRelease(result, pInfo->allocator);
+        return false;
     }
-    if (checkForCloseTag(pInfo, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH)) {
-        return result;
+    if (!checkForCloseTag(pInfo, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH)) {
+        __CFPListRelease(result, pInfo->allocator);
+        return false;
     }
-    __CFPListRelease(result, pInfo);
-    return NULL;
+    *out = result;
+    return true;
 }
 
 static int allowImmutableCollections = -1;
@@ -1329,70 +1256,245 @@ static void checkImmutableCollections(void) {
     allowImmutableCollections = (NULL == __CFgetenv("CFPropertyListAllowImmutableCollections")) ? 0 : 1;
 }
 
-static CFTypeRef parseArrayTag(_CFXMLPlistParseInfo *pInfo) {
+// This converts the input value, a set of strings, into the form that's efficient for using during recursive decent parsing, a set of arrays
+static CFSetRef createTopLevelKeypaths(CFAllocatorRef allocator, CFSetRef keyPaths) {
+    if (!keyPaths) return NULL;
+    
+    CFIndex count = CFSetGetCount(keyPaths);
+    new_cftype_array(keyPathValues, count);
+    CFSetGetValues(keyPaths, keyPathValues);
+    CFMutableSetRef splitKeyPathSet = CFSetCreateMutable(allocator, count, &kCFTypeSetCallBacks);
+    for (CFIndex i = 0; i < count; i++) {
+        // Split each key path and add it to the split path set, which we will reference throughout parsing
+        CFArrayRef split = CFStringCreateArrayBySeparatingStrings(allocator, (CFStringRef)(keyPathValues[i]), CFSTR(":"));
+        CFSetAddValue(splitKeyPathSet, split);
+        __CFPListRelease(split, allocator);
+    }
+    free_cftype_array(keyPathValues);
+    return splitKeyPathSet;
+}
+
+// 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) {
+    if (!currentKeys) { *theseKeys = NULL; *nextKeys = NULL; return; }
+    
+    CFIndex count = CFSetGetCount(currentKeys);
+    
+    // For each array in the current key path set, grab the item at the start of the list and put it into theseKeys. The rest of the array goes into nextKeys.
+    CFMutableSetRef outTheseKeys = NULL;
+    CFMutableSetRef outNextKeys = NULL;
+    
+    new_cftype_array(currentKeyPaths, count);
+    CFSetGetValues(currentKeys, currentKeyPaths);
+    for (CFIndex i = 0; i < count; i++) {
+        CFArrayRef oneKeyPath = (CFArrayRef)currentKeyPaths[i];
+        CFIndex keyPathCount = CFArrayGetCount(oneKeyPath);
+        
+        if (keyPathCount > 0) {
+            if (!outTheseKeys) outTheseKeys = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
+            
+            CFSetAddValue(outTheseKeys, CFArrayGetValueAtIndex(oneKeyPath, 0));
+        }
+        
+        if (keyPathCount > 1) {
+            if (!outNextKeys) outNextKeys = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
+            
+            // Create an array with values from 1 - end of list
+            new_cftype_array(restOfKeys, keyPathCount - 1);
+            CFArrayGetValues(oneKeyPath, CFRangeMake(1, CFArrayGetCount(oneKeyPath) - 1), restOfKeys);
+            CFArrayRef newNextKeys = CFArrayCreate(allocator, restOfKeys, CFArrayGetCount(oneKeyPath) - 1, &kCFTypeArrayCallBacks);
+            CFSetAddValue(outNextKeys, newNextKeys);
+            __CFPListRelease(newNextKeys, allocator);
+            free_cftype_array(restOfKeys);
+            
+        }
+    }
+    
+    *theseKeys = outTheseKeys;
+    *nextKeys = outNextKeys;
+}
+
+static Boolean parseArrayTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
+    CFTypeRef tmp = NULL;
+
+    if (pInfo->skip) {
+        Boolean result = getContentObject(pInfo, NULL, &tmp);
+        while (result) {
+            if (tmp) {
+                // Shouldn't happen (if skipping, all content values should be null), but just in case
+                __CFPListRelease(tmp, pInfo->allocator);
+            }
+            result = getContentObject(pInfo, NULL, &tmp);
+        }
+        
+        if (pInfo->error) {
+            // getContentObject encountered a parse error
+            return false;
+        }
+        if (!checkForCloseTag(pInfo, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH)) {
+            return false;
+        } else {
+            *out = NULL;
+            return true;
+        }
+    }
+    
     CFMutableArrayRef array = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
-    CFTypeRef tmp = getContentObject(pInfo, NULL);
-    while (tmp) {
-        CFArrayAppendValue(array, tmp);
-        __CFPListRelease(tmp, pInfo);
-        tmp = getContentObject(pInfo, NULL);
+    Boolean result;
+    
+    CFIndex count = 0;
+    CFSetRef oldKeyPaths = pInfo->keyPaths;
+    CFSetRef newKeyPaths, keys;
+    __CFPropertyListCreateSplitKeypaths(pInfo->allocator, pInfo->keyPaths, &keys, &newKeyPaths);
+    
+    if (keys) {
+        CFStringRef countString = CFStringCreateWithFormat(pInfo->allocator, NULL, CFSTR("%ld"), count);
+        if (!CFSetContainsValue(keys, countString)) pInfo->skip = true;
+        __CFPListRelease(countString, pInfo->allocator);
+        count++;
+        pInfo->keyPaths = newKeyPaths;
     }
+    result = getContentObject(pInfo, NULL, &tmp);
+    if (keys) {
+        pInfo->keyPaths = oldKeyPaths;
+        pInfo->skip = false;
+    }
+
+    while (result) {
+        if (tmp) {
+            CFArrayAppendValue(array, tmp);
+            __CFPListRelease(tmp, pInfo->allocator);
+        }
+        
+        if (keys) {
+            // prep for getting next object
+            CFStringRef countString = CFStringCreateWithFormat(pInfo->allocator, NULL, CFSTR("%ld"), count);
+            if (!CFSetContainsValue(keys, countString)) pInfo->skip = true;
+            __CFPListRelease(countString, pInfo->allocator);
+            count++;
+            pInfo->keyPaths = newKeyPaths;
+        }
+        result = getContentObject(pInfo, NULL, &tmp);
+        if (keys) {
+            // reset after getting object
+            pInfo->keyPaths = oldKeyPaths;
+            pInfo->skip = false;
+        }
+
+    }
+    
+    __CFPListRelease(newKeyPaths, pInfo->allocator);
+    __CFPListRelease(keys, pInfo->allocator);
+
     if (pInfo->error) { // getContentObject encountered a parse error
-        __CFPListRelease(array, pInfo);
-        return NULL;
+        __CFPListRelease(array, pInfo->allocator);
+        return false;
     }
-    if (checkForCloseTag(pInfo, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH)) {
-       if (-1 == allowImmutableCollections) checkImmutableCollections();
-       if (1 == allowImmutableCollections) {
-           if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
-               CFArrayRef newArray = CFArrayCreateCopy(pInfo->allocator, array);
-               __CFPListRelease(array, pInfo);
-               array = (CFMutableArrayRef)newArray;
-           }
-       }
-       return array;
+    if (!checkForCloseTag(pInfo, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH)) {
+        __CFPListRelease(array, pInfo->allocator);
+        return false;
     }
-    __CFPListRelease(array, pInfo);
-    return NULL;
+    if (-1 == allowImmutableCollections) {
+        checkImmutableCollections();
+    }
+    if (1 == allowImmutableCollections) {
+        if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
+            CFArrayRef newArray = CFArrayCreateCopy(pInfo->allocator, array);
+            __CFPListRelease(array, pInfo->allocator);
+            array = (CFMutableArrayRef)newArray;
+        }
+    }
+    *out = array;
+    return true;
 }
 
-static CFTypeRef parseDictTag(_CFXMLPlistParseInfo *pInfo) {
-    CFMutableDictionaryRef dict = NULL;
-    CFTypeRef key=NULL, value=NULL;
+static Boolean parseDictTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
     Boolean gotKey;
-    const UniChar *base = pInfo->curr;
-    key = getContentObject(pInfo, &gotKey);
-    while (key) {
-        if (!gotKey) {
-            __CFPListRelease(key, pInfo);
-            __CFPListRelease(dict, pInfo);
-            pInfo->curr = base;
-            if (!pInfo->error) {
-                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Found non-key inside <dict> at line %d"), lineNumber(pInfo));
+    Boolean result;
+    CFTypeRef key = NULL, value = NULL;
+    
+    if (pInfo->skip) {
+        result = getContentObject(pInfo, &gotKey, &key);
+        while (result) {
+            if (!gotKey) { 
+                if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Found non-key inside <dict> at line %d"), lineNumber(pInfo));
+                return false;
             }
-            return NULL;
-        }
-        value = getContentObject(pInfo, NULL);
-        if (!value) {
-            __CFPListRelease(key, pInfo);
-            __CFPListRelease(dict, pInfo);
-            if (!pInfo->error) {
-                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Value missing for key inside <dict> at line %d"), lineNumber(pInfo));
+            result = getContentObject(pInfo, NULL, &value);
+            if (!result) { 
+                if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Value missing for key inside <dict> at line %d"), lineNumber(pInfo)); 
+                return false; 
             }
-            return NULL;
+            // key and value should be null, but we'll release just in case here
+            __CFPListRelease(key, pInfo->allocator);
+            key = NULL;
+            __CFPListRelease(value, pInfo->allocator);
+            value = NULL;            
+            result = getContentObject(pInfo, &gotKey, &key);
+        }
+        if (checkForCloseTag(pInfo, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH)) {
+            *out = NULL;
+            return true;
+        } else {
+            return false;
         }
-       if (NULL == dict) {
-           dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-           _CFDictionarySetCapacity(dict, 10);
-       }
-        CFDictionarySetValue(dict, key, value);
-        __CFPListRelease(key, pInfo);
+    }
+    
+    CFSetRef oldKeyPaths = pInfo->keyPaths;
+    CFSetRef nextKeyPaths, theseKeyPaths;
+    __CFPropertyListCreateSplitKeypaths(pInfo->allocator, pInfo->keyPaths, &theseKeyPaths, &nextKeyPaths);
+    
+    CFMutableDictionaryRef dict = NULL;
+    
+    result = getContentObject(pInfo, &gotKey, &key);
+    while (result && key) {
+        if (!gotKey) { 
+            if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Found non-key inside <dict> at line %d"), lineNumber(pInfo)); 
+            __CFPListRelease(key, pInfo->allocator);
+            __CFPListRelease(nextKeyPaths, pInfo->allocator);
+            __CFPListRelease(theseKeyPaths, pInfo->allocator);
+            __CFPListRelease(dict, pInfo->allocator);
+            return false;
+        }
+        
+        if (theseKeyPaths) {
+            if (!CFSetContainsValue(theseKeyPaths, key)) pInfo->skip = true;
+            pInfo->keyPaths = nextKeyPaths;
+        }
+        result = getContentObject(pInfo, NULL, &value);
+        if (theseKeyPaths) {
+            pInfo->keyPaths = oldKeyPaths;
+            pInfo->skip = false;
+        }
+        
+        if (!result) { 
+            if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Value missing for key inside <dict> at line %d"), lineNumber(pInfo)); 
+            __CFPListRelease(key, pInfo->allocator);
+            __CFPListRelease(nextKeyPaths, pInfo->allocator);
+            __CFPListRelease(theseKeyPaths, pInfo->allocator);
+            __CFPListRelease(dict, pInfo->allocator);
+            return false;
+        }
+        
+        if (key && value) {
+            if (NULL == dict) {
+                dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                _CFDictionarySetCapacity(dict, 10);
+            }
+            CFDictionarySetValue(dict, key, value);
+        }
+        
+        __CFPListRelease(key, pInfo->allocator);
         key = NULL;
-        __CFPListRelease(value, pInfo);
+        __CFPListRelease(value, pInfo->allocator);
         value = NULL;
-        base = pInfo->curr;
-        key = getContentObject(pInfo, &gotKey);
+        
+        result = getContentObject(pInfo, &gotKey, &key);
     }
+    
+    __CFPListRelease(nextKeyPaths, pInfo->allocator);
+    __CFPListRelease(theseKeyPaths, pInfo->allocator);
+
     if (checkForCloseTag(pInfo, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH)) {
        if (NULL == dict) {
            if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
@@ -1409,41 +1511,117 @@ static CFTypeRef parseDictTag(_CFXMLPlistParseInfo *pInfo) {
                    uint32_t v;
                    CFNumberGetValue((CFNumberRef)val, kCFNumberSInt32Type, &v);
                    uid = (CFTypeRef)_CFKeyedArchiverUIDCreate(pInfo->allocator, v);
-                   __CFPListRelease(dict, pInfo);
-                   return uid;
+                   __CFPListRelease(dict, pInfo->allocator);
+                    *out = uid;
+                    return true;
                }
            }
            if (-1 == allowImmutableCollections) checkImmutableCollections();
            if (1 == allowImmutableCollections) {
                if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
                    CFDictionaryRef newDict = CFDictionaryCreateCopy(pInfo->allocator, dict);
-                   __CFPListRelease(dict, pInfo);
+                   __CFPListRelease(dict, pInfo->allocator);
                    dict = (CFMutableDictionaryRef)newDict;
                }
            }
        }
-        return dict;
+        *out = dict;
+        return true;
     }
-    __CFPListRelease(dict, pInfo);
-    return NULL;
+    
+    return false;
 }
 
-static CFTypeRef parseDataTag(_CFXMLPlistParseInfo *pInfo) {
-    CFDataRef result;
-    const UniChar *base = pInfo->curr;
-    result = __CFPLDataDecode(pInfo, pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves);
-    if (!result) {
-        pInfo->curr = base;
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret <data> at line %d (should be base64-encoded)"), lineNumber(pInfo));
-        return NULL;
+static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
+    const char *base = pInfo->curr;
+    static const signed char dataDecodeTable[128] = {
+        /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1,
+        /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1,
+        /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1,
+        /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1,
+        /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1,
+        /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63,
+        /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59,
+        /* '8' */ 60, 61, -1, -1, -1,  0, -1, -1,
+        /* '@' */ -1,  0,  1,  2,  3,  4,  5,  6,
+        /* 'H' */  7,  8,  9, 10, 11, 12, 13, 14,
+        /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22,
+        /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1,
+        /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32,
+        /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40,
+        /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48,
+        /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1
+    };
+    
+    int tmpbufpos = 0;
+    int tmpbuflen = 256;
+    uint8_t *tmpbuf = pInfo->skip ? NULL : (uint8_t *)CFAllocatorAllocate(pInfo->allocator, tmpbuflen, 0);
+    int numeq = 0;
+    int acc = 0;
+    int cntr = 0;
+    
+    for (; pInfo->curr < pInfo->end; pInfo->curr++) {
+        signed char c = *(pInfo->curr);
+        if (c == '<') {
+            break;
+        }
+        if ('=' == c) {
+            numeq++;
+        } else if (!isspace(c)) {
+            numeq = 0;
+        }
+        if (dataDecodeTable[c] < 0)
+            continue;
+        cntr++;
+        acc <<= 6;
+        acc += dataDecodeTable[c];
+        if (!pInfo->skip && 0 == (cntr & 0x3)) {
+            if (tmpbuflen <= tmpbufpos + 2) {
+                if (tmpbuflen < 256 * 1024) {
+                    tmpbuflen *= 4;
+                } else if (tmpbuflen < 16 * 1024 * 1024) {
+                    tmpbuflen *= 2;
+                } else {
+                    // once in this stage, this will be really slow
+                    // and really potentially fragment memory
+                    tmpbuflen += 256 * 1024;
+                }
+                tmpbuf = (uint8_t *)CFAllocatorReallocate(pInfo->allocator, tmpbuf, tmpbuflen, 0);
+                if (!tmpbuf) HALT; // out of memory
+            }
+            tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff;
+            if (numeq < 2) tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff;
+            if (numeq < 1) tmpbuf[tmpbufpos++] = acc & 0xff;
+        }
+    }
+    
+    CFDataRef result = NULL;
+    if (!pInfo->skip) {
+        if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+            result = (CFDataRef)CFDataCreateMutable(pInfo->allocator, 0);
+            CFDataAppendBytes((CFMutableDataRef)result, tmpbuf, tmpbufpos);
+            CFAllocatorDeallocate(pInfo->allocator, tmpbuf);
+        } else {
+            result = CFDataCreateWithBytesNoCopy(pInfo->allocator, tmpbuf, tmpbufpos, pInfo->allocator);
+        }
+        if (!result) {
+            pInfo->curr = base;
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret <data> at line %d (should be base64-encoded)"), lineNumber(pInfo));
+            return false;
+        }
+    }
+    
+    if (checkForCloseTag(pInfo, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH)) {
+        *out = result;
+        return true;
+    } else {
+        __CFPListRelease(result, pInfo->allocator);
+        return false;
     }
-    if (checkForCloseTag(pInfo, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH)) return result;
-    __CFPListRelease(result, pInfo);
-    return NULL;
 }
 
 CF_INLINE Boolean read2DigitNumber(_CFXMLPlistParseInfo *pInfo, int32_t *result) {
-    UniChar ch1, ch2;
+    char ch1, ch2;
     if (pInfo->curr + 2 >= pInfo->end) return false;
     ch1 = *pInfo->curr;
     ch2 = *(pInfo->curr + 1);
@@ -1454,7 +1632,7 @@ CF_INLINE Boolean read2DigitNumber(_CFXMLPlistParseInfo *pInfo, int32_t *result)
 }
 
 // YYYY '-' MM '-' DD 'T' hh ':' mm ':' ss 'Z'
-static CFTypeRef parseDateTag(_CFXMLPlistParseInfo *pInfo) {
+static Boolean parseDateTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
     int32_t year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;
     int32_t num = 0;
     Boolean badForm = false;
@@ -1506,17 +1684,17 @@ static CFTypeRef parseDateTag(_CFXMLPlistParseInfo *pInfo) {
         badForm = true;
     }
 
-    if (badForm) {
+    if (badForm || !checkForCloseTag(pInfo, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH)) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret <date> at line %d"), lineNumber(pInfo));
-        return NULL;
+        return false;
     }
-    if (!checkForCloseTag(pInfo, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH)) return NULL;
 
     CFAbsoluteTime at = 0.0;
 #if 1
     CFGregorianDate date = {yearIsNegative ? -year : year, month, day, hour, minute, second};
     at = CFGregorianDateGetAbsoluteTime(date, NULL);
 #else
+    // this doesn't work
     CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorSystemDefault, kCFCalendarIdentifierGregorian);
     CFTimeZoneRef tz = CFTimeZoneCreateWithName(kCFAllocatorSystemDefault, CFSTR("GMT"), true);
     CFCalendarSetTimeZone(calendar, tz);
@@ -1524,69 +1702,62 @@ static CFTypeRef parseDateTag(_CFXMLPlistParseInfo *pInfo) {
     CFRelease(calendar);
     CFRelease(tz);
 #endif
-    return CFDateCreate(pInfo->allocator, at);
+    if (pInfo->skip) {
+        *out = NULL;
+    } else {
+        *out = CFDateCreate(pInfo->allocator, at);
+    }
+    return true;
 }
 
-static CFTypeRef parseRealTag(_CFXMLPlistParseInfo *pInfo) {
-    CFStringRef str = getString(pInfo);
-    SInt32 idx, len;
-    double val;
-    CFNumberRef result;
-    CFStringInlineBuffer buf;
-    if (!str) {
-        if (!pInfo->error) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <real> on line %d"), lineNumber(pInfo));
-        }
-        return NULL;
+static Boolean parseRealTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
+    CFStringRef str = NULL;
+    if (!parseStringTag(pInfo, &str)) {
+        if (!pInfo->error) pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <real> on line %d"), lineNumber(pInfo));
+        return false;
     }
     
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("nan"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberNaN) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+infinity"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberPositiveInfinity) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-infinity"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberNegativeInfinity) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("infinity"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberPositiveInfinity) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-inf"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberNegativeInfinity) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("inf"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberPositiveInfinity) : NULL;
-       }
-       if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+inf"), kCFCompareCaseInsensitive)) {
-           __CFPListRelease(str, pInfo);
-           return (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) ? CFRetain(kCFNumberPositiveInfinity) : NULL;
-       }
-
-    len = CFStringGetLength(str);
-    CFStringInitInlineBuffer(str, &buf, CFRangeMake(0, len));
-    idx = 0;
-    if (!__CFStringScanDouble(&buf, NULL, &idx, &val) || idx != len) {
-        __CFPListRelease(str, pInfo);
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered misformatted real on line %d"), lineNumber(pInfo));
-        return NULL;
+    CFNumberRef result = NULL;
+    
+    if (!pInfo->skip) {
+        if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("nan"), kCFCompareCaseInsensitive)) result = kCFNumberNaN;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+infinity"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-infinity"), kCFCompareCaseInsensitive)) result = kCFNumberNegativeInfinity;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("infinity"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("-inf"), kCFCompareCaseInsensitive)) result = kCFNumberNegativeInfinity;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("inf"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
+        else if (kCFCompareEqualTo == CFStringCompare(str, CFSTR("+inf"), kCFCompareCaseInsensitive)) result = kCFNumberPositiveInfinity;
+        
+        if (result) {
+            CFRetain(result);
+        } else {
+            CFIndex len = CFStringGetLength(str);
+            CFStringInlineBuffer buf;
+            CFStringInitInlineBuffer(str, &buf, CFRangeMake(0, len));
+            SInt32 idx = 0;
+            double val;
+            if (!__CFStringScanDouble(&buf, NULL, &idx, &val) || idx != len) {
+                __CFPListRelease(str, pInfo->allocator);
+                pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered misformatted real on line %d"), lineNumber(pInfo));
+                return false;
+            }
+            result = CFNumberCreate(pInfo->allocator, kCFNumberDoubleType, &val);
+        }
+    }
+    
+    __CFPListRelease(str, pInfo->allocator);
+    if (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) {
+        *out = result;
+        return true;
+    } else {
+        __CFPListRelease(result, pInfo->allocator);
+        return false;
     }
-    __CFPListRelease(str, pInfo);
-    result = CFNumberCreate(pInfo->allocator, kCFNumberDoubleType, &val);
-    if (checkForCloseTag(pInfo, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH)) return result;
-    __CFPListRelease(result, pInfo);
-    return NULL;
 }
 
 #define GET_CH if (pInfo->curr == pInfo->end) {        \
                        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Premature end of file after <integer> on line %d"), lineNumber(pInfo)); \
-                       return NULL;                    \
+                       return false;                   \
                }                                       \
                ch = *(pInfo->curr)
 
@@ -1599,23 +1770,64 @@ enum {
     kCFNumberSInt128Type = 17
 };
 
-static CFTypeRef parseIntegerTag(_CFXMLPlistParseInfo *pInfo) {
+CF_INLINE bool isWhitespace(const char *utf8bytes, const char *end) {
+    // Converted UTF-16 isWhitespace from CFString to UTF8 bytes to get full list of UTF8 whitespace
+    /*
+     0020 -> <20>
+     0009 -> <09>
+     00a0 -> <c2a0>
+     1680 -> <e19a80>
+     2000 -> <e28080>
+     2001 -> <e28081>
+     2002 -> <e28082>
+     2003 -> <e28083>
+     2004 -> <e28084>
+     2005 -> <e28085>
+     2006 -> <e28086>
+     2007 -> <e28087>
+     2008 -> <e28088>
+     2009 -> <e28089>
+     200a -> <e2808a>
+     200b -> <e2808b>
+     202f -> <e280af>
+     205f -> <e2819f>
+     3000 -> <e38080>
+     */
+    // Except we consider some additional values from 0x0 to 0x21 and 0x7E to 0xA1 as whitespace, for compatability
+    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);
+        if (byte1 == 0xe2 && byte2 == 0x80) {
+            return ((byte3 >= 80 && byte3 <= 0x8b) || byte3 == 0xaf);
+        } else if (byte1 == 0xe2 && byte2 == 0x81) {
+            return byte3 == 0x9f;
+        } else if (byte1 == 0xe3 && byte2 == 0x80 && byte3 == 0x80) {
+            return true;
+        }
+    }
+    return false;
+}
+
+static Boolean parseIntegerTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
     bool isHex = false, isNeg = false, hadLeadingZero = false;
-    UniChar ch = 0;
+    char ch = 0;
     
     // decimal_constant         S*(-|+)?S*[0-9]+               (S == space)
     // hex_constant            S*(-|+)?S*0[xX][0-9a-fA-F]+     (S == space)
     
-    while (pInfo->curr < pInfo->end && __CFIsWhitespace(*(pInfo->curr))) pInfo->curr++;
+    while (pInfo->curr < pInfo->end && isWhitespace(pInfo->curr, pInfo->end)) pInfo->curr++;
     GET_CH;
     if ('<' == ch) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <integer> on line %d"), lineNumber(pInfo));
-        return NULL;
+        return false;
     }
     if ('-' == ch || '+' == ch) {
        isNeg = ('-' == ch);
        pInfo->curr++;
-       while (pInfo->curr < pInfo->end && __CFIsWhitespace(*(pInfo->curr))) pInfo->curr++;
+       while (pInfo->curr < pInfo->end && isWhitespace(pInfo->curr, pInfo->end)) pInfo->curr++;
     }
     GET_CH;
     if ('0' == ch) {
@@ -1637,13 +1849,18 @@ static CFTypeRef parseIntegerTag(_CFXMLPlistParseInfo *pInfo) {
        int32_t val = 0;
         if (!checkForCloseTag(pInfo, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH)) {
            // checkForCloseTag() sets error string
-           return NULL;
+           return false;
         }
-       return CFNumberCreate(pInfo->allocator, kCFNumberSInt32Type, &val);
+        if (pInfo->skip) {
+            *out = NULL;
+        } else {
+            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt32Type, &val);
+        }
+        return true;
     }
     if ('<' == ch) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Incomplete <integer> on line %d"), lineNumber(pInfo));
-       return NULL;
+       return false;
     }
     uint64_t value = 0;
     uint32_t multiplier = (isHex ? 16 : 10);
@@ -1661,56 +1878,63 @@ static CFTypeRef parseIntegerTag(_CFXMLPlistParseInfo *pInfo) {
                 break;
             default:   // other character
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unknown character '%c' (0x%x) in <integer> on line %d"), ch, ch, lineNumber(pInfo));
-                return NULL;
+                return false;
        }
        if (!isHex && new_digit > 9) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Hex digit in non-hex <integer> on line %d"), lineNumber(pInfo));
-           return NULL;
+           return false;
        }
        if (UINT64_MAX / multiplier < value) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer overflow in <integer> on line %d"), lineNumber(pInfo));
-           return NULL;
+           return false;
        }
        value = multiplier * value;
        if (UINT64_MAX - new_digit < value) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer overflow in <integer> on line %d"), lineNumber(pInfo));
-           return NULL;
+           return false;
        }
        value = value + new_digit;
        if (isNeg && (uint64_t)INT64_MAX + 1 < value) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Integer underflow in <integer> on line %d"), lineNumber(pInfo));
-           return NULL;
+           return false;
        }
        pInfo->curr++;
        GET_CH;
     }
     if (!checkForCloseTag(pInfo, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH)) {
        // checkForCloseTag() sets error string
-       return NULL;
+       return false;
     }
-    if (isNeg || value <= INT64_MAX) {
-       int64_t v = value;
-       if (isNeg) v = -v;      // no-op if INT64_MIN
-        return CFNumberCreate(pInfo->allocator, kCFNumberSInt64Type, &v);
+    
+    if (pInfo->skip) {
+        *out = NULL;
+    } else {
+        if (isNeg || value <= INT64_MAX) {
+            int64_t v = value;
+            if (isNeg) v = -v; // no-op if INT64_MIN
+            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt64Type, &v);
+        } else {
+            CFSInt128Struct val;
+            val.high = 0;
+            val.low = value;
+            *out = CFNumberCreate(pInfo->allocator, kCFNumberSInt128Type, &val);
+        }
     }
-    CFSInt128Struct val;
-    val.high = 0;
-    val.low = value;
-    return CFNumberCreate(pInfo->allocator, kCFNumberSInt128Type, &val);
+    return true;
 }
 
 #undef GET_CH
 
 // Returned object is retained; caller must free.  pInfo->curr expected to point to the first character after the '<'
-static CFTypeRef parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey) {
-    const UniChar *marker = pInfo->curr;
+static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTypeRef *out) {
+    const char *marker = pInfo->curr;
     int markerLength = -1;
     Boolean isEmpty;
     int markerIx = -1;
     
     if (isKey) *isKey = false;
     while (pInfo->curr < pInfo->end) {
-        UniChar ch = *(pInfo->curr);
+        char ch = *(pInfo->curr);
         if (ch == ' ' || ch ==  '\t' || ch == '\n' || ch =='\r') {
             if (markerLength == -1) markerLength = pInfo->curr - marker;
         } else if (ch == '>') {
@@ -1718,7 +1942,7 @@ static CFTypeRef parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey) {
         }
         pInfo->curr ++;
     }
-    if (pInfo->curr >= pInfo->end) return NULL;
+    if (pInfo->curr >= pInfo->end) return false;
     isEmpty = (*(pInfo->curr-1) == '/');
     if (markerLength == -1)
         markerLength = pInfo->curr - (isEmpty ? 1 : 0) - marker;
@@ -1727,159 +1951,199 @@ static CFTypeRef parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey) {
         // Back up to the beginning of the marker
         pInfo->curr = marker;
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed tag on line %d"), lineNumber(pInfo));
-        return NULL;
+        return false;
     }
     switch (*marker) {
         case 'a':   // Array
-            if (markerLength == ARRAY_TAG_LENGTH && matchString(marker, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH))
+            if (markerLength == ARRAY_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[ARRAY_IX], ARRAY_TAG_LENGTH))
                 markerIx = ARRAY_IX;
             break;
         case 'd': // Dictionary, data, or date; Fortunately, they all have the same marker length....
             if (markerLength != DICT_TAG_LENGTH)
                 break;
-            if (matchString(marker, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH))
+            if (!memcmp(marker, CFXMLPlistTags[DICT_IX], DICT_TAG_LENGTH))
                 markerIx = DICT_IX;
-            else if (matchString(marker, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH))
+            else if (!memcmp(marker, CFXMLPlistTags[DATA_IX], DATA_TAG_LENGTH))
                 markerIx = DATA_IX;
-            else if (matchString(marker, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH))
+            else if (!memcmp(marker, CFXMLPlistTags[DATE_IX], DATE_TAG_LENGTH))
                 markerIx = DATE_IX;
             break;
         case 'f': // false (boolean)
-            if (markerLength == FALSE_TAG_LENGTH && matchString(marker, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) {
+            if (markerLength == FALSE_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) {
                 markerIx = FALSE_IX;
             }
             break;
         case 'i': // integer
-            if (markerLength == INTEGER_TAG_LENGTH && matchString(marker, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH))
+            if (markerLength == INTEGER_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[INTEGER_IX], INTEGER_TAG_LENGTH))
                 markerIx = INTEGER_IX;
             break;
         case 'k': // Key of a dictionary
-            if (markerLength == KEY_TAG_LENGTH && matchString(marker, CFXMLPlistTags[KEY_IX], KEY_TAG_LENGTH)) {
+            if (markerLength == KEY_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[KEY_IX], KEY_TAG_LENGTH)) {
                 markerIx = KEY_IX;
                 if (isKey) *isKey = true;
             }
             break;
         case 'p': // Plist
-            if (markerLength == PLIST_TAG_LENGTH && matchString(marker, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH))
+            if (markerLength == PLIST_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[PLIST_IX], PLIST_TAG_LENGTH))
                 markerIx = PLIST_IX;
             break;
         case 'r': // real
-            if (markerLength == REAL_TAG_LENGTH && matchString(marker, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH))
+            if (markerLength == REAL_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[REAL_IX], REAL_TAG_LENGTH))
                 markerIx = REAL_IX;
             break;
         case 's': // String
-            if (markerLength == STRING_TAG_LENGTH && matchString(marker, CFXMLPlistTags[STRING_IX], STRING_TAG_LENGTH))
+            if (markerLength == STRING_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[STRING_IX], STRING_TAG_LENGTH))
                 markerIx = STRING_IX;
             break;
         case 't': // true (boolean)
-            if (markerLength == TRUE_TAG_LENGTH && matchString(marker, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH))
+            if (markerLength == TRUE_TAG_LENGTH && !memcmp(marker, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH))
                 markerIx = TRUE_IX;
             break;
     }
 
     if (!pInfo->allowNewTypes && markerIx != PLIST_IX && markerIx != ARRAY_IX && markerIx != DICT_IX && markerIx != STRING_IX && markerIx != KEY_IX && markerIx != DATA_IX) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered new tag when expecting only old-style property list objects"));
-        return NULL;
+        return false;
     }
 
     switch (markerIx) {
         case PLIST_IX:
             if (isEmpty) {
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty plist tag"));
-                return NULL;
+                return false;
             }
-            return parsePListTag(pInfo);
+            return parsePListTag(pInfo, out);
         case ARRAY_IX: 
             if (isEmpty) {
-                return pInfo->mutabilityOption == kCFPropertyListImmutable ?  CFArrayCreate(pInfo->allocator, NULL, 0, &kCFTypeArrayCallBacks) : CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
+                if (pInfo->skip) {
+                    *out = NULL;
+                } else {
+                    if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
+                        *out = CFArrayCreate(pInfo->allocator, NULL, 0, &kCFTypeArrayCallBacks);
+                    } else {
+                        *out = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
+                    }
+                }
+                return true;
             } else {
-                return parseArrayTag(pInfo);
+                return parseArrayTag(pInfo, out);
             }
         case DICT_IX:
             if (isEmpty) {
-                if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
-                    return CFDictionaryCreate(pInfo->allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                if (pInfo->skip) {
+                    *out = NULL;
                 } else {
-                    return CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                    if (pInfo->mutabilityOption == kCFPropertyListImmutable) {
+                        *out = CFDictionaryCreate(pInfo->allocator, NULL, NULL, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                    } else {
+                        *out = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+                    }
                 }
+                return true;
             } else {
-                return parseDictTag(pInfo);
+                return parseDictTag(pInfo, out);
             }
         case KEY_IX:
         case STRING_IX:
         {
-            CFStringRef str;
             int tagLen = (markerIx == KEY_IX) ? KEY_TAG_LENGTH : STRING_TAG_LENGTH;
             if (isEmpty) {
-                return pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves ? CFStringCreateMutable(pInfo->allocator, 0) : CFStringCreateWithCharacters(pInfo->allocator, NULL, 0);
+                if (pInfo->skip) {
+                    *out = NULL;
+                } else {
+                    if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
+                        *out = CFStringCreateMutable(pInfo->allocator, 0);
+                    } else {
+                        *out = CFStringCreateWithCharacters(pInfo->allocator, NULL, 0);
+                    }
+                }
+                return true;
+            }
+            if (!parseStringTag(pInfo, (CFStringRef *)out)) {
+                return false; // parseStringTag will already have set the error string
             }
-            str = getString(pInfo);
-            if (!str) return NULL; // getString will already have set the error string
             if (!checkForCloseTag(pInfo, CFXMLPlistTags[markerIx], tagLen)) {
-                __CFPListRelease(str, pInfo);
-                return NULL;
+                __CFPListRelease(*out, pInfo->allocator);
+                return false;
+            } else {
+                return true;
             }
-            return str;
         }
         case DATA_IX:
             if (isEmpty) {
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <data> on line %d"), lineNumber(pInfo));
-                return NULL;
+                return false;
             } else {
-                return parseDataTag(pInfo);
+                return parseDataTag(pInfo, out);
             }
         case DATE_IX:
             if (isEmpty) {
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <date> on line %d"), lineNumber(pInfo));
-                return NULL;
+                return false;
             } else {
-                return parseDateTag(pInfo);
+                return parseDateTag(pInfo, out);
             }
         case TRUE_IX:
             if (!isEmpty) {
-               if (!checkForCloseTag(pInfo, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH)) return NULL;
+               if (!checkForCloseTag(pInfo, CFXMLPlistTags[TRUE_IX], TRUE_TAG_LENGTH)) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered non-empty <true> on line %d"), lineNumber(pInfo));
+                    return false;
+                }
            }
-           return CFRetain(kCFBooleanTrue);
+            if (pInfo->skip) {
+                *out = NULL;
+            } else {
+                *out = CFRetain(kCFBooleanTrue);
+            }
+            return true;
         case FALSE_IX:
             if (!isEmpty) {
-               if (!checkForCloseTag(pInfo, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) return NULL;
+               if (!checkForCloseTag(pInfo, CFXMLPlistTags[FALSE_IX], FALSE_TAG_LENGTH)) {
+                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered non-empty <false> on line %d"), lineNumber(pInfo));
+                    return false;
+                }
            }
-            return CFRetain(kCFBooleanFalse);
+            if (pInfo->skip) {
+                *out = NULL;
+            } else {
+                *out = CFRetain(kCFBooleanFalse);
+            }
+            return true;
         case REAL_IX:
             if (isEmpty) {
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <real> on line %d"), lineNumber(pInfo));
-                return NULL;
+                return false;
             } else {
-                return parseRealTag(pInfo);
+                return parseRealTag(pInfo, out);
             }
         case INTEGER_IX:
             if (isEmpty) {
                 pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered empty <integer> on line %d"), lineNumber(pInfo));
-                return NULL;
+                return false;
             } else {
-                return parseIntegerTag(pInfo);
+                return parseIntegerTag(pInfo, out);
             }
         default:  {
-            CFStringRef markerStr = CFStringCreateWithCharacters(pInfo->allocator, marker, markerLength);
+            CFStringRef markerStr = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (const UInt8 *)marker, markerLength, kCFStringEncodingUTF8, NO);
             pInfo->curr = marker;
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown tag %@ on line %d"), markerStr, lineNumber(pInfo));
-            __CFPListRelease(markerStr, pInfo);
-            return NULL;
+            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown tag %@ on line %d"), markerStr ? markerStr : CFSTR("<unknown>"), lineNumber(pInfo));
+            if (markerStr) CFRelease(markerStr);
+            return false;
         }
     }
 }
 
-static CFTypeRef parseXMLPropertyList(_CFXMLPlistParseInfo *pInfo) {
+static Boolean parseXMLPropertyList(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) {
     while (!pInfo->error && pInfo->curr < pInfo->end) {
         UniChar ch;
         skipWhitespace(pInfo);
         if (pInfo->curr+1 >= pInfo->end) {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("No XML content found"));
-            return NULL;
+            return false;
         }
         if (*(pInfo->curr) != '<') {
             pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character %c at line %d"), *(pInfo->curr), lineNumber(pInfo));
-            return NULL;
+            return false;
         }
         ch = *(++ pInfo->curr);
         if (ch == '!') {
@@ -1898,7 +2162,7 @@ static CFTypeRef parseXMLPropertyList(_CFXMLPlistParseInfo *pInfo) {
             skipXMLProcessingInstruction(pInfo);
         } else {
             // Tag or malformed
-            return parseXMLElement(pInfo, NULL);
+            return parseXMLElement(pInfo, NULL, out);
             // Note we do not verify that there was only one element, so a file that has garbage after the first element will nonetheless successfully parse
         }
     }
@@ -1906,22 +2170,46 @@ static CFTypeRef parseXMLPropertyList(_CFXMLPlistParseInfo *pInfo) {
     if (!(pInfo->error)) {
         pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unexpected EOF"));
     }
-    return NULL;
+    return false;
 }
 
-static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error) {
+static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error, CFIndex *skip) {
     const uint8_t *bytes = (uint8_t *)CFDataGetBytePtr(data);
     UInt32 length = CFDataGetLength(data);
     const uint8_t *idx, *end;
     char quote;
     
-    // Check for the byte order mark first
-    if (length > 2 &&
-        ((*bytes == 0xFF && *(bytes+1) == 0xFE) ||
-         (*bytes == 0xFE && *(bytes+1) == 0xFF) ||
-         *bytes == 0x00 || *(bytes+1) == 0x00)) // This clause checks for a Unicode sequence lacking the byte order mark; technically an error, but this check is recommended by the XML spec
-        return kCFStringEncodingUnicode;
+    // Check for the byte order mark first. If we find it, set the skip value so the parser doesn't attempt to parse the BOM itself.
+    if (length > 4) {
+        if (*bytes == 0x00 && *(bytes+1) == 0x00 && *(bytes+2) == 0xFE && *(bytes+3) == 0xFF) {
+            *skip = 4;
+            return kCFStringEncodingUTF32BE;
+        } else if (*bytes == 0xFF && *(bytes+1) == 0xFE && *(bytes+2) == 0x00 && *(bytes+3) == 0x00) {
+            *skip = 4;
+            return kCFStringEncodingUTF32LE;
+        }
+    }
     
+    if (length > 3) {
+        if (*bytes == 0xEF && *(bytes+1) == 0xBB && *(bytes+2) == 0xBF) {
+            *skip = 3;
+            return kCFStringEncodingUTF8;
+        }
+    }
+
+    if (length > 2) {
+        if (*bytes == 0xFF && *(bytes+1) == 0xFE) {
+            *skip = 2;
+            return kCFStringEncodingUTF16LE;
+        } else if (*bytes == 0xFE && *(bytes+1) == 0xFF) {
+            *skip = 2;
+            return kCFStringEncodingUTF16BE;            
+        } else if (*bytes == 0x00 || *(bytes+1) == 0x00) { // This clause checks for a Unicode sequence lacking the byte order mark; technically an error, but this check is recommended by the XML spec
+            *skip = 2;
+            return kCFStringEncodingUnicode;
+        }
+    }
+        
     // Scan for the <?xml.... ?> opening
     if (length < 5 || strncmp((char const *) bytes, "<?xml", 5) != 0) return kCFStringEncodingUTF8;
     idx = bytes + 5;
@@ -1949,7 +2237,6 @@ static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error) {
     else {
         CFStringRef encodingName;
         const uint8_t *base = idx+1; // Move past the quote character
-        CFStringEncoding enc;
         UInt32 len;
         idx ++;
         while (idx < end && *idx != quote) idx ++;
@@ -1958,11 +2245,13 @@ static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error) {
         if (len == 5 && (*base == 'u' || *base == 'U') && (base[1] == 't' || base[1] == 'T') && (base[2] == 'f' || base[2] == 'F') && (base[3] == '-') && (base[4] == '8'))
             return kCFStringEncodingUTF8;
         encodingName = CFStringCreateWithBytes(kCFAllocatorSystemDefault, base, len, kCFStringEncodingISOLatin1, false);
-        enc = CFStringConvertIANACharSetNameToEncoding(encodingName);
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+        CFStringEncoding enc = CFStringConvertIANACharSetNameToEncoding(encodingName);
         if (enc != kCFStringEncodingInvalidId) {
             CFRelease(encodingName);
             return enc;
         }
+#endif
 
         if (error) {
             *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown encoding (%@)"), encodingName);
@@ -1973,7 +2262,6 @@ static CFStringEncoding encodingForXMLData(CFDataRef data, CFErrorRef *error) {
 }
 
 bool __CFTryParseBinaryPlist(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFPropertyListRef *plist, CFStringRef *errorString);
-unsigned long _CFPropertyListAllowNonUTF8 = 0;
 
 #define SAVE_PLISTS 0
 
@@ -2010,92 +2298,183 @@ static Boolean __savePlistData(CFDataRef data, CFOptionFlags opt) {
 }
 #endif
 
-
-CFTypeRef _CFPropertyListCreateFromXMLStringError(CFAllocatorRef allocator, CFStringRef xmlString, CFOptionFlags option, CFErrorRef *error, Boolean allowNewTypes, CFPropertyListFormat *format) {
+// If the data is from a converted string, then originalString is non-NULL. If originalString is NULL, then pass in guessedEncoding.
+// keyPaths is a set of CFStrings, ':'-separated paths
+static Boolean _CFPropertyListCreateFromUTF8Data(CFAllocatorRef allocator, CFDataRef xmlData, CFIndex skipBytes, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError, Boolean allowNewTypes, CFPropertyListFormat *format, CFSetRef keyPaths, CFTypeRef *out) {
     initStatics();
     
-    CFAssert1(xmlString != NULL, __kCFLogAssertion, "%s(): NULL string not allowed", __PRETTY_FUNCTION__);
+    CFAssert1(xmlData != NULL, __kCFLogAssertion, "%s(): NULL data not allowed", __PRETTY_FUNCTION__);
     CFAssert2(option == kCFPropertyListImmutable || option == kCFPropertyListMutableContainers || option == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %d", __PRETTY_FUNCTION__, option);
     
-    UInt32 length;
-    Boolean createdBuffer = false;
-    length = xmlString ? CFStringGetLength(xmlString) : 0;
-    
+    CFIndex length = CFDataGetLength(xmlData);
     if (!length) {
-        if (error) {
-            *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty."));
-        }
-        return NULL;
+        if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty."));
+        return false;
     }
     
     _CFXMLPlistParseInfo pInfoBuf;
     _CFXMLPlistParseInfo *pInfo = &pInfoBuf;
     CFTypeRef result;
     
-    // Ensure that xmlString is not collected while we are using it
-    CFRetain(xmlString);
-    UniChar *buf = (UniChar *)CFStringGetCharactersPtr(xmlString);
+    // Ensure that the data is not collected while we are using it
+    CFRetain(xmlData);
+    const char *buf = (const char *)CFDataGetBytePtr(xmlData);
+    
+    // We may have to skip over starting stuff like BOM markers.
+    buf += skipBytes;
     
-    if (!buf) {
-        buf = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, length * sizeof(UniChar), 0);
-        if (!buf) {
-            out_of_memory_warning();
-            return NULL;
-        }
-        CFStringGetCharacters(xmlString, CFRangeMake(0, length), buf);
-        createdBuffer = true;
-    }
     pInfo->begin = buf;
     pInfo->end = buf+length;
     pInfo->curr = buf;
     pInfo->allocator = allocator;
     pInfo->error = NULL;
-    pInfo->stringSet = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks);
-    _CFSetSetCapacity(pInfo->stringSet, CFStringGetLength(xmlString) / 250); // avoid lots of rehashes, may waste some memory; simple heuristic
+    _createStringMap(pInfo);
     pInfo->mutabilityOption = option;
     pInfo->allowNewTypes = allowNewTypes;
+    pInfo->skip = false;
+    pInfo->keyPaths = createTopLevelKeypaths(allocator, keyPaths);
     
-    result = parseXMLPropertyList(pInfo);
-    if (result && format) *format = kCFPropertyListXMLFormat_v1_0;
-    if (!result) {
-        CFErrorRef xmlParserErr = pInfo->error;
-        // Reset pInfo so we can try again
-        pInfo->curr = pInfo->begin;
-        pInfo->error = NULL;
+    Boolean success = parseXMLPropertyList(pInfo, &result);
+    if (success && result && format) *format = kCFPropertyListXMLFormat_v1_0;
+    
+    _cleanupStringMap(pInfo);
+    if (pInfo->keyPaths && !_CFAllocatorIsGCRefZero(allocator)) CFRelease(pInfo->keyPaths);
+    CFRelease(xmlData);
+
+    if (success) {
+        *out = result; // caller releases
+        return true;
+    }
+    
+    // Try again, old-style
+    CFErrorRef oldStyleError = NULL;
+    result = __CFParseOldStylePropertyListOrStringsFile(allocator, xmlData, originalString, guessedEncoding, option, outError ? &oldStyleError : NULL, format);
+    if (result) {
+        // Release old error, return
+        if (pInfo->error) CFRelease(pInfo->error);
+        *out = result;
+        return true;
+    }
+    
+    // Failure, both ways. Set up the error to be given back to caller.
+    if (!outError) {
+        if (pInfo->error) CFRelease(pInfo->error);
+        return false;
+    }
+    
+    // Caller's responsibility to release outError
+    if (pInfo->error && oldStyleError) {
+        // Add the error from the old-style property list parser to the user info of the original error (pInfo->error), which had better exist
+        CFDictionaryRef oldUserInfo = CFErrorCopyUserInfo(pInfo->error);
+        CFMutableDictionaryRef newUserInfo = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, CFDictionaryGetCount(oldUserInfo) + 1, oldUserInfo);
+        CFDictionaryAddValue(newUserInfo, CFPropertyListOldStyleParserErrorKey, oldStyleError);
         
-        // Try pList
-        result = parseOldStylePropertyListOrStringsFile(pInfo);
-        if (result && format) {
-            *format = kCFPropertyListOpenStepFormat;
-        }
+        // Re-create the xml parser error with this new user info dictionary
+        CFErrorRef newError = CFErrorCreate(kCFAllocatorSystemDefault, CFErrorGetDomain(pInfo->error), CFErrorGetCode(pInfo->error), newUserInfo);
         
-        if (!result && xmlParserErr && error) {
-            // Add the new error from the old-style property list parser to the user info of the original error
-            CFDictionaryRef xmlUserInfo = CFErrorCopyUserInfo(xmlParserErr);
-            CFMutableDictionaryRef userInfo = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, CFDictionaryGetCount(xmlUserInfo) + 1, xmlUserInfo);
-            CFDictionaryAddValue(userInfo, CFPropertyListOldStyleParserErrorKey, pInfo->error);
-            
-            // Re-create the xml parser error with this new user info dictionary
-            CFErrorRef newError = CFErrorCreate(kCFAllocatorSystemDefault, CFErrorGetDomain(xmlParserErr), CFErrorGetCode(xmlParserErr), userInfo);
-            
-            CFRelease(xmlUserInfo);
-            CFRelease(userInfo);
-                        
-            // It is the responsibility of the caller to release this newly created error
-            *error = newError;
-        }
+        CFRelease(oldUserInfo);
+        CFRelease(newUserInfo);
+        CFRelease(oldStyleError);
+        CFRelease(pInfo->error);
+        *outError = newError;
         
-        if (xmlParserErr) {
-            CFRelease(xmlParserErr);
+    } else if (pInfo->error && !oldStyleError) {
+        // Return original error
+        *outError = pInfo->error;
+    } else if (!pInfo->error && oldStyleError) {
+        // Return only old-style error
+        // Probably shouldn't get here
+        *outError = oldStyleError;
+    } else if (!pInfo->error && !oldStyleError) {
+        // Return unknown error
+        *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Encountered unknown error during parse"));
+    }
+    return false;    
+}
+
+static CFDataRef _createUTF8DataFromString(CFAllocatorRef allocator, CFStringRef str) {
+    CFIndex bytesNeeded = 0;
+    CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, 0, false, NULL, 0, &bytesNeeded);
+
+    const char *bytes = (const char *)CFAllocatorAllocate(allocator, bytesNeeded, 0);
+    CFStringGetBytes(str, CFRangeMake(0, CFStringGetLength(str)), kCFStringEncodingUTF8, 0, false, (uint8_t *)bytes, bytesNeeded, NULL);
+   
+    CFDataRef utf8Data = CFDataCreateWithBytesNoCopy(allocator, (const UInt8 *)bytes, bytesNeeded, allocator);
+    return utf8Data;
+}
+
+// Set topLevelKeys to a set of top level keys to decode. If NULL, all keys are decoded. If the top level object is not a dictionary, all objects are decoded. If the plist is not XML, all objects are decoded.
+static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *outError, Boolean allowNewTypes, CFPropertyListFormat *format, CFSetRef topLevelKeys, CFTypeRef *out) {
+    initStatics();
+    CFStringEncoding encoding;
+    
+    if (!data || CFDataGetLength(data) == 0) {
+        if (outError) {
+            *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Cannot parse a NULL or zero-length data"));
         }
+        return false;
     }
     
-    if (createdBuffer) {
-        CFAllocatorDeallocate(kCFAllocatorSystemDefault, (void *)pInfo->begin);
+#if SAVE_PLISTS
+    __savePlistData(data, option);
+#endif
+    
+    // Ignore the error from CFTryParseBinaryPlist -- if it doesn't work, we're going to try again anyway using the XML parser
+    if (__CFTryParseBinaryPlist(allocator, data, option, out, NULL)) {
+       if (format) *format = kCFPropertyListBinaryFormat_v1_0;
+        return true;
     }
-    if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(pInfo->stringSet);
-    if (pInfo->error) CFRelease(pInfo->error);
-    CFRelease(xmlString);
+    
+    // Use our own error variable here so we can check it against NULL later
+    CFErrorRef subError = NULL;
+    CFIndex skip = 0;
+    encoding = encodingForXMLData(data, &subError, &skip); // 0 is an error return, NOT MacRoman.
+    
+    if (encoding == 0) {
+        // Couldn't find an encoding
+        // Note that encodingForXMLData() will give us the right values for a standard plist, too.
+        if (outError && subError == NULL) {
+           // encodingForXMLData didn't set an error, so we create a new one here
+            *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not determine the encoding of the XML data"));
+        } else if (outError && subError) {
+           // give the caller the subError, they will release
+           *outError = subError;
+       } else if (!outError && subError) {
+           // Release the error
+           CFRelease(subError);
+       }
+        return false;
+    }
+    
+    if (encoding == kCFStringEncodingUTF8) {
+        // Use fast path
+        return _CFPropertyListCreateFromUTF8Data(allocator, data, skip, NULL, encoding, option, outError, allowNewTypes, format, topLevelKeys, out);
+    }
+    
+    // Convert to UTF8 first
+    CFStringRef xmlString = CFStringCreateWithBytes(allocator, CFDataGetBytePtr(data) + skip, CFDataGetLength(data) - skip, encoding, 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);
+    
+    return result;
+}
+
+// -----------------------------------------------------------------------------------------------------------------------
+
+#pragma mark -
+#pragma mark Exported Parsing Functions
+
+CFTypeRef _CFPropertyListCreateFromXMLStringError(CFAllocatorRef allocator, CFStringRef xmlString, CFOptionFlags option, CFErrorRef *error, Boolean allowNewTypes, CFPropertyListFormat *format) {
+    // Convert to UTF8 first
+    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);
+
     return result;
 }
 
@@ -2143,6 +2522,51 @@ 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);
+
+// 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) {
+    
+    initStatics();
+    
+    if (!keyPaths || !data) {
+        return false;
+    }
+    
+    uint8_t marker;    
+    CFBinaryPlistTrailer trailer;
+    uint64_t offset;
+    const uint8_t *databytes = CFDataGetBytePtr(data);
+    uint64_t datalen = CFDataGetLength(data);
+    Boolean success = false;
+    CFTypeRef out = NULL;
+
+    // First check to see if it is a binary property list
+    if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {        
+        uint64_t valueOffset = offset;
+        
+        // Split up the key path
+        CFSetRef splitKeyPaths = createTopLevelKeypaths(allocator, keyPaths);
+
+        // Create a dictionary to cache objects in
+        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);        
+    } else {
+       // Try an XML property list
+        success = _CFPropertyListCreateWithData(allocator, data, option, error, true, NULL, keyPaths, &out);
+    }
+    
+    if (success && value) {
+        *value = out; // caller releases
+    } else if (out) {
+        CFRelease(out);
+    }
+    return success;
+}
+
 /* Get a single value for a given key in a top-level dictionary in a property list.
  @param allocator The allocator to use.
  @param data The property list data.
@@ -2165,7 +2589,7 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
     uint64_t offset;
     const uint8_t *databytes = CFDataGetBytePtr(data);
     uint64_t datalen = CFDataGetLength(data);
-    bool result = false;
+    Boolean success = false;
     
     // First check to see if it is a binary property list
     if (8 <= datalen && __CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) {
@@ -2181,24 +2605,24 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
         for (CFIndex i = 0; i < keyPathCount; i++) {
             CFStringRef oneKey = (CFStringRef)CFArrayGetValueAtIndex(keyPathArray, i);
             SInt32 intValue = CFStringGetIntValue(oneKey);
-            if ((intValue == 0 && CFStringCompare(CFSTR("0"), oneKey, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN) {
+            if ((intValue == 0 && CFStringCompare(CFSTR("0"), oneKey, 0) != kCFCompareEqualTo) || intValue == INT_MAX || intValue == INT_MIN || intValue < 0) {
                 // Treat as a string key into a dictionary
-                result = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, valueOffset, &trailer, (CFTypeRef)oneKey, &keyOffset, &valueOffset, false, objects);
+                success = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, valueOffset, &trailer, (CFTypeRef)oneKey, &keyOffset, &valueOffset, false, objects);
             } else {
                 // Treat as integer index into an array
-                result = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, valueOffset, &trailer, intValue, &valueOffset, objects);
+                success = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, valueOffset, &trailer, intValue, &valueOffset, objects);
             }
             
-            if (!result) {
+            if (!success) {
                 break;
             }
         }
         
         // value could be null if the caller wanted to check for the existence of a key but not bother creating it
-        if (result && value) {
+        if (success && value) {
             CFPropertyListRef pl;
-           result = __CFBinaryPlistCreateObject2(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, &pl);
-           if (result) {
+           success = __CFBinaryPlistCreateObjectFiltered(databytes, datalen, valueOffset, &trailer, allocator, option, objects, NULL, 0, NULL, &pl);
+           if (success) {
                // caller's responsibility to release the created object
                *value = pl;
            }
@@ -2210,9 +2634,8 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
        // 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;
-        result = true;
-        
+        CFPropertyListRef nextObject = plist;  
+        success = true;
        if (!(*error) && plist) {
             CFArrayRef keyPathArray = CFStringCreateArrayBySeparatingStrings(kCFAllocatorSystemDefaultGCRefZero, keyPath, CFSTR(":"));
             for (CFIndex i = 0;  i < CFArrayGetCount(keyPathArray); i++) {
@@ -2225,15 +2648,17 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
                     // Treat as integer index into an array
                     nextObject = (CFPropertyListRef)CFArrayGetValueAtIndex((CFArrayRef)nextObject, intValue);
                 } else {
-                    result = false;
+                    success = false;
                     break;
                 }
             }
             
-            if (result && nextObject && value) {
+            if (success && nextObject && value) {
                 *value = nextObject;
                 // caller's responsibility to release the created object
                 CFRetain(*value);
+            } else if (!nextObject) {
+                success = false;
             }
             
             if (!_CFAllocatorIsGCRefZero(kCFAllocatorSystemDefaultGCRefZero)) CFRelease(keyPathArray);
@@ -2241,87 +2666,30 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data,
         if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(plist);
     }
     
-    return result;
+    return success;
 }
 
-CFTypeRef _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *error, Boolean allowNewTypes, CFPropertyListFormat *format) {
-    initStatics();
-    CFStringEncoding encoding;
-    CFPropertyListRef plist;
-    
-    if (!data || CFDataGetLength(data) == 0) {
-        if (error) {
-            *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Cannot parse a NULL or zero-length data"));
-        }
-        return NULL;
-    }
-    
-#if SAVE_PLISTS
-    __savePlistData(data, option);
-#endif
-    
-    // Ignore the error from CFTryParseBinaryPlist -- if it doesn't work, we're going to try again anyway using the XML parser
-    if (__CFTryParseBinaryPlist(allocator, data, option, &plist, NULL)) {
-       if (format) *format = kCFPropertyListBinaryFormat_v1_0;
-       return plist;
-    }
-    
-    // Use our own error variable here so we can check it against NULL later
-    CFErrorRef subError = NULL;
-    encoding = encodingForXMLData(data, &subError); // 0 is an error return, NOT MacRoman.
-    
-    if (encoding == 0) {
-        // Couldn't find an encoding
-        // Note that encodingForXMLData() will give us the right values for a standard plist, too.
-        if (error && subError == NULL) {
-           // encodingForXMLData didn't set an error, so we create a new one here
-            *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not determine the encoding of the XML data"));
-        } else if (error && subError) {
-           // give the caller the subError, they will release
-           *error = subError;
-       } else if (!error && subError) {
-           // Release the error
-           CFRelease(subError);
-       }
-        return NULL;
-    }
-    
-    CFStringRef xmlString = CFStringCreateWithBytes(allocator, CFDataGetBytePtr(data), CFDataGetLength(data), encoding, true);
-    if (NULL == xmlString && (!_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard) || _CFPropertyListAllowNonUTF8)) { // conversion failed, probably because not in proper encoding
-        // Call __CFStringCreateImmutableFunnel3() the same way CFStringCreateWithBytes() does, except with the addt'l flag
-        if (encoding == kCFStringEncodingUTF8) xmlString = __CFStringCreateImmutableFunnel3(allocator, CFDataGetBytePtr(data), CFDataGetLength(data), kCFStringEncodingUTF8, true, true, false, false, false, (CFAllocatorRef)-1  /* ALLOCATORSFREEFUNC */, kCFStringEncodingLenientUTF8Conversion);
-    }
-    
-    // Haven't done anything XML-specific to this point.  However, the encoding we used to translate the bytes should be kept in mind; we used Unicode if the byte-order mark was present; UTF-8 otherwise.  If the system encoding is not UTF-8 or some variant of 7-bit ASCII, we'll be in trouble.....
-    plist = _CFPropertyListCreateFromXMLStringError(allocator, xmlString, option, error, allowNewTypes, format);
-    
-    if (xmlString) {
-        if (!_CFAllocatorIsGCRefZero(allocator)) CFRelease(xmlString);
-        xmlString = NULL;
-    }
-    
-    return plist;
-}
-
-
+// Legacy
 CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString, Boolean allowNewTypes, CFPropertyListFormat *format) {
     initStatics();
-    CFTypeRef result;
+    CFTypeRef out = NULL;
     if (errorString) *errorString = NULL;
     CFErrorRef error = NULL;
-    result = _CFPropertyListCreateWithData(allocator, xmlData, option, &error, allowNewTypes, format);
-    if (error && errorString) {
-        *errorString = __CFPropertyListCopyErrorDebugDescription(error);
+    Boolean result = _CFPropertyListCreateWithData(allocator, xmlData, option, &error, allowNewTypes, format, NULL, &out);
+    if (!result && error && errorString) {
+        *errorString = __copyErrorDebugDescription(error);
     }
     if (error) CFRelease(error);
-    return result;
+    return out;
 }
 
 CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) {
     initStatics();
     CFAssert1(data != NULL, __kCFLogAssertion, "%s(): NULL data not allowed", __PRETTY_FUNCTION__);
     CFAssert2(options == kCFPropertyListImmutable || options == kCFPropertyListMutableContainers || options == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %d", __PRETTY_FUNCTION__, options);
-    return _CFPropertyListCreateWithData(allocator, data, options, error, true, format);
+    CFPropertyListRef out = NULL;
+    _CFPropertyListCreateWithData(allocator, data, options, error, true, format, NULL, &out);
+    return out;
 }
 
 CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString) {
@@ -2330,7 +2698,7 @@ CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDa
     CFErrorRef error = NULL;
     CFPropertyListRef result = CFPropertyListCreateWithData(allocator, xmlData, option, NULL, &error);
     if (error && errorString) {
-        *errorString = __CFPropertyListCopyErrorDebugDescription(error);
+        *errorString = __copyErrorDebugDescription(error);
     }
     if (error) CFRelease(error);
     return result;
@@ -2468,13 +2836,13 @@ CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStrea
     
     CFIndex result = CFPropertyListWrite(propertyList, stream, format, 0, &error);
     if (error && errorString) {
-        *errorString = __CFPropertyListCopyErrorDebugDescription(error);
+        *errorString = __copyErrorDebugDescription(error);
     }
     if (error) CFRelease(error);
     return result;    
 }
 
-static void __CFConvertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint8_t **buffer, CFIndex *length, CFErrorRef *error) {
+static void __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 (;;) {
@@ -2517,10 +2885,7 @@ static void __CFConvertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, ui
 
 CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFErrorRef *error) {
     initStatics();
-    CFPropertyListRef pl;
-    CFDataRef data;
-    CFIndex buflen = 0;
-    uint8_t *buffer = NULL;
+    
     CFAssert1(stream != NULL, __kCFLogAssertion, "%s(): NULL stream not allowed", __PRETTY_FUNCTION__);
     CFAssert1(CFReadStreamGetTypeID() == CFGetTypeID(stream), __kCFLogAssertion, "%s(): stream argument is not a read stream", __PRETTY_FUNCTION__);
     CFAssert1(kCFStreamStatusOpen == CFReadStreamGetStatus(stream) || kCFStreamStatusReading == CFReadStreamGetStatus(stream), __kCFLogAssertion, "%s():  stream is not open", __PRETTY_FUNCTION__);
@@ -2528,7 +2893,9 @@ CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFRea
     
     if (0 == streamLength) streamLength = LONG_MAX;
     CFErrorRef underlyingError = NULL;
-    __CFConvertReadStreamToBytes(stream, streamLength, &buffer, &buflen, &underlyingError);
+    CFIndex buflen = 0;
+    uint8_t *buffer = NULL;
+    __convertReadStreamToBytes(stream, streamLength, &buffer, &buflen, &underlyingError);
     if (underlyingError) {
         if (error) {
             // Wrap the error from CFReadStream in a new error in the cocoa domain
@@ -2547,9 +2914,12 @@ CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFRea
         if (error) *error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("stream had too few bytes"));
         return NULL;
     }
-    data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, buffer, buflen, kCFAllocatorSystemDefault);
-    pl = _CFPropertyListCreateWithData(allocator, data, mutabilityOption, error, true, format);
+    
+    CFDataRef data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, buffer, buflen, kCFAllocatorSystemDefault);
+    CFPropertyListRef pl = NULL; // initialize to null, because if the following call fails we must return NULL
+    _CFPropertyListCreateWithData(allocator, data, mutabilityOption, error, true, format, NULL, &pl);
     CFRelease(data);
+    
     return pl;
 }
 
@@ -2559,7 +2929,7 @@ CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFRea
     CFErrorRef error = NULL;
     CFPropertyListRef result = CFPropertyListCreateWithStream(allocator, stream, length, mutabilityOption, format, &error);
     if (error && errorString) {
-        *errorString = __CFPropertyListCopyErrorDebugDescription(error);
+        *errorString = __copyErrorDebugDescription(error);
     }
     if (error) CFRelease(error);
     return result;
@@ -2567,435 +2937,8 @@ CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFRea
 
 #endif //DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
 
-// ========================================================================
-
-//
-// Old NeXT-style property lists
-//
-
-static CFTypeRef parsePlistObject(_CFXMLPlistParseInfo *pInfo, bool requireObject);
-
-#define isValidUnquotedStringCharacter(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z') || ((x) >= '0' && (x) <= '9') || (x) == '_' || (x) == '$' || (x) == '/' || (x) == ':' || (x) == '.' || (x) == '-')
-
-// Returns true if the advance found something before the end of the buffer, false otherwise
-static Boolean advanceToNonSpace(_CFXMLPlistParseInfo *pInfo) {
-    UniChar ch2;
-    while (pInfo->curr < pInfo->end) {
-       ch2 = *(pInfo->curr);
-        pInfo->curr ++;
-        if (ch2 >= 9 && ch2 <= 0x0d) continue; // tab, newline, vt, form feed, carriage return
-        if (ch2 == ' ' || ch2 == 0x2028 || ch2 == 0x2029) continue;    // space and Unicode line sep, para sep
-       if (ch2 == '/') {
-            if (pInfo->curr >= pInfo->end) {
-                // whoops; back up and return
-                pInfo->curr --;
-                return true;
-            } else if (*(pInfo->curr) == '/') {
-                pInfo->curr ++;
-                while (pInfo->curr < pInfo->end) {     // go to end of comment line
-                    UniChar ch3 = *(pInfo->curr);
-                    if (ch3 == '\n' || ch3 == '\r' || ch3 == 0x2028 || ch3 == 0x2029) break;
-                    pInfo->curr ++;
-               }
-           } else if (*(pInfo->curr) == '*') {         // handle /* ... */
-                pInfo->curr ++;
-               while (pInfo->curr < pInfo->end) {
-                   ch2 = *(pInfo->curr);
-                    pInfo->curr ++;
-                   if (ch2 == '*' && pInfo->curr < pInfo->end && *(pInfo->curr) == '/') {
-                        pInfo->curr ++; // advance past the '/'
-                        break;
-                    }
-                }
-            } else {
-                pInfo->curr --;
-                return true;
-           }
-        } else {
-            pInfo->curr --;
-            return true;
-        }
-    }
-    return false;
-}
-
-static UniChar getSlashedChar(_CFXMLPlistParseInfo *pInfo) {
-    UniChar ch = *(pInfo->curr);
-    pInfo->curr ++;
-    switch (ch) {
-       case '0':
-       case '1':       
-       case '2':       
-       case '3':       
-       case '4':       
-       case '5':       
-       case '6':       
-       case '7':  {
-            uint8_t num = ch - '0';
-            UniChar result;
-            CFIndex usedCharLen;
-           /* three digits maximum to avoid reading \000 followed by 5 as \5 ! */
-           if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { // we use in this test the fact that the buffer is zero-terminated
-                pInfo->curr ++;
-               num = (num << 3) + ch - '0';
-               if ((pInfo->curr < pInfo->end) && (ch = *(pInfo->curr)) >= '0' && ch <= '7') {
-                    pInfo->curr ++;
-                   num = (num << 3) + ch - '0';
-               }
-           }
-            CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, 0, &num, sizeof(uint8_t), NULL,  &result, 1, &usedCharLen);
-            return (usedCharLen == 1) ? result : 0;
-       }
-       case 'U': {
-           unsigned num = 0, numDigits = 4;    /* Parse four digits */
-           while (pInfo->curr < pInfo->end && numDigits--) {
-                if (((ch = *(pInfo->curr)) < 128) && isxdigit(ch)) { 
-                    pInfo->curr ++;
-                   num = (num << 4) + ((ch <= '9') ? (ch - '0') : ((ch <= 'F') ? (ch - 'A' + 10) : (ch - 'a' + 10)));
-               }
-           }
-           return num;
-       }
-       case 'a':       return '\a';    // Note: the meaning of '\a' varies with -traditional to gcc
-       case 'b':       return '\b';
-       case 'f':       return '\f';
-       case 'n':       return '\n';
-       case 'r':       return '\r';
-       case 't':       return '\t';
-       case 'v':       return '\v';
-       case '"':       return '\"';
-       case '\n':      return '\n';
-    }
-    return ch;
-}
-
-static CFStringRef parseQuotedPlistString(_CFXMLPlistParseInfo *pInfo, UniChar quote) {
-    CFMutableStringRef str = NULL;
-    const UniChar *startMark = pInfo->curr;
-    const UniChar *mark = pInfo->curr;
-    while (pInfo->curr < pInfo->end) {
-       UniChar ch = *(pInfo->curr);
-        if (ch == quote) break;
-        if (ch == '\\') {
-            _catFromMarkToBuf(mark, pInfo->curr, &str, pInfo);
-            pInfo->curr ++;
-            ch = getSlashedChar(pInfo);
-            CFStringAppendCharacters(str, &ch, 1);
-            mark = pInfo->curr;
-       } else {
-            // Note that the original NSParser code was much more complex at this point, but it had to deal with 8-bit characters in a non-UniChar stream.  We always have UniChar (we translated the data by the system encoding at the very beginning, hopefully), so this is safe.
-            pInfo->curr ++;
-        }
-    }
-    if (pInfo->end <= pInfo->curr) {
-        __CFPListRelease(str, pInfo);
-        pInfo->curr = startMark;
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated quoted string starting on line %d"), lineNumber(pInfo));
-        return NULL;
-    }
-    if (!str) {
-        if (pInfo->mutabilityOption == kCFPropertyListMutableContainersAndLeaves) {
-            _catFromMarkToBuf(mark, pInfo->curr, &str, pInfo);
-        } else {
-            str = (CFMutableStringRef)_uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark);
-        }
-    } else {
-        if (mark != pInfo->curr) {
-            _catFromMarkToBuf(mark, pInfo->curr, &str, pInfo);
-        }
-        if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-            CFStringRef uniqueString = _uniqueStringForString(pInfo, str);
-            __CFPListRelease(str, pInfo);
-            str = (CFMutableStringRef)uniqueString;
-        }
-    }
-    pInfo->curr ++;  // Advance past the quote character before returning.
-    if (pInfo->error) {
-        CFRelease(pInfo->error);
-        pInfo->error = NULL;
-    }
-    return str;
-}
-
-static CFStringRef parseUnquotedPlistString(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *mark = pInfo->curr;
-    while (pInfo->curr < pInfo->end) {
-        UniChar ch = *pInfo->curr;
-        if (isValidUnquotedStringCharacter(ch))
-            pInfo->curr ++;
-        else break;
-    }
-    if (pInfo->curr != mark) {
-        if (pInfo->mutabilityOption != kCFPropertyListMutableContainersAndLeaves) {
-            CFStringRef str = _uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark);
-            return str;
-        } else {
-            CFMutableStringRef str = CFStringCreateMutable(pInfo->allocator, 0);
-            CFStringAppendCharacters(str, mark, pInfo->curr - mark);
-            return str;
-        }
-    }
-    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF"));
-    return NULL;
-}
-
-static CFStringRef parsePlistString(_CFXMLPlistParseInfo *pInfo, bool requireObject) {
-    UniChar ch;
-    Boolean foundChar = advanceToNonSpace(pInfo);
-    if (!foundChar) {
-        if (requireObject) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing string"));
-        }
-        return NULL;
-    }
-    ch = *(pInfo->curr);
-    if (ch == '\'' || ch == '\"') {
-        pInfo->curr ++;
-        return parseQuotedPlistString(pInfo, ch);
-    } else if (isValidUnquotedStringCharacter(ch)) {
-        return parseUnquotedPlistString(pInfo);
-    } else {
-        if (requireObject) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid string character at line %d"), lineNumber(pInfo));
-       }
-        return NULL;
-    }
-}
-
-static CFTypeRef parsePlistArray(_CFXMLPlistParseInfo *pInfo) {
-    CFMutableArrayRef array = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks);
-    CFTypeRef tmp = parsePlistObject(pInfo, false);
-    Boolean foundChar;
-    while (tmp) {
-        CFArrayAppendValue(array, tmp);
-        __CFPListRelease(tmp, pInfo);
-        foundChar = advanceToNonSpace(pInfo);
-       if (!foundChar) {
-           __CFPListRelease(array, pInfo);
-           pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected ',' for array at line %d"), lineNumber(pInfo));
-           return NULL;
-       }
-        if (*pInfo->curr != ',') {
-            tmp = NULL;
-        } else {
-            pInfo->curr ++;
-            tmp = parsePlistObject(pInfo, false);
-        }
-    }
-    foundChar = advanceToNonSpace(pInfo);
-    if (!foundChar || *pInfo->curr != ')') {
-        __CFPListRelease(array, pInfo);
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating ')' for array at line %d"), lineNumber(pInfo));
-        return NULL;
-    }
-    if (pInfo->error) {
-        CFRelease(pInfo->error);
-        pInfo->error = NULL;
-    }
-    pInfo->curr ++;
-    return array;
-}
-
-static CFDictionaryRef parsePlistDictContent(_CFXMLPlistParseInfo *pInfo) {
-    CFMutableDictionaryRef dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    CFStringRef key = NULL;
-    Boolean failedParse = false;
-    key = parsePlistString(pInfo, false);
-    while (key) {
-        CFTypeRef value;
-        Boolean foundChar = advanceToNonSpace(pInfo);
-        if (!foundChar) {
-            CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListCreateFromXMLData(): Unexpected end of file. Missing semicolon or value in dictionary."));
-            failedParse = true;
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), lineNumber(pInfo));
-            break;
-        }
-       
-       if (*pInfo->curr == ';') {
-           /* This is a strings file using the shortcut format */
-           /* although this check here really applies to all plists. */
-           value = CFRetain(key);
-       } else if (*pInfo->curr == '=') {
-           pInfo->curr ++;
-           value = parsePlistObject(pInfo, true);
-           if (!value) {
-               failedParse = true;
-               break;
-           }
-       } else {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected ';' or '=' after key at line %d"), lineNumber(pInfo));
-           failedParse = true;
-           break;
-       }
-       CFDictionarySetValue(dict, key, value);
-       __CFPListRelease(key, pInfo);
-       key = NULL;
-       __CFPListRelease(value, pInfo);
-       value = NULL;
-       foundChar = advanceToNonSpace(pInfo);
-       if (foundChar && *pInfo->curr == ';') {
-           pInfo->curr ++;
-           key = parsePlistString(pInfo, false);
-       } else if (true || !foundChar) {
-           CFLog(kCFLogLevelWarning, CFSTR("CFPropertyListCreateFromXMLData(): Old-style plist parser: missing semicolon in dictionary."));
-           failedParse = true;
-           pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), lineNumber(pInfo));
-       }
-    }
-
-    if (failedParse) {
-        __CFPListRelease(key, pInfo);
-        __CFPListRelease(dict, pInfo);
-        return NULL;
-    }
-    if (pInfo->error) {
-        CFRelease(pInfo->error);
-        pInfo->error = NULL;
-    }
-    return dict;
-}
-
-static CFTypeRef parsePlistDict(_CFXMLPlistParseInfo *pInfo) {
-    CFDictionaryRef dict = parsePlistDictContent(pInfo);
-    if (!dict) return NULL;
-    Boolean foundChar = advanceToNonSpace(pInfo);
-    if (!foundChar || *pInfo->curr != '}') {
-        __CFPListRelease(dict, pInfo);
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '}' for dictionary at line %d"), lineNumber(pInfo));
-        return NULL;
-    }
-    pInfo->curr ++;
-    return dict;
-}
-
-CF_INLINE unsigned char fromHexDigit(unsigned char ch) {
-    if (isdigit(ch)) return ch - '0';
-    if ((ch >= 'a') && (ch <= 'f')) return ch - 'a' + 10;
-    if ((ch >= 'A') && (ch <= 'F')) return ch - 'A' + 10;
-    return 0xff; // Just choose a large number for the error code
-}
-
-/* Gets up to bytesSize bytes from a plist data. Returns number of bytes actually read. Leaves cursor at first non-space, non-hex character.
-   -1 is returned for unexpected char, -2 for uneven number of hex digits
-*/
-static int getDataBytes(_CFXMLPlistParseInfo *pInfo, unsigned char *bytes, int bytesSize) {
-    int numBytesRead = 0;
-    while ((pInfo->curr < pInfo->end) && (numBytesRead < bytesSize)) {
-       int first, second;
-       UniChar ch1 = *pInfo->curr;
-       if (ch1 == '>') return numBytesRead;  // Meaning we're done
-       first = fromHexDigit((unsigned char)ch1);
-       if (first != 0xff) {    // If the first char is a hex, then try to read a second hex
-           pInfo->curr++;
-           if (pInfo->curr >= pInfo->end) return -2;   // Error: uneven number of hex digits
-           UniChar ch2 = *pInfo->curr;
-           second = fromHexDigit((unsigned char)ch2);
-           if (second == 0xff) return -2;  // Error: uneven number of hex digits
-           bytes[numBytesRead++] = (first << 4) + second;
-           pInfo->curr++;
-       } else if (ch1 == ' ' || ch1 == '\n' || ch1 == '\t' || ch1 == '\r' || ch1 == 0x2028 || ch1 == 0x2029) {
-           pInfo->curr++;
-       } else {
-           return -1;  // Error: unexpected character
-       }
-    }
-    return numBytesRead;    // This does likely mean we didn't encounter a '>', but we'll let the caller deal with that
-}
-
-#define numBytes 400
-static CFTypeRef parsePlistData(_CFXMLPlistParseInfo *pInfo) {
-    CFMutableDataRef result = CFDataCreateMutable(pInfo->allocator, 0);
-
-    // Read hex bytes and append them to result
-    while (1) {
-       unsigned char bytes[numBytes];
-       int numBytesRead = getDataBytes(pInfo, bytes, numBytes);
-       if (numBytesRead < 0) {
-           __CFPListRelease(result, pInfo);
-            switch (numBytesRead) {
-                case -2: 
-                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; uneven length"), lineNumber(pInfo));
-                    break;
-                default: 
-                    pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; invalid hex"), lineNumber(pInfo));
-                    break;
-            }
-           return NULL;
-       }
-       if (numBytesRead == 0) break;
-       CFDataAppendBytes(result, bytes, numBytesRead);
-    }
-
-    if (pInfo->error) {
-        CFRelease(pInfo->error);
-        pInfo->error = NULL;
-    }
-
-    if (*(pInfo->curr) == '>') {
-        pInfo->curr ++; // Move past '>'
-        return result;
-    } else {
-        __CFPListRelease(result, pInfo);
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '>' for data at line %d"), lineNumber(pInfo));
-        return NULL;
-    }
-}
-#undef numBytes
-
-// Returned object is retained; caller must free.
-static CFTypeRef parsePlistObject(_CFXMLPlistParseInfo *pInfo, bool requireObject) {
-    UniChar ch;
-    Boolean foundChar = advanceToNonSpace(pInfo);
-    if (!foundChar) {
-        if (requireObject) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"));
-        }
-        return NULL;
-    }
-    ch = *(pInfo->curr);
-    pInfo->curr ++;
-    if (ch == '{') {
-        return parsePlistDict(pInfo);
-    } else if (ch == '(') {
-        return parsePlistArray(pInfo);
-    } else if (ch == '<') {
-        return parsePlistData(pInfo);
-    } else if (ch == '\'' || ch == '\"') {
-        return parseQuotedPlistString(pInfo, ch);
-    } else if (isValidUnquotedStringCharacter(ch)) {
-        pInfo->curr --;
-        return parseUnquotedPlistString(pInfo);
-    } else {
-        pInfo->curr --;  // Must back off the charcter we just read
-        if (requireObject) {
-            pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character '0x%x' at line %d"), ch, lineNumber(pInfo));
-        }
-        return NULL;
-    }
-}
-
-static CFTypeRef parseOldStylePropertyListOrStringsFile(_CFXMLPlistParseInfo *pInfo) {
-    const UniChar *begin = pInfo->curr;
-    CFTypeRef result;
-    Boolean foundChar = advanceToNonSpace(pInfo);
-    // A file consisting only of whitespace (or empty) is now defined to be an empty dictionary
-    if (!foundChar) return CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    result = parsePlistObject(pInfo, true);
-    foundChar = advanceToNonSpace(pInfo);
-    if (!foundChar) return result;
-    if (!result) return NULL;
-    if (CFGetTypeID(result) != stringtype) {
-        __CFPListRelease(result, pInfo);
-        pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Junk after plist at line %d"), lineNumber(pInfo));
-        return NULL;
-    }
-    __CFPListRelease(result, pInfo);
-    // Check for a strings file (looks like a dictionary without the opening/closing curly braces)
-    pInfo->curr = begin;
-    return parsePlistDictContent(pInfo);
-}
-
-#undef isValidUnquotedStringCharacter
+#pragma mark -
+#pragma mark Property List Copies
 
 static CFArrayRef _arrayDeepImmutableCopy(CFAllocatorRef allocator, CFArrayRef array, CFOptionFlags mutabilityOption) {
     CFArrayRef result = NULL;
index 0b0eaa030aa770a0c4fac364c007047007ac0d92..35ba94a60134f2fe8a95e0ec983c586493653f15 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFPropertyList.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFPROPERTYLIST__)
 #include <CoreFoundation/CFStream.h>
 #endif
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFPropertyListMutabilityOptions) {
     kCFPropertyListImmutable = 0,
     kCFPropertyListMutableContainers,
     kCFPropertyListMutableContainersAndLeaves
 };
-typedef CFOptionFlags CFPropertyListMutabilityOptions;
+
+CF_IMPLICIT_BRIDGING_DISABLED
 
 /*
        Creates a property list object from its XML description; xmlData should
@@ -73,6 +75,8 @@ CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDa
 CF_EXPORT
 CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList);
 
+CF_IMPLICIT_BRIDGING_ENABLED
+
 /*
        Recursively creates a copy of the given property list (so nested arrays
        and dictionaries are copied as well as the top-most container). The
@@ -82,12 +86,11 @@ CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRe
 CF_EXPORT
 CFPropertyListRef CFPropertyListCreateDeepCopy(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFOptionFlags mutabilityOption);
 
-enum {
+typedef CF_ENUM(CFIndex, CFPropertyListFormat) {
     kCFPropertyListOpenStepFormat = 1,
     kCFPropertyListXMLFormat_v1_0 = 100,
     kCFPropertyListBinaryFormat_v1_0 = 200
 };
-typedef CFIndex CFPropertyListFormat;
 
 /* Returns true if the object graph rooted at plist is a valid property list
  * graph -- that is, no cycles, containing only plist objects, and dictionary
@@ -98,6 +101,7 @@ CF_EXPORT
 Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat format);
 
 #if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_EMBEDDED
+CF_IMPLICIT_BRIDGING_DISABLED
 
 /* Writes the bytes of a plist serialization out to the stream.  The
  * stream must be opened and configured -- the function simply writes
@@ -127,16 +131,17 @@ CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStrea
 CF_EXPORT
 CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFStringRef *errorString);
 
+CF_IMPLICIT_BRIDGING_ENABLED
 #endif
 
-#if MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED || __IPHONE_4_0 <=  __IPHONE_OS_VERSION_MAX_ALLOWED
+CF_IMPLICIT_BRIDGING_DISABLED
+
 enum {
     kCFPropertyListReadCorruptError = 3840,              // Error parsing a property list
     kCFPropertyListReadUnknownVersionError = 3841,       // The version number in the property list is unknown
     kCFPropertyListReadStreamError = 3842,               // Stream error reading a property list
     kCFPropertyListWriteStreamError = 3851,              // Stream error writing a property list
-};
-#endif
+} CF_ENUM_AVAILABLE(10_6, 4_0);
 
 /* Create a property list with a CFData input. If the format parameter is non-NULL, it will be set to the format of the data after parsing is complete. The options parameter is used to specify CFPropertyListMutabilityOptions. If an error occurs while parsing the data, the return value will be NULL. Additionally, if an error occurs and the error parameter is non-NULL, the error parameter will be set to a CFError describing the problem, which the caller must release. If the parse succeeds, the returned value is a reference to the new property list. It is the responsibility of the caller to release this value.
  */
@@ -162,8 +167,10 @@ CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef str
 CF_EXPORT
 CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
+CF_IMPLICIT_BRIDGING_ENABLED
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFPROPERTYLIST__ */
 
index d1da4ce4b686639d8584bb0536720082fdeb2858..8a151fc46d7e7953516aa3c2aefee2d0da2c6e10 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFRunLoop.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -35,7 +35,8 @@
 #include <limits.h>
 #include <pthread.h>
 #include <dispatch/dispatch.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
+#include <dispatch/private.h>
 #include <CoreFoundation/CFUserNotification.h>
 #include <mach/mach.h>
 #include <mach/clock_types.h>
 #include <dlfcn.h>
 extern mach_port_t _dispatch_get_main_queue_port_4CF(void);
 extern void _dispatch_main_queue_callback_4CF(mach_msg_header_t *msg);
-#else
+#elif DEPLOYMENT_TARGET_WINDOWS
 #include <process.h>
-__private_extern__ LONGLONG __CFTSRToFiletime(int64_t tsr);
 DISPATCH_EXPORT HANDLE _dispatch_get_main_queue_handle_4CF(void);
 DISPATCH_EXPORT void _dispatch_main_queue_callback_4CF(void);
+
+#define MACH_PORT_NULL 0
+#define mach_port_name_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
 #include <Block.h>
 
+
 static int _LogCFRunLoop = 0;
 
 // for conservative arithmetic safety, such that (TIMER_DATE_LIMIT + TIMER_INTERVAL_LIMIT + kCFAbsoluteTimeIntervalSince1970) * 10^9 < 2^63
@@ -64,6 +73,8 @@ static int _LogCFRunLoop = 0;
 
 static pthread_t kNilPthreadT = { nil, nil };
 #define pthreadPointer(a) a.p
+typedef        int kern_return_t;
+#define KERN_SUCCESS 0
 
 #else
 
@@ -77,7 +88,7 @@ CF_EXPORT bool CFDictionaryGetKeyIfPresent(CFDictionaryRef dict, const void *key
 
 // 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
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
 __private_extern__ uint32_t __CFGetProcessPortCount(void) {
     ipc_info_space_t info;
@@ -130,7 +141,12 @@ __private_extern__ 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) HALT;
+        if (ret != KERN_SUCCESS) {
+            char msg[256];
+            snprintf(msg, 256, "*** Failure from thread_resume (%d) ***", ret);
+            CRSetCrashLogMessage(msg); 
+            HALT;
+        }
         mach_port_deallocate(mach_task_self(), thread);
     }
 }
@@ -175,20 +191,35 @@ 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;
-    ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &result);
-    if (KERN_SUCCESS == ret) {
-        ret = mach_port_insert_right(mach_task_self(), result, result, MACH_MSG_TYPE_MAKE_SEND);
-    } else {
-        __THE_SYSTEM_HAS_NO_PORTS_AVAILABLE__(ret);
-    }
-    if (KERN_SUCCESS == 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);
+    kern_return_t ret = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &result);
+    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; 
+    }
+
+    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;
+    }
+
+    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) mach_port_destroy(mach_task_self(), result);
-    return (KERN_SUCCESS == ret) ? result : CFPORT_NULL;
+    
+    return result;
 }
 
 CF_INLINE void __CFPortFree(__CFPort port) {
@@ -205,20 +236,18 @@ CF_INLINE __CFPortSet __CFPortSetAllocate(void) {
     return (KERN_SUCCESS == ret) ? result : CFPORT_NULL;
 }
 
-CF_INLINE Boolean __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
+CF_INLINE kern_return_t __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
     if (MACH_PORT_NULL == port) {
-        return false;
+        return -1;
     }
-    kern_return_t ret = mach_port_insert_member(mach_task_self(), port, portSet);
-    return (KERN_SUCCESS == ret);
+    return mach_port_insert_member(mach_task_self(), port, portSet);
 }
 
-CF_INLINE Boolean __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
+CF_INLINE kern_return_t __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
     if (MACH_PORT_NULL == port) {
-        return false;
+        return -1;
     }
-    kern_return_t ret = mach_port_extract_member(mach_task_self(), port, portSet);
-    return (KERN_SUCCESS == ret);
+    return mach_port_extract_member(mach_task_self(), port, portSet);
 }
 
 CF_INLINE void __CFPortSetFree(__CFPortSet portSet) {
@@ -290,9 +319,9 @@ static __CFPort *__CFPortSetGetPorts(__CFPortSet portSet, __CFPort *portBuf, uin
     return result;
 }
 
-static Boolean __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
+static kern_return_t __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
     if (NULL == port) {
-        return false;
+        return -1;
     }
     __CFSpinLock(&(portSet->lock));
     if (portSet->used >= portSet->size) {
@@ -304,13 +333,13 @@ static Boolean __CFPortSetInsert(__CFPort port, __CFPortSet portSet) {
     }
     portSet->handles[portSet->used++] = port;
     __CFSpinUnlock(&(portSet->lock));
-    return true;
+    return KERN_SUCCESS;
 }
 
-static Boolean __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
+static kern_return_t __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
     int i, j;
     if (NULL == port) {
-        return false;
+        return -1;
     }
     __CFSpinLock(&(portSet->lock));
     for (i = 0; i < portSet->used; i++) {
@@ -324,7 +353,7 @@ static Boolean __CFPortSetRemove(__CFPort port, __CFPortSet portSet) {
         }
     }
     __CFSpinUnlock(&(portSet->lock));
-    return false;
+    return KERN_SUCCESS;
 }
 
 #endif
@@ -344,7 +373,7 @@ typedef     struct UnsignedWide {
 typedef UnsignedWide           AbsoluteTime;
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 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);
@@ -369,6 +398,55 @@ static uint32_t __CFSendTrivialMachMessage(mach_port_t port, uint32_t msg_id, CF
     if (result == MACH_SEND_TIMED_OUT) mach_msg_destroy(&header);
     return result;
 }
+#elif DEPLOYMENT_TARGET_WINDOWS
+
+static HANDLE mk_timer_create(void) {
+    return CreateWaitableTimer(NULL, FALSE, NULL);
+}
+
+static kern_return_t mk_timer_destroy(HANDLE name) {
+    BOOL res = CloseHandle(name);
+    if (!res) {
+        DWORD err = GetLastError();
+        CFLog(kCFLogLevelError, CFSTR("CFRunLoop: Unable to destroy timer: %d"), err);
+    }
+    return (int)res;
+}
+
+static kern_return_t mk_timer_arm(HANDLE name, LARGE_INTEGER expire_time) {
+    BOOL res = SetWaitableTimer(name, &expire_time, 0, NULL, NULL, FALSE);
+    if (!res) {
+        DWORD err = GetLastError();
+        CFLog(kCFLogLevelError, CFSTR("CFRunLoop: Unable to set timer: %d"), err);
+    }
+    return (int)res;
+}
+
+static kern_return_t mk_timer_cancel(HANDLE name, LARGE_INTEGER *result_time) {
+    BOOL res = CancelWaitableTimer(name);
+    if (!res) {
+        DWORD err = GetLastError();
+        CFLog(kCFLogLevelError, CFSTR("CFRunLoop: Unable to cancel timer: %d"), err);
+    }
+    return (int)res;
+}
+
+// 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) {
+    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) {
+        result.QuadPart = 0;
+    } else {
+        CFTimeInterval amountOfTimeToWait = __CFTSRToTimeInterval(timeDiff);
+        // Result is in 100 ns (10**-7 sec) units to be consistent with a FILETIME.
+        // CFTimeInterval is in seconds.
+        result.QuadPart = -(amountOfTimeToWait * 10000000);
+    }
+    return result;
+}
+
 #endif
 
 /* unlock a run loop and modes before doing callouts/sleeping */
@@ -397,7 +475,7 @@ struct __CFRunLoopMode {
     CFMutableDictionaryRef _portToV1SourceMap;
     __CFPortSet _portSet;
     CFIndex _observerMask;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     mach_port_t _timerPort;
 #endif
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -451,11 +529,7 @@ static void __CFRunLoopModeDeallocate(CFTypeRef cf) {
     if (NULL != rlm->_portToV1SourceMap) CFRelease(rlm->_portToV1SourceMap);
     CFRelease(rlm->_name);
     __CFPortSetFree(rlm->_portSet);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (MACH_PORT_NULL != rlm->_timerPort) mk_timer_destroy(rlm->_timerPort);
-#elif DEPLOYMENT_TARGET_WINDOWS
-    if (NULL != rlm->_timerPort) CloseHandle(rlm->_timerPort);
-#endif
     pthread_mutex_destroy(&rlm->_lock);
     memset((char *)cf + sizeof(CFRuntimeBase), 0x7C, sizeof(struct __CFRunLoopMode) - sizeof(CFRuntimeBase));
 }
@@ -466,12 +540,19 @@ struct _block_item {
     void (^_block)(void);
 };
 
+typedef struct _per_run_data {
+    uint32_t a;
+    uint32_t b;
+    uint32_t stopped;
+    uint32_t ignoreWakeUps;
+} _per_run_data;
+
 struct __CFRunLoop {
     CFRuntimeBase _base;
     pthread_mutex_t _lock;                     /* locked for accessing mode list */
     __CFPort _wakeUpPort;                      // used for CFRunLoopWakeUp 
-    Boolean _ignoreWakeUps;
-    volatile uint32_t *_stopped;
+    Boolean _unused;
+    volatile _per_run_data *_perRunData;              // reset for runs of the run loop
     pthread_t _pthread;
     uint32_t _winthread;
     CFMutableSetRef _commonModes;
@@ -483,31 +564,47 @@ struct __CFRunLoop {
     CFTypeRef _counterpart;
 };
 
-#if DEPLOYMENT_TARGET_WINDOWS
-static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls);
-#endif
-
 /* Bit 0 of the base reserved bits is used for stopped state */
 /* Bit 1 of the base reserved bits is used for sleeping state */
 /* Bit 2 of the base reserved bits is used for deallocating state */
 
+CF_INLINE volatile _per_run_data *__CFRunLoopPushPerRunData(CFRunLoopRef rl) {
+    volatile _per_run_data *previous = rl->_perRunData;
+    rl->_perRunData = (volatile _per_run_data *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(_per_run_data), 0);
+    rl->_perRunData->a = 0x4346524C;
+    rl->_perRunData->b = 0x4346524C; // 'CFRL'
+    rl->_perRunData->stopped = 0x00000000;
+    rl->_perRunData->ignoreWakeUps = 0x00000000;
+    return previous;
+}
+
+CF_INLINE void __CFRunLoopPopPerRunData(CFRunLoopRef rl, volatile _per_run_data *previous) {
+    if (rl->_perRunData) CFAllocatorDeallocate(kCFAllocatorSystemDefault, (void *)rl->_perRunData);
+    rl->_perRunData = previous;
+}
+
 CF_INLINE Boolean __CFRunLoopIsStopped(CFRunLoopRef rl) {
-    return (rl->_stopped && rl->_stopped[2]) ? true : false;
+    return (rl->_perRunData->stopped) ? true : false;
 }
 
 CF_INLINE void __CFRunLoopSetStopped(CFRunLoopRef rl) {
-    if (!rl->_stopped) {
-        rl->_stopped = (uint32_t volatile *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 4 * sizeof(uint32_t), 0);
-        rl->_stopped[0] = 0x4346524C;
-        rl->_stopped[1] = 0x4346524C; // 'CFRL'
-        rl->_stopped[2] = 0x00000000; // here the value is stored
-        rl->_stopped[3] = 0x4346524C;
-    }
-    if (rl->_stopped) rl->_stopped[2] = 0x53544F50;    // 'STOP'
+    rl->_perRunData->stopped = 0x53544F50;     // 'STOP'
 }
 
 CF_INLINE void __CFRunLoopUnsetStopped(CFRunLoopRef rl) {
-    if (rl->_stopped) rl->_stopped[2] = 0x0;
+    rl->_perRunData->stopped = 0x0;
+}
+
+CF_INLINE Boolean __CFRunLoopIsIgnoringWakeUps(CFRunLoopRef rl) {
+    return (rl->_perRunData->ignoreWakeUps) ? true : false;    
+}
+
+CF_INLINE void __CFRunLoopSetIgnoreWakeUps(CFRunLoopRef rl) {
+    rl->_perRunData->ignoreWakeUps = 0x57414B45; // 'WAKE'
+}
+
+CF_INLINE void __CFRunLoopUnsetIgnoreWakeUps(CFRunLoopRef rl) {
+    rl->_perRunData->ignoreWakeUps = 0x0;
 }
 
 CF_INLINE Boolean __CFRunLoopIsSleeping(CFRunLoopRef rl) {
@@ -545,9 +642,9 @@ static CFStringRef __CFRunLoopCopyDescription(CFTypeRef cf) {
     CFMutableStringRef result;
     result = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
 #if DEPLOYMENT_TARGET_WINDOWS
-    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoop %p [%p]>{wakeup port = 0x%x, stopped = %s,\ncurrent mode = %@,\n"), cf, CFGetAllocator(cf), rl->_wakeUpPort, (rl->_stopped && *(rl->_stopped)) ? "true" : "false", rl->_currentMode ? rl->_currentMode->_name : CFSTR("(none)"));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoop %p [%p]>{wakeup port = 0x%x, stopped = %s, ignoreWakeUps = %s, \ncurrent mode = %@,\n"), cf, CFGetAllocator(cf), rl->_wakeUpPort, __CFRunLoopIsStopped(rl) ? "true" : "false", __CFRunLoopIsIgnoringWakeUps(rl) ? "true" : "false", rl->_currentMode ? rl->_currentMode->_name : CFSTR("(none)"));
 #else
-    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoop %p [%p]>{wakeup port = 0x%x, stopped = %s,\ncurrent mode = %@,\n"), cf, CFGetAllocator(cf), rl->_wakeUpPort, (rl->_stopped && (rl->_stopped[2] == 0x53544F50)) ? "true" : "false", rl->_currentMode ? rl->_currentMode->_name : CFSTR("(none)"));
+    CFStringAppendFormat(result, NULL, CFSTR("<CFRunLoop %p [%p]>{wakeup port = 0x%x, stopped = %s, ignoreWakeUps = %s, \ncurrent mode = %@,\n"), cf, CFGetAllocator(cf), rl->_wakeUpPort, __CFRunLoopIsStopped(rl) ? "true" : "false", __CFRunLoopIsIgnoringWakeUps(rl) ? "true" : "false", rl->_currentMode ? rl->_currentMode->_name : CFSTR("(none)"));
 #endif
     CFStringAppendFormat(result, NULL, CFSTR("common modes = %@,\ncommon mode items = %@,\nmodes = %@}\n"), rl->_commonModes, rl->_commonModeItems, rl->_modes);
     return result;
@@ -598,14 +695,21 @@ static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeNam
     rlm->_timers = NULL;
     rlm->_observerMask = 0;
     rlm->_portSet = __CFPortSetAllocate();
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     rlm->_timerPort = mk_timer_create();
-#elif DEPLOYMENT_TARGET_WINDOWS
-    // We use a manual reset timer because it is possible that we will WaitForMultipleObjectsEx on the timer port but not service it on that run loop iteration. The event is reset when we handle the timers.
-    rlm->_timerPort = CreateWaitableTimer(NULL, TRUE, NULL);
-#endif
-    if (!__CFPortSetInsert(rlm->_timerPort, rlm->_portSet)) HALT;
-    if (!__CFPortSetInsert(rl->_wakeUpPort, rlm->_portSet)) HALT;
+    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(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    
     rlm->_msgQMask = 0;
     rlm->_msgPump = NULL;
@@ -1092,6 +1196,7 @@ static void __CFRunLoopDeallocate(CFTypeRef cf) {
     }
     __CFPortFree(rl->_wakeUpPort);
     rl->_wakeUpPort = CFPORT_NULL;
+    __CFRunLoopPopPerRunData(rl, NULL);
     __CFRunLoopUnlock(rl);
     pthread_mutex_destroy(&rl->_lock);
     memset((char *)cf + sizeof(CFRuntimeBase), 0x8C, sizeof(struct __CFRunLoop) - sizeof(CFRuntimeBase));
@@ -1143,11 +1248,11 @@ static CFRunLoopRef __CFRunLoopCreate(pthread_t t) {
     if (NULL == loop) {
        return NULL;
     }
-    loop->_stopped = NULL;
+    (void)__CFRunLoopPushPerRunData(loop);
     __CFRunLoopLockInit(&loop->_lock);
     loop->_wakeUpPort = __CFPortAllocate();
     if (CFPORT_NULL == loop->_wakeUpPort) HALT;
-    loop->_ignoreWakeUps = true;
+    __CFRunLoopSetIgnoreWakeUps(loop);
     loop->_commonModes = CFSetCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeSetCallBacks);
     CFSetAddValue(loop->_commonModes, kCFRunLoopDefaultMode);
     loop->_commonModeItems = NULL;
@@ -1189,8 +1294,8 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
         __CFSpinLock(&loopsLock);
     }
     CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
+    __CFSpinUnlock(&loopsLock);
     if (!loop) {
-        __CFSpinUnlock(&loopsLock);
        CFRunLoopRef newLoop = __CFRunLoopCreate(t);
         __CFSpinLock(&loopsLock);
        loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t));
@@ -1198,6 +1303,8 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
            CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop);
            loop = newLoop;
        }
+        // don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it
+        __CFSpinUnlock(&loopsLock);
        CFRelease(newLoop);
     }
     if (pthread_equal(t, pthread_self())) {
@@ -1206,7 +1313,6 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) {
             _CFSetTSD(__CFTSDKeyRunLoopCntr, (void *)(PTHREAD_DESTRUCTOR_ITERATIONS-1), (void (*)(void *))__CFFinalizeRunLoop);
         }
     }
-    __CFSpinUnlock(&loopsLock);
     return loop;
 }
 
@@ -1552,7 +1658,7 @@ static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(void (*pe
 
 static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() __attribute__((noinline));
 static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         void *(*perform)(void *msg, CFIndex size, CFAllocatorRef allocator, void *info),
         mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply,
 #else
@@ -1560,7 +1666,7 @@ static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(
 #endif
         void *info) {
     if (perform) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         *reply = perform(msg, size, kCFAllocatorSystemDefault, info);
 #else
         perform(info);
@@ -1634,7 +1740,7 @@ static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Bool
 // msg, size and reply are unused on Windows
 static Boolean __CFRunLoopDoSource1() __attribute__((noinline));
 static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                                     , mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply
 #endif
                                     ) {        /* DOES CALLOUT */
@@ -1650,7 +1756,7 @@ static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRun
        __CFRunLoopSourceUnsetSignaled(rls);
        __CFRunLoopSourceUnlock(rls);
         __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(rls->_context.version1.perform,
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             msg, size, reply,
 #endif
             rls->_context.version1.info);
@@ -1702,6 +1808,22 @@ 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;
+        }
+    }
+    if (nextTimer) {
+        int64_t fireTSR = nextTimer->_fireTSR;
+        fireTSR = (fireTSR / tenus + 1) * tenus;
+        mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
+    }
+}
+
 // 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) {
@@ -1718,25 +1840,7 @@ static void __CFRepositionTimerInMode(CFRunLoopModeRef rlm, CFRunLoopTimerRef rl
     if (!found && isInArray) return;
     CFIndex newIdx = __CFRunLoopInsertionIndexInTimerArray(rlm->_timers, rlt);
     CFArrayInsertValueAtIndex(rlm->_timers, newIdx, rlt);
-    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;
-        }
-    }
-    if (nextTimer) {
-        int64_t fireTSR = nextTimer->_fireTSR;
-        fireTSR = (fireTSR / tenus + 1) * tenus;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-        mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
-#elif DEPLOYMENT_TARGET_WINDOWS
-        LARGE_INTEGER dueTime;
-        dueTime.QuadPart = __CFTSRToFiletime(fireTSR);
-        SetWaitableTimer(rlm->_timerPort, &dueTime, 0, NULL, NULL, FALSE);
-#endif
-    }
+    __CFArmNextTimerInMode(rlm);
     if (isInArray) CFRelease(rlt);
 }
 
@@ -1765,25 +1869,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo
        oldFireTSR = rlt->_fireTSR;
        __CFRunLoopTimerFireTSRUnlock();
 
-        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;
-            }
-        }
-        if (nextTimer) {
-            int64_t fireTSR = nextTimer->_fireTSR;
-            fireTSR = (fireTSR / tenus + 1) * tenus;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-            mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
-#elif DEPLOYMENT_TARGET_WINDOWS
-            LARGE_INTEGER dueTime;
-            dueTime.QuadPart = __CFTSRToFiletime(fireTSR);
-            SetWaitableTimer(rlm->_timerPort, &dueTime, 0, NULL, NULL, FALSE);
-#endif
-        }
+        __CFArmNextTimerInMode(rlm);
 
        __CFRunLoopModeUnlock(rlm);
        __CFRunLoopUnlock(rl);
@@ -1815,25 +1901,7 @@ 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.
-            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;
-                }
-            }
-            if (nextTimer) {
-                int64_t fireTSR = nextTimer->_fireTSR;
-                fireTSR = (fireTSR / tenus + 1) * tenus;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-                mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
-#else
-                LARGE_INTEGER dueTime;
-                dueTime.QuadPart = __CFTSRToFiletime(fireTSR);
-                SetWaitableTimer(rlm->_timerPort, &dueTime, 0, NULL, NULL, FALSE);
-#endif
-            }
+            __CFArmNextTimerInMode(rlm);
         } else {
            int64_t nextFireTSR = 0LL;
             int64_t intervalTSR = 0LL;
@@ -1937,7 +2005,7 @@ CF_EXPORT Boolean _CFRunLoopFinished(CFRunLoopRef rl, CFStringRef modeName) {
 
 static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) __attribute__((noinline));
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
 #define TIMEOUT_INFINITY (~(mach_msg_timeout_t)0)
 
@@ -2044,15 +2112,6 @@ static void __CFRunLoopTimeout(void *arg) {
     // The interval is DISPATCH_TIME_FOREVER, so this won't fire again
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
-#define MACH_PORT_NULL 0
-#define mach_port_name_t HANDLE
-#define _dispatch_get_main_queue_port_4CF _dispatch_get_main_queue_handle_4CF
-#else
-#error Unknown deployment target - CFRunLoop not functional
-#endif
-
 /* 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();
@@ -2064,7 +2123,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
        rlm->_stopped = false;
        return kCFRunLoopRunStopped;
     }
-
+    
     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();
@@ -2096,7 +2155,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
     int32_t retVal = 0;
     do {
         uint8_t msg_buffer[3 * 1024];
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         mach_msg_header_t *msg = NULL;
 #elif DEPLOYMENT_TARGET_WINDOWS
         HANDLE livePort = NULL;
@@ -2104,7 +2163,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
 #endif
        __CFPortSet waitSet = rlm->_portSet;
 
-       rl->_ignoreWakeUps = false;
+        __CFRunLoopUnsetIgnoreWakeUps(rl);
 
         if (rlm->_observerMask & kCFRunLoopBeforeTimers) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers);
         if (rlm->_observerMask & kCFRunLoopBeforeSources) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources);
@@ -2119,7 +2178,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         Boolean poll = sourceHandledThisLoop || (0LL == timeout_context->termTSR);
 
         if (MACH_PORT_NULL != dispatchPort && !didDispatchPortLastTime) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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)) {
                 goto handle_msg;
@@ -2142,11 +2201,11 @@ 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
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         if (kCFUseCollectableAllocator) {
             objc_clear_stack(0);
             memset(msg_buffer, 0, sizeof(msg_buffer));
@@ -2155,7 +2214,6 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), poll ? 0 : TIMEOUT_INFINITY);
 #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.
-        // Note: don't pass 0 for polling, or this thread will never yield the CPU.
         __CFRunLoopWaitForMultipleObjects(waitSet, NULL, poll ? 0 : TIMEOUT_INFINITY, rlm->_msgQMask, &livePort, &windowsMessageReceived);
 #endif
         
@@ -2168,17 +2226,17 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
         // in there if this function returns.
 
         __CFPortSetRemove(dispatchPort, waitSet);
-
-       rl->_ignoreWakeUps = true;
+        
+        __CFRunLoopSetIgnoreWakeUps(rl);
 
         // user callouts now OK again
        __CFRunLoopUnsetSleeping(rl);
        if (!poll && (rlm->_observerMask & kCFRunLoopAfterWaiting)) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting);
 
         handle_msg:;
-       rl->_ignoreWakeUps = true;
+        __CFRunLoopSetIgnoreWakeUps(rl);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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
@@ -2200,7 +2258,23 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
             __CFRunLoopLock(rl);
            __CFRunLoopModeLock(rlm);
            sourceHandledThisLoop = true;
-        } else
+            
+            // To prevent starvation of sources other than the message queue, we check again to see if any other sources need to be serviced
+            // Use 0 for the mask so windows messages are ignored this time. Also use 0 for the timeout, because we're just checking to see if the things are signalled right now -- we will wait on them again later.
+            // NOTE: Ignore the dispatch source (it's not in the wait set anymore) and also don't run the observers here since we are polling.
+            __CFRunLoopSetSleeping(rl);
+            __CFRunLoopModeUnlock(rlm);
+            __CFRunLoopUnlock(rl);
+            
+            __CFRunLoopWaitForMultipleObjects(waitSet, NULL, 0, 0, &livePort, NULL);
+            
+            __CFRunLoopLock(rl);
+            __CFRunLoopModeLock(rlm);            
+            __CFRunLoopUnsetSleeping(rl);
+            // If we have a new live port then it will be handled below as normal
+        }
+        
+        
 #endif
         if (MACH_PORT_NULL == livePort) {
             // handle nothing
@@ -2212,32 +2286,30 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
 #endif
         } else if (livePort == rlm->_timerPort) {
 #if DEPLOYMENT_TARGET_WINDOWS
-            // We use a manual reset timer to ensure that we don't miss timers firing because the run loop did the wakeUpPort this time
-            // The only way to reset a timer is to reset the timer using SetWaitableTimer. We don't want it to fire again though, so we set the timeout to a large negative value. The timer may be reset again inside the timer handling code.
-            LARGE_INTEGER dueTime;
-            dueTime.QuadPart = LONG_MIN;
-            SetWaitableTimer(rlm->_timerPort, &dueTime, 0, NULL, NULL, FALSE);
+            // 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.
+            // 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);
+            }
+#else
+            __CFRunLoopDoTimers(rl, rlm, mach_absolute_time());
 #endif
-           __CFRunLoopDoTimers(rl, rlm, mach_absolute_time());
         } else if (livePort == dispatchPort) {
-           __CFRunLoopModeUnlock(rlm);
-           __CFRunLoopUnlock(rl);
+               __CFRunLoopModeUnlock(rlm);
+               __CFRunLoopUnlock(rl);
             _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-           _dispatch_main_queue_callback_4CF(msg);
-#elif DEPLOYMENT_TARGET_WINDOWS
-            _dispatch_main_queue_callback_4CF();
-#endif
+               _dispatch_main_queue_callback_4CF(msg);
             _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL);
-           __CFRunLoopLock(rl);
-           __CFRunLoopModeLock(rlm);
-           sourceHandledThisLoop = true;
+               __CFRunLoopLock(rl);
+               __CFRunLoopModeLock(rlm);
+               sourceHandledThisLoop = true;
             didDispatchPortLastTime = true;
         } else {
             // Despite the name, this works for windows handles as well
             CFRunLoopSourceRef rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort);
             if (rls) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                mach_msg_header_t *reply = NULL;
                sourceHandledThisLoop = __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply) || sourceHandledThisLoop;
                if (NULL != reply) {
@@ -2249,7 +2321,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter
 #endif
            }
         } 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         if (msg && msg != (mach_msg_header_t *)msg_buffer) free(msg);
 #endif
         
@@ -2291,8 +2363,7 @@ SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterva
        __CFRunLoopUnlock(rl);
        return did ? kCFRunLoopRunHandledSource : kCFRunLoopRunFinished;
     }
-    uint32_t *previousStopped = (uint32_t *)rl->_stopped;
-    rl->_stopped = NULL;
+    volatile _per_run_data *previousPerRun = __CFRunLoopPushPerRunData(rl);
     CFRunLoopModeRef previousMode = rl->_currentMode;
     rl->_currentMode = currentMode;
     int32_t result;
@@ -2300,8 +2371,7 @@ SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterva
        result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
        if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit);
         __CFRunLoopModeUnlock(currentMode);
-       if (rl->_stopped) CFAllocatorDeallocate(kCFAllocatorSystemDefault, (uint32_t *)rl->_stopped);
-       rl->_stopped = previousStopped;
+        __CFRunLoopPopPerRunData(rl, previousPerRun);
        rl->_currentMode = previousMode;
     __CFRunLoopUnlock(rl);
     return result;
@@ -2341,20 +2411,23 @@ void CFRunLoopWakeUp(CFRunLoopRef rl) {
     CHECK_FOR_FORK();
     // This lock is crucial to ignorable wakeups, do not remove it.
     __CFRunLoopLock(rl);
-    if (rl->_ignoreWakeUps) {
+    if (__CFRunLoopIsIgnoringWakeUps(rl)) {
         __CFRunLoopUnlock(rl);
         return;
     }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     kern_return_t ret;
     /* We unconditionally try to send the message, since we don't want
      * 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;
     }
-#else
+#elif DEPLOYMENT_TARGET_WINDOWS
     SetEvent(rl->_wakeUpPort);
 #endif
     __CFRunLoopUnlock(rl);
@@ -2430,12 +2503,7 @@ void CFRunLoopPerformBlock(CFRunLoopRef rl, CFTypeRef mode, void (^block)(void))
     } else {
        mode = NULL;
     }
-#if DEPLOYMENT_TARGET_WINDOWS
-    // <rdar://problem/7659483> clang ObjC rewriter: __typeof(block) not rewritten correctly
-    block = (void (^)(void))_Block_copy(block);
-#else
     block = Block_copy(block);
-#endif
     if (!mode || !block) {
        if (mode) CFRelease(mode);
        if (block) Block_release(block);
@@ -2765,7 +2833,7 @@ Boolean CFRunLoopContainsTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringR
     return hasValue;
 }
 
-void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeName) {
+void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeName) {    
     CHECK_FOR_FORK();
     if (__CFRunLoopIsDeallocating(rl)) return;
     if (!__CFIsValid(rlt) || (NULL != rlt->_runLoop && rlt->_runLoop != rl)) return;
@@ -2847,32 +2915,10 @@ void CFRunLoopRemoveTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef mo
             __CFRunLoopTimerUnlock(rlt);
            CFArrayRemoveValueAtIndex(rlm->_timers, idx);
             if (0 == CFArrayGetCount(rlm->_timers)) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
                 AbsoluteTime dummy;
                 mk_timer_cancel(rlm->_timerPort, &dummy);
-#elif DEPLOYMENT_TARGET_WINDOWS
-                CancelWaitableTimer(rlm->_timerPort);
-#endif
             } else if (0 == idx) {
-                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;
-                    }
-                }
-                if (nextTimer) {
-                   int64_t fireTSR = nextTimer->_fireTSR;
-                   fireTSR = (fireTSR / tenus + 1) * tenus;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-                   mk_timer_arm(rlm->_timerPort, __CFUInt64ToAbsoluteTime(fireTSR));
-#elif DEPLOYMENT_TARGET_WINDOWS
-                    LARGE_INTEGER dueTime;
-                    dueTime.QuadPart = __CFTSRToFiletime(fireTSR);
-                    SetWaitableTimer(rlm->_timerPort, &dueTime, 0, NULL, NULL, FALSE);
-#endif
-                }
+                __CFArmNextTimerInMode(rlm);
             }
        }
         if (NULL != rlm) {
@@ -2918,12 +2964,10 @@ static CFStringRef __CFRunLoopSourceCopyDescription(CFTypeRef cf) {     /* DOES CALL
        void *addr = rls->_context.version0.version == 0 ? (void *)rls->_context.version0.perform : (rls->_context.version0.version == 1 ? (void *)rls->_context.version1.perform : NULL);
 #if DEPLOYMENT_TARGET_WINDOWS
        contextDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopSource context>{version = %ld, info = %p, callout = %p}"), rls->_context.version0.version, rls->_context.version0.info, addr);
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        Dl_info info;
        const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
        contextDesc = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopSource context>{version = %ld, info = %p, callout = %s (%p)}"), rls->_context.version0.version, rls->_context.version0.info, name, addr);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     }
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -2969,7 +3013,10 @@ CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order
     CHECK_FOR_FORK();
     CFRunLoopSourceRef memory;
     uint32_t size;
-    if (NULL == context) HALT;
+    if (NULL == context) {
+        CRSetCrashLogMessage("*** NULL context value passed to CFRunLoopSourceCreate(). ***"); 
+        HALT;
+    }
     size = sizeof(struct __CFRunLoopSource) - sizeof(CFRuntimeBase);
     memory = (CFRunLoopSourceRef)_CFRuntimeCreateInstance(allocator, __kCFRunLoopSourceTypeID, size, NULL);
     if (NULL == memory) {
@@ -3122,13 +3169,11 @@ static CFStringRef __CFRunLoopObserverCopyDescription(CFTypeRef cf) {   /* DOES CA
     }
 #if DEPLOYMENT_TARGET_WINDOWS
     result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopObserver %p [%p]>{valid = %s, activities = 0x%x, repeats = %s, order = %d, callout = %p, context = %@}"), cf, CFGetAllocator(rlo), __CFIsValid(rlo) ? "Yes" : "No", rlo->_activities, __CFRunLoopObserverRepeats(rlo) ? "Yes" : "No", rlo->_order, rlo->_callout, contextDesc);    
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     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);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     CFRelease(contextDesc);
     return result;
@@ -3300,14 +3345,11 @@ static CFStringRef __CFRunLoopTimerCopyDescription(CFTypeRef cf) {      /* DOES CALLO
     }
     void *addr = (void *)rlt->_callout;
     const char *name = "???";
-#if DEPLOYMENT_TARGET_WINDOWS
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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 : "???";
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
-    CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFRunLoopTimer %p [%p]>{valid = %s, interval = %0.09g, next fire date = %0.09g, callout = %s (%p), context = %@}"), cf, CFGetAllocator(rlt), __CFIsValid(rlt) ? "Yes" : "No", rlt->_interval, rlt->_nextFireDate, name, addr, contextDesc);
+    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);
     CFRelease(contextDesc);
     return result;
 }
@@ -3410,7 +3452,7 @@ CFRunLoopTimerRef CFRunLoopTimerCreateWithHandler(CFAllocatorRef allocator, CFAb
 
 CFAbsoluteTime CFRunLoopTimerGetNextFireDate(CFRunLoopTimerRef rlt) {
     CHECK_FOR_FORK();
-    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, CFAbsoluteTime, rlt, "_cffireTime");
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, CFAbsoluteTime, (NSTimer *)rlt, _cffireTime);
     __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
     CFAbsoluteTime at = 0.0;
     __CFRunLoopTimerLock(rlt);
@@ -3489,7 +3531,7 @@ void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDat
 
 CFTimeInterval CFRunLoopTimerGetInterval(CFRunLoopTimerRef rlt) {
     CHECK_FOR_FORK();
-    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, CFTimeInterval, rlt, "timeInterval");
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, CFTimeInterval, (NSTimer *)rlt, timeInterval);
     __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
     return rlt->_interval;
 }
@@ -3508,7 +3550,7 @@ CFIndex CFRunLoopTimerGetOrder(CFRunLoopTimerRef rlt) {
 
 void CFRunLoopTimerInvalidate(CFRunLoopTimerRef rlt) { /* DOES CALLOUT */
     CHECK_FOR_FORK();
-    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, void, rlt, "invalidate");
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, void, (NSTimer *)rlt, invalidate);
     __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
     __CFRunLoopTimerLock(rlt);
     if (!__CFRunLoopTimerIsDeallocating(rlt)) {
@@ -3559,7 +3601,7 @@ void CFRunLoopTimerInvalidate(CFRunLoopTimerRef rlt) {    /* DOES CALLOUT */
 
 Boolean CFRunLoopTimerIsValid(CFRunLoopTimerRef rlt) {
     CHECK_FOR_FORK();
-    CF_OBJC_FUNCDISPATCH0(__kCFRunLoopTimerTypeID, Boolean, rlt, "isValid");
+    CF_OBJC_FUNCDISPATCHV(__kCFRunLoopTimerTypeID, Boolean, (NSTimer *)rlt, isValid);
     __CFGenericValidateType(rlt, __kCFRunLoopTimerTypeID);
     return __CFIsValid(rlt);
 }
index 018f039ac72b7f88b7e7dc66ec72dd7a1c180c98..e2eb7f3abced714bfb268506cbfcee63bcebc2b1 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFRunLoop.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFRUNLOOP__)
@@ -55,7 +55,7 @@ enum {
 };
 
 /* Run Loop Observer Activities */
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFRunLoopActivity) {
     kCFRunLoopEntry = (1UL << 0),
     kCFRunLoopBeforeTimers = (1UL << 1),
     kCFRunLoopBeforeSources = (1UL << 2),
@@ -64,7 +64,6 @@ enum {
     kCFRunLoopExit = (1UL << 7),
     kCFRunLoopAllActivities = 0x0FFFFFFFU
 };
-typedef CFOptionFlags CFRunLoopActivity;
 
 CF_EXPORT const CFStringRef kCFRunLoopDefaultMode;
 CF_EXPORT const CFStringRef kCFRunLoopCommonModes;
index 981dcee9f3d64cce213f9828f26f494a54043e26..6a5ee6d29bcfaa3a5598c02484d8bf723da513a5 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFRuntime.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -34,7 +34,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdio.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <dlfcn.h>
 #include <mach-o/dyld.h>
 #include <mach/mach.h>
 #include <sys/stat.h>
 #include <CoreFoundation/CFStringDefaultEncoding.h>
 #endif
+#if DEPLOYMENT_TARGET_EMBEDDED
+// This isn't in the embedded runtime.h header
+OBJC_EXPORT void *objc_destructInstance(id obj);
+#endif
 
 
 
@@ -66,6 +70,7 @@ __kCFReleaseEvent = 29
 #define FAKE_INSTRUMENTS 0
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+__private_extern__ void __CFOAInitializeNSObject(void);  // from NSObject.m
 
 bool __CFOASafe = false;
 
@@ -73,17 +78,6 @@ void (*__CFObjectAllocRecordAllocationFunction)(int, void *, int64_t , uint64_t,
 void (*__CFObjectAllocSetLastAllocEventNameFunction)(void *, const char *) = NULL;
 
 void __CFOAInitialize(void) {
-    static void (*dyfunc)(void) = (void *)~0;
-    if (NULL == __CFgetenv("OAKeepAllocationStatistics")) return;
-    if ((void *)~0 == dyfunc) {
-       dyfunc = dlsym(RTLD_DEFAULT, "_OAInitialize");
-    }
-    if (NULL != dyfunc) {
-       dyfunc();
-       __CFObjectAllocRecordAllocationFunction = dlsym(RTLD_DEFAULT, "_OARecordAllocationEvent");
-       __CFObjectAllocSetLastAllocEventNameFunction = dlsym(RTLD_DEFAULT, "_OASetLastAllocationEventName");
-       __CFOASafe = true;
-    }
 }
 
 void __CFRecordAllocationEvent(int eventnum, void *ptr, int64_t size, uint64_t data, const char *classname) {
@@ -205,8 +199,8 @@ 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;
-static CFRuntimeClass * __CFRuntimeClassTable[__CFRuntimeClassTableSize] = {0};
-static int32_t __CFRuntimeClassTableCount = 0;
+__private_extern__ CFRuntimeClass * __CFRuntimeClassTable[__CFRuntimeClassTableSize] = {0};
+__private_extern__ int32_t __CFRuntimeClassTableCount = 0;
 
 __private_extern__ uintptr_t __CFRuntimeObjCClassTable[__CFRuntimeClassTableSize] = {0};
 
@@ -214,13 +208,22 @@ __private_extern__ uintptr_t __CFRuntimeObjCClassTable[__CFRuntimeClassTableSize
 bool (*__CFObjCIsCollectable)(void *) = NULL;
 #endif
 
+#if !__CONSTANT_CFSTRINGS__ || DEPLOYMENT_TARGET_EMBEDDED_MINI
 // Compiler uses this symbol name; must match compiler built-in decl, so we use 'int'
 #if __LP64__
 int __CFConstantStringClassReference[24] = {0};
 #else
 int __CFConstantStringClassReference[12] = {0};
 #endif
-void *__CFConstantStringClassReferencePtr = &__CFConstantStringClassReference;
+#endif
+
+#if __LP64__
+int __CFConstantStringClassReference[24] = {0};
+#else
+int __CFConstantStringClassReference[12] = {0};
+#endif
+
+void *__CFConstantStringClassReferencePtr = NULL;
 
 Boolean _CFIsObjC(CFTypeID typeID, void *obj) {
     return CF_IS_OBJC(typeID, obj);
@@ -266,8 +269,9 @@ void _CFRuntimeUnregisterClassWithTypeID(CFTypeID typeID) {
 __private_extern__ uint8_t __CFZombieEnabled = 0;
 __private_extern__ uint8_t __CFDeallocateZombies = 0;
 
+extern void __CFZombifyNSObject(void);  // from NSObject.m
+
 void _CFEnableZombies(void) {
-    __CFZombieEnabled = 0xFF;
 }
 
 #endif /* DEBUG */
@@ -402,7 +406,7 @@ enum {
 #if DEPLOYMENT_TARGET_MACOSX
 #define NUM_EXTERN_TABLES 8
 #define EXTERN_TABLE_IDX(O) (((uintptr_t)(O) >> 8) & 0x7)
-#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #define NUM_EXTERN_TABLES 1
 #define EXTERN_TABLE_IDX(O) 0
 #else
@@ -545,7 +549,7 @@ __private_extern__ void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, co
 
 CFTypeID CFGetTypeID(CFTypeRef cf) {
 #if defined(DEBUG)
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFGetTypeID() called with NULL ***"); HALT; }
 #endif
     CFTYPE_OBJC_FUNCDISPATCH0(CFTypeID, cf, _cfTypeID);
     __CFGenericAssertIsCF(cf);
@@ -562,7 +566,7 @@ CFStringRef CFCopyTypeIDDescription(CFTypeID type) {
 static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR);
 
 CFTypeRef CFRetain(CFTypeRef cf) {
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFRetain() called with NULL ***"); HALT; }
     if (cf) __CFGenericAssertIsCF(cf);
     return _CFRetain(cf, false);
 }
@@ -570,7 +574,7 @@ CFTypeRef CFRetain(CFTypeRef cf) {
 static void _CFRelease(CFTypeRef cf);
 
 void CFRelease(CFTypeRef cf) {
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFRelease() called with NULL ***"); HALT; }
 #if 0
     void **addrs[2] = {&&start, &&end};
     start:;
@@ -590,7 +594,7 @@ void CFRelease(CFTypeRef cf) {
 __private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
 
 __private_extern__ const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr) {
-    if (NULL == ptr) HALT;
+    if (NULL == ptr) { CRSetCrashLogMessage("*** __CFStringCollectionCopy() called with NULL ***"); HALT; }
     CFStringRef theString = (CFStringRef)ptr;
     CFStringRef result = CFStringCreateCopy(_CFConvertAllocatorToGCRefZeroEquivalent(allocator), theString);
     return (const void *)result;
@@ -599,7 +603,7 @@ __private_extern__ const void *__CFStringCollectionCopy(CFAllocatorRef allocator
 extern void CFCollection_non_gc_storage_error(void);
 
 __private_extern__ const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr) {
-    if (NULL == ptr) HALT;
+    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.
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
@@ -634,7 +638,7 @@ __private_extern__ const void *__CFTypeCollectionRetain(CFAllocatorRef allocator
 
 
 __private_extern__ void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr) {
-    if (NULL == ptr) HALT;
+    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.
     if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
@@ -671,7 +675,7 @@ static CFSpinLock_t __CFRuntimeExternRefCountTableLock = CFSpinLockInit;
 #endif
 
 static uint64_t __CFGetFullRetainCount(CFTypeRef cf) {
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** __CFGetFullRetainCount() called with NULL ***"); HALT; }
 #if __LP64__
     uint32_t lowBits = ((CFRuntimeBase *)cf)->_rc;
     if (0 == lowBits) {
@@ -693,7 +697,7 @@ static uint64_t __CFGetFullRetainCount(CFTypeRef cf) {
 }
 
 CFIndex CFGetRetainCount(CFTypeRef cf) {
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFGetRetainCount() called with NULL ***"); HALT; }
     uint32_t cfinfo = *(uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo);
     if (cfinfo & 0x800000) { // custom ref counting for object
         CFTypeID typeID = (cfinfo >> 8) & 0x03FF; // mask up to 0x0FFF
@@ -732,8 +736,8 @@ CFTypeRef CFMakeUncollectable(CFTypeRef cf) {
 }
 
 Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2) {
-    if (NULL == cf1) HALT;
-    if (NULL == cf2) HALT;
+    if (NULL == cf1) { CRSetCrashLogMessage("*** CFEqual() called with NULL first argument ***"); HALT; }
+    if (NULL == cf2) { CRSetCrashLogMessage("*** CFEqual() called with NULL second argument ***"); HALT; }
     if (cf1 == cf2) return true;
     CFTYPE_OBJC_FUNCDISPATCH1(Boolean, cf1, isEqual:, cf2);
     CFTYPE_OBJC_FUNCDISPATCH1(Boolean, cf2, isEqual:, cf1);
@@ -747,7 +751,7 @@ Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2) {
 }
 
 CFHashCode CFHash(CFTypeRef cf) {
-    if (NULL == cf) HALT;
+    if (NULL == cf) { CRSetCrashLogMessage("*** CFHash() called with NULL ***"); HALT; }
     CFTYPE_OBJC_FUNCDISPATCH0(CFHashCode, cf, hash);
     __CFGenericAssertIsCF(cf);
     CFHashCode (*hash)(CFTypeRef cf) = __CFRuntimeClassTable[__CFGenericTypeID_inline(cf)]->hash; 
@@ -802,7 +806,7 @@ extern void __CFStorageInitialize(void);
 extern void __CFErrorInitialize(void);
 extern void __CFTreeInitialize(void);
 extern void __CFURLInitialize(void);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 extern void __CFMachPortInitialize(void);
 #endif
 extern void __CFMessagePortInitialize(void);
@@ -810,6 +814,7 @@ extern void __CFRunLoopInitialize(void);
 extern void __CFRunLoopObserverInitialize(void);
 extern void __CFRunLoopSourceInitialize(void);
 extern void __CFRunLoopTimerInitialize(void);
+extern void __CFPFactoryInitialize(void);
 extern void __CFBundleInitialize(void);
 extern void __CFPlugInInitialize(void);
 extern void __CFPlugInInstanceInitialize(void);
@@ -832,12 +837,15 @@ extern void __CFTimeZoneInitialize();
 extern void __CFCalendarInitialize();
 extern void __CFTimeZoneInitialize();
 #endif
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+extern void __CFXPreferencesInitialize(void);
+#endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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;
+__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
 asm(".desc ___crashreporter_info__, 0x10");
 
 static void __01121__(void) {
@@ -851,11 +859,13 @@ static void __01123__(void) {
     // This is not a problem for CF.
     if (__CF120290) {
        __CF120293 = true;
+#if DEPLOYMENT_TARGET_MACOSX
        if (__CF120291) {
-           __crashreporter_info__ = "*** multi-threaded process forked ***";
+           CRSetCrashLogMessage2("*** multi-threaded process forked ***");
        } else {
-           __crashreporter_info__ = "*** single-threaded process forked ***";
+           CRSetCrashLogMessage2("*** single-threaded process forked ***");
        }
+#endif
     }
 }
 
@@ -874,12 +884,13 @@ CF_EXPORT const void *__CFArgStuff;
 const void *__CFArgStuff = NULL;
 __private_extern__ void *__CFAppleLanguages = NULL;
 
+// do not cache CFFIXED_USER_HOME or HOME, there are situations where they can change
+
 static struct {
     const char *name;
     const char *value;
 } __CFEnv[] = {
     {"PATH", NULL},
-    {"HOME", NULL},
     {"USER", NULL},
     {"HOMEPATH", NULL},
     {"HOMEDRIVE", NULL},
@@ -889,7 +900,6 @@ static struct {
     {"NEXT_ROOT", NULL},
     {"DYLD_IMAGE_SUFFIX", NULL},
     {"CFProcessPath", NULL},
-    {"CFFIXED_USER_HOME", NULL},
     {"CFNETWORK_LIBRARY_PATH", NULL},
     {"CFUUIDVersionNumber", NULL},
     {"CFDebugNamedDataSharing", NULL},
@@ -902,8 +912,9 @@ static struct {
     {"CF_CHARSET_PATH", NULL},
     {"__CF_USER_TEXT_ENCODING", NULL},
     {"__CFPREFERENCES_AUTOSYNC_INTERVAL", NULL},
-    {"__CFPREFERENCES_USE_OLD_UID_BEHAVIOR", NULL},
+    {"__CFPREFERENCES_LOG_FAILURES", NULL},
     {"CFNumberDisableCache", NULL},
+    {"__CFPREFERENCES_AVOID_DAEMON", NULL},
     {NULL, NULL}, // the last one is for optional "COMMAND_MODE" "legacy", do not use this slot, insert before
 };
 
@@ -944,7 +955,7 @@ void __CFInitialize(void) {
     if (!__CFInitialized && !__CFInitializing) {
         __CFInitializing = 1;
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#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
 #endif
 
@@ -959,10 +970,10 @@ void __CFInitialize(void) {
         
         __CFProphylacticAutofsAccess = true;
 
-       for (CFIndex idx = 0; idx < sizeof(__CFEnv) / sizeof(__CFEnv[0]); idx++) {
-           __CFEnv[idx].value = __CFEnv[idx].name ? getenv(__CFEnv[idx].name) : NULL;
-       }
-
+        for (CFIndex idx = 0; idx < sizeof(__CFEnv) / sizeof(__CFEnv[0]); idx++) {
+            __CFEnv[idx].value = __CFEnv[idx].name ? getenv(__CFEnv[idx].name) : NULL;
+        }
+        
 #if !defined(kCFUseCollectableAllocator)
         kCFUseCollectableAllocator = objc_collectingEnabled();
 #endif
@@ -971,19 +982,12 @@ void __CFInitialize(void) {
             __CFObjCIsCollectable = (bool (*)(void *))objc_isAuto;
 #endif
         }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        UInt32 s, r;
        __CFStringGetUserDefaultEncoding(&s, &r); // force the potential setenv to occur early
        pthread_atfork(__01121__, NULL, __01123__);
 #endif
 
-#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
-       const char *value = __CFgetenv("NSZombieEnabled");
-       if (value && (*value == 'Y' || *value == 'y')) __CFZombieEnabled = 0xff;
-       value = __CFgetenv("NSDeallocateZombies");
-       if (value && (*value == 'Y' || *value == 'y')) __CFDeallocateZombies = 0xff;
-
-#endif
 
         memset(__CFRuntimeClassTable, 0, sizeof(__CFRuntimeClassTable));
         memset(__CFRuntimeObjCClassTable, 0, sizeof(__CFRuntimeObjCClassTable));
@@ -1047,39 +1051,44 @@ void __CFInitialize(void) {
         
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
         __CFBundleInitialize();
+        __CFPFactoryInitialize();
 #endif
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         __CFPlugInInitialize();
         __CFPlugInInstanceInitialize();
 #endif
         __CFUUIDInitialize();
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
        __CFMessagePortInitialize();
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         __CFMachPortInitialize();
 #endif
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
         __CFStreamInitialize();
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
+        __CFWindowsNamedPipeInitialize();
+#endif
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
         __CFRunLoopInitialize();
         __CFRunLoopObserverInitialize();
         __CFRunLoopSourceInitialize();
         __CFRunLoopTimerInitialize();
 #endif
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         __CFTimeZoneInitialize();
         __CFCalendarInitialize();
 #if DEPLOYMENT_TARGET_LINUX
         __CFTimeZoneInitialize();
         __CFCalendarInitialize();
 #endif
-        
+#endif
 
         {
             CFIndex idx, cnt;
             char **args;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             args = *_NSGetArgv();
             cnt = *_NSGetArgc();
 #elif DEPLOYMENT_TARGET_WINDOWS
@@ -1117,14 +1126,19 @@ void __CFInitialize(void) {
 
         _CFProcessPath();      // cache this early
 
-
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         __CFOAInitialize();
-#endif
+        
 
         if (__CFRuntimeClassTableCount < 256) __CFRuntimeClassTableCount = 256;
 
 
+#if defined(DEBUG) || defined(ENABLE_ZOMBIES)
+        const char *value = __CFgetenv("NSZombieEnabled");
+        if (value && (*value == 'Y' || *value == 'y')) _CFEnableZombies();
+        value = __CFgetenv("NSDeallocateZombies");
+        if (value && (*value == 'Y' || *value == 'y')) __CFDeallocateZombies = 0xff;
+#endif
+
 #if defined(DEBUG) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
         CFLog(kCFLogLevelWarning, CFSTR("Assertions enabled"));
 #endif
@@ -1138,6 +1152,11 @@ 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);
+
 static CFBundleRef RegisterCoreFoundationBundle(void) {
 #ifdef _DEBUG
     // might be nice to get this from the project file at some point
@@ -1223,7 +1242,7 @@ int DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved ) {
 #define RC_DEALLOCATING_BIT    (0x400000ULL)
 #endif
 
-#if COCOA_ARR1 && __LP64__
+#if !DEPLOYMENT_TARGET_WINDOWS && __LP64__
 static bool (*CAS64)(int64_t, int64_t, volatile int64_t *) = OSAtomicCompareAndSwap64Barrier;
 #else
 static bool (*CAS32)(int32_t, int32_t, volatile int32_t *) = OSAtomicCompareAndSwap32Barrier;
@@ -1252,7 +1271,7 @@ static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR) {
     Boolean didAuto = false;
 #if __LP64__
     if (0 == ((CFRuntimeBase *)cf)->_rc && !CF_IS_COLLECTABLE(cf)) return cf;  // Constant CFTypeRef
-#if COCOA_ARR1
+#if !DEPLOYMENT_TARGET_WINDOWS
     uint64_t allBits;
     do {
         allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo);
@@ -1283,7 +1302,7 @@ static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR) {
     bool success = 0;
     do {
         cfinfo = *infoLocation;
-#if COCOA_ARR1
+#if !DEPLOYMENT_TARGET_WINDOWS
         // if already deallocating, don't allow new retain
         if (tryR && (cfinfo & 0x400000)) return NULL;
 #endif
@@ -1326,11 +1345,13 @@ 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
     return _CFRetain(cf, true);
 }
 
 Boolean _CFIsDeallocating(CFTypeRef cf) {
     if (NULL == cf) return false;
+    if (CF_IS_TAGGED_OBJ(cf)) return false;
     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
@@ -1357,10 +1378,11 @@ static void _CFRelease(CFTypeRef cf) {
         return;
     }
 
+    CFIndex start_rc = __builtin_expect(__CFOASafe, 0) ? CFGetRetainCount(cf) : 0;
     Boolean isAllocator = (__kCFAllocatorTypeID_CONST == typeID);
     Boolean didAuto = false;
 #if __LP64__
-#if COCOA_ARR1
+#if !DEPLOYMENT_TARGET_WINDOWS
     uint32_t lowBits;
     uint64_t allBits;
     again:;
@@ -1438,7 +1460,7 @@ static void _CFRelease(CFTypeRef cf) {
     }
 #endif
 #else
-#if COCOA_ARR1
+#if !DEPLOYMENT_TARGET_WINDOWS
     again:;
     volatile uint32_t *infoLocation = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo);
     CFIndex rcLowBits = __CFBitfieldGetValue(cfinfo, RC_END, RC_START);
@@ -1586,7 +1608,7 @@ static void _CFRelease(CFTypeRef cf) {
 #endif
 #endif
     if (!didAuto && __builtin_expect(__CFOASafe, 0)) {
-       __CFRecordAllocationEvent(__kCFReleaseEvent, (void *)cf, 0, CFGetRetainCount(cf), NULL);
+       __CFRecordAllocationEvent(__kCFReleaseEvent, (void *)cf, 0, start_rc - 1, NULL);
     }
     return;
 
index a1cd9d5b47ea662ef1e8febc44477205dcdc94df..4ee6137c3d0ed3a130319d76c645599ed76f4576 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFRuntime.h
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFRUNTIME__)
diff --git a/CFSet.c b/CFSet.c
index 71273fdce714e5ececdc261b3e0b2043819b9c9d..775b4e8b9861adb72ecf6700ae9fd4750ab2ef4d 100644 (file)
--- a/CFSet.c
+++ b/CFSet.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFSet.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
        Machine generated from Notes/HashingCode.template
 */
@@ -36,6 +36,7 @@
 #include "CFBasicHash.h"
 #include <CoreFoundation/CFString.h>
 
+
 #define CFDictionary 0
 #define CFSet 0
 #define CFBag 0
@@ -217,7 +218,7 @@ static CFBasicHashCallbacks *__CFSetCopyCallbacks(CFConstBasicHashRef ht, CFAllo
     } else {
         newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
     }
-    if (!newcb) HALT;
+    if (!newcb) return NULL;
     memmove(newcb, (void *)cb, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *));
     return newcb;
 }
@@ -386,7 +387,7 @@ static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHas
         } else {
             newcb = (CFBasicHashCallbacks *)CFAllocatorAllocate(allocator, sizeof(CFBasicHashCallbacks) + 10 * sizeof(void *), 0);
         }
-        if (!newcb) HALT;
+        if (!newcb) return NULL;
         newcb->copyCallbacks = __CFSetCopyCallbacks;
         newcb->freeCallbacks = __CFSetFreeCallbacks;
         newcb->retainValue = __CFSetRetainValue;
@@ -427,7 +428,8 @@ static CFBasicHashRef __CFSetCreateGeneric(CFAllocatorRef allocator, const CFHas
     }
 
     CFBasicHashRef ht = CFBasicHashCreate(allocator, flags, cb);
-    CFBasicHashSetSpecialBits(ht, specialBits);
+    if (ht) CFBasicHashSetSpecialBits(ht, specialBits);
+    if (!ht && !CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, cb);
     return ht;
 }
 
@@ -468,6 +470,7 @@ CFHashRef CFSetCreate(CFAllocatorRef allocator, const_any_pointer_t *klist, CFIn
     CFTypeID typeID = CFSetGetTypeID();
     CFAssert2(0 <= numValues, __kCFLogAssertion, "%s(): numValues (%ld) cannot be less than zero", __PRETTY_FUNCTION__, numValues);
     CFBasicHashRef ht = __CFSetCreateGeneric(allocator, keyCallBacks, valueCallBacks, CFDictionary);
+    if (!ht) return NULL;
     if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
     for (CFIndex idx = 0; idx < numValues; idx++) {
         CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
@@ -489,6 +492,7 @@ CFMutableHashRef CFSetCreateMutable(CFAllocatorRef allocator, CFIndex capacity,
     CFTypeID typeID = CFSetGetTypeID();
     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);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
@@ -513,8 +517,8 @@ CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -522,6 +526,7 @@ CFHashRef CFSetCreateCopy(CFAllocatorRef allocator, CFHashRef other) {
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     CFBasicHashMakeImmutable(ht);
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
@@ -548,8 +553,8 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
         CFDictionaryGetKeysAndValues(other, klist, vlist);
 #endif
         ht = __CFSetCreateGeneric(allocator, & kCFTypeSetKeyCallBacks, CFDictionary ? & kCFTypeSetValueCallBacks : NULL, CFDictionary);
-        if (0 < numValues) CFBasicHashSetCapacity(ht, numValues);
-        for (CFIndex idx = 0; idx < numValues; idx++) {
+        if (ht && 0 < numValues) CFBasicHashSetCapacity(ht, numValues);
+        for (CFIndex idx = 0; ht && idx < numValues; idx++) {
             CFBasicHashAddValue(ht, (uintptr_t)klist[idx], (uintptr_t)vlist[idx]);
         }
         if (klist != kbuffer && klist != vlist) CFAllocatorDeallocate(kCFAllocatorSystemDefault, klist);
@@ -557,6 +562,7 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
     } else {
         ht = CFBasicHashCreateCopy(allocator, (CFBasicHashRef)other);
     }
+    if (!ht) return NULL;
     *(uintptr_t *)ht = __CFISAForTypeID(typeID);
     _CFRuntimeSetInstanceTypeID(ht, typeID);
     if (__CFOASafe) __CFSetLastAllocationEventName(ht, "CFSet (mutable)");
@@ -564,8 +570,8 @@ CFMutableHashRef CFSetCreateMutableCopy(CFAllocatorRef allocator, CFIndex capaci
 }
 
 CFIndex CFSetGetCount(CFHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFSetTypeID, CFIndex, hc, "count");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFSetTypeID, CFIndex, hc, "count");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, count);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSSet *)hc, count);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     return CFBasicHashGetCount((CFBasicHashRef)hc);
 }
@@ -576,8 +582,8 @@ CFIndex CFSetGetCountOfKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 CFIndex CFSetGetCountOfValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, CFIndex, hc, "countForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, CFIndex, hc, "countForObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, countForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSSet *)hc, countForObject:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     return CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key);
 }
@@ -588,23 +594,23 @@ Boolean CFSetContainsKey(CFHashRef hc, const_any_pointer_t key) {
 #if CFSet || CFBag
 Boolean CFSetContainsValue(CFHashRef hc, const_any_pointer_t key) {
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, char, hc, "containsKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, char, hc, "containsObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSDictionary *)hc, containsKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSSet *)hc, containsObject:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     return (0 < CFBasicHashGetCountOfKey((CFBasicHashRef)hc, (uintptr_t)key));
 }
 
 const_any_pointer_t CFSetGetValue(CFHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, const_any_pointer_t, hc, "objectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, const_any_pointer_t, hc, "member:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, const_any_pointer_t, (NSDictionary *)hc, objectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, const_any_pointer_t, (NSSet *)hc, member:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     return (0 < bkt.count ? (const_any_pointer_t)bkt.weak_value : 0);
 }
 
 Boolean CFSetGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *value) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "__getValue:forKey:", (any_t *)value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "__getValue:forObj:", (any_t *)value, key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, Boolean, (NSDictionary *)hc, __getValue:(id *)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, Boolean, (NSSet *)hc, __getValue:(id *)value forObj:(id)key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -622,19 +628,18 @@ Boolean CFSetGetValueIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_
 
 #if CFDictionary
 CFIndex CFDictionaryGetCountOfValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, CFIndex, hc, "countForObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, CFIndex, (NSDictionary *)hc, countForObject:(id)value);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     return CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value);
 }
 
 Boolean CFDictionaryContainsValue(CFHashRef hc, const_any_pointer_t value) {
-    CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, char, hc, "containsObject:", value);
+    CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, char, (NSDictionary *)hc, containsObject:(id)value);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     return (0 < CFBasicHashGetCountOfValue((CFBasicHashRef)hc, (uintptr_t)value));
 }
 
 CF_EXPORT Boolean CFDictionaryGetKeyIfPresent(CFHashRef hc, const_any_pointer_t key, const_any_pointer_t *actualkey) {
-    CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, Boolean, hc, "getActualKey:forKey:", actualkey, key);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFBasicHashBucket bkt = CFBasicHashFindBucket((CFBasicHashRef)hc, (uintptr_t)key);
     if (0 < bkt.count) {
@@ -658,8 +663,8 @@ void CFSetGetKeysAndValues(CFHashRef hc, const_any_pointer_t *keybuf, const_any_
 void CFSetGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
     const_any_pointer_t *valuebuf = 0;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "getObjects:andKeys:", (any_t *)valuebuf, (any_t *)keybuf);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "getObjects:", (any_t *)keybuf);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, getObjects:(id *)keybuf);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     if (kCFUseCollectableAllocator) {
         CFOptionFlags flags = CFBasicHashGetFlags((CFBasicHashRef)hc);
@@ -681,8 +686,8 @@ void CFSetGetValues(CFHashRef hc, const_any_pointer_t *keybuf) {
 
 void CFSetApplyFunction(CFHashRef hc, CFSetApplierFunction applier, any_pointer_t context) {
     FAULT_CALLBACK((void **)&(applier));
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "__apply:context:", applier, context);
-    if (CFSet) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "__applyValues:context:", applier, context);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSDictionary *)hc, __apply:(void (*)(const void *, const void *, void *))applier context:(void *)context);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSSet *)hc, __applyValues:(void (*)(const void *, void *))applier context:(void *)context);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFBasicHashApply((CFBasicHashRef)hc, ^(CFBasicHashBucket bkt) {
 #if CFDictionary
@@ -756,8 +761,8 @@ void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_point
 void CFSetAddValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "addObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "addObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, __addObject:(id)value forKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, addObject:(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)) {
@@ -775,8 +780,8 @@ void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key, const_any_p
 void CFSetReplaceValue(CFMutableHashRef hc, const_any_pointer_t key) {
     const_any_pointer_t value = key;
 #endif
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "replaceObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "replaceObject:", key);
+    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);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -794,8 +799,8 @@ 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_FUNCDISPATCH2(__kCFSetTypeID, void, hc, "setObject:forKey:", value, key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "setObject:", 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);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
@@ -808,8 +813,8 @@ void CFSetSetValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFSetRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "removeObjectForKey:", key);
-    if (CFSet) CF_OBJC_FUNCDISPATCH1(__kCFSetTypeID, void, hc, "removeObject:", key);
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, removeObjectForKey:(id)key);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, removeObject:(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)) {
@@ -821,8 +826,8 @@ void CFSetRemoveValue(CFMutableHashRef hc, const_any_pointer_t key) {
 }
 
 void CFSetRemoveAllValues(CFMutableHashRef hc) {
-    if (CFDictionary) CF_OBJC_FUNCDISPATCH0(__kCFSetTypeID, void, hc, "removeAllObjects");
-    if (CFSet) CF_OBJC_FUNCDISPATCH0(__kCFSetTypeID, void, hc, "removeAllObjects");
+    if (CFDictionary) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableDictionary *)hc, removeAllObjects);
+    if (CFSet) CF_OBJC_FUNCDISPATCHV(__kCFSetTypeID, void, (NSMutableSet *)hc, removeAllObjects);
     __CFGenericValidateType(hc, __kCFSetTypeID);
     CFAssert2(CFBasicHashIsMutable((CFBasicHashRef)hc), __kCFLogAssertion, "%s(): immutable collection %p passed to mutating operation", __PRETTY_FUNCTION__, hc);
     if (!CFBasicHashIsMutable((CFBasicHashRef)hc)) {
diff --git a/CFSet.h b/CFSet.h
index 44487372a2f424eddf774e400859f2a81f0331b5..0ee1ce86c8ebac383227355506b681bf3b89379b 100644 (file)
--- a/CFSet.h
+++ b/CFSet.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFSet.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 /*!
         @header CFSet
@@ -34,6 +34,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -502,6 +503,7 @@ CF_EXPORT
 void CFSetRemoveAllValues(CFMutableSetRef theSet);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFSET__ */
 
index 819fdc9ef790da91a661b3569b0ae7e537c1e99a..f07069a2411eb8efac2b4cedf19f0c7669ef9d35 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocket.c
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -34,6 +34,7 @@
 #include <CoreFoundation/CFSocket.h>
 #include "CFInternal.h"
 #include <dispatch/dispatch.h>
+#include <dispatch/private.h>
 #include <netinet/in.h>
 #include <sys/sysctl.h>
 #include <sys/socket.h>
@@ -953,7 +954,7 @@ Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable) {
 #include <sys/types.h>
 #include <math.h>
 #include <limits.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <sys/sysctl.h>
 #include <sys/un.h>
 #include <libc.h>
@@ -981,11 +982,8 @@ Boolean __CFSocketGetBytesAvailable(CFSocketRef s, CFIndex* ctBytesAvailable) {
 typedef int32_t fd_mask;
 typedef int socklen_t;
 
-// not entirely correct, but good enough for what it's used for here
-void gettimeofday(struct timeval *tp, void *tzp) {
-    tp->tv_sec = 0;
-    tp->tv_usec = 0;
-}
+#define gettimeofday _NS_gettimeofday
+__private_extern__ 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) \
@@ -1007,7 +1005,7 @@ void gettimeofday(struct timeval *tp, void *tzp) {
 
 //#define LOG_CFSOCKET
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define INVALID_SOCKET (CFSocketNativeHandle)(-1)
 #define closesocket(a) close((a))
 #define ioctlsocket(a,b,c) ioctl((a),(b),(c))
@@ -1226,7 +1224,7 @@ CF_INLINE Boolean __CFSocketFdClr(CFSocketNativeHandle sock, CFMutableDataRef fd
 }
 
 static SInt32 __CFSocketCreateWakeupSocketPair(void) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     SInt32 error;
 
     error = socketpair(PF_LOCAL, SOCK_DGRAM, 0, __CFWakeupSocketPair);
@@ -2166,7 +2164,7 @@ static CFStringRef __CFSocketCopyDescription(CFTypeRef cf) {
     result = CFStringCreateMutable(CFGetAllocator(s), 0);
     __CFSocketLock(s);
     void *addr = s->_callout;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     Dl_info info;
     const char *name = (dladdr(addr, &info) && info.dli_saddr == addr && info.dli_sname) ? info.dli_sname : "???";
 #else
@@ -2229,7 +2227,7 @@ static const CFRuntimeClass __CFSocketClass = {
 CFTypeID CFSocketGetTypeID(void) {
     if (_kCFRuntimeNotATypeID == __kCFSocketTypeID) {
        __kCFSocketTypeID = _CFRuntimeRegisterClass(&__CFSocketClass);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         struct rlimit lim1;
         int ret1 = getrlimit(RLIMIT_NOFILE, &lim1);
         int mib[] = {CTL_KERN, KERN_MAXFILESPERPROC};
@@ -2389,10 +2387,11 @@ void CFSocketInvalidate(CFSocketRef s) {
             s->_addressQueue = NULL;
         }
         s->_socketSetCount = 0;
-        for (idx = CFArrayGetCount(s->_runLoops); idx--;) {
-            CFRunLoopWakeUp((CFRunLoopRef)CFArrayGetValueAtIndex(s->_runLoops, idx));
-        }
+        
+        // we'll need this later
+        CFArrayRef runLoops = (CFArrayRef)CFRetain(s->_runLoops);        
         CFRelease(s->_runLoops);
+        
         s->_runLoops = NULL;
         source0 = s->_source0;
         s->_source0 = NULL;
@@ -2403,6 +2402,13 @@ void CFSocketInvalidate(CFSocketRef s) {
         s->_context.release = 0;
         s->_context.copyDescription = 0;
         __CFSocketUnlock(s);
+        
+        // Do this after the socket unlock to avoid deadlock (10462525)
+        for (idx = CFArrayGetCount(runLoops); idx--;) {
+            CFRunLoopWakeUp((CFRunLoopRef)CFArrayGetValueAtIndex(runLoops, idx));
+        }
+        CFRelease(runLoops);
+
         if (NULL != contextRelease) {
             contextRelease(contextInfo);
         }
@@ -2947,7 +2953,7 @@ CFSocketError CFSocketSetAddress(CFSocketRef s, CFDataRef address) {
     if (!name || namelen <= 0) return kCFSocketError;
     
     CFSocketNativeHandle sock = CFSocketGetNative(s);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     // Verify that the namelen is correct. If not, we have to fix it up. Developers will often incorrectly use 0 or strlen(path). See 9217961 and the second half of 9098274.
     // Max size is a size byte, plus family byte, plus path of 255, plus a null byte.
     char newName[255];
@@ -2992,7 +2998,7 @@ CFSocketError CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeI
     if (!name || namelen <= 0) return kCFSocketError;
     CFSocketNativeHandle sock = CFSocketGetNative(s);
     {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
         SInt32 flags = fcntl(sock, F_GETFL, 0);
         if (flags >= 0) wasBlocking = ((flags & O_NONBLOCK) == 0);
         if (wasBlocking && (timeout > 0.0 || timeout < 0.0)) ioctlsocket(sock, FIONBIO, (u_long *)&yes);
@@ -3060,7 +3066,7 @@ CFSocketRef CFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt
         if (0 >= protocol && SOCK_STREAM == socketType) protocol = IPPROTO_TCP;
         if (0 >= protocol && SOCK_DGRAM == socketType) protocol = IPPROTO_UDP;
     }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     if (PF_LOCAL == protocolFamily && 0 >= socketType) socketType = SOCK_STREAM;
 #endif
 #if DEPLOYMENT_TARGET_WINDOWS
@@ -3147,7 +3153,7 @@ static void __CFSocketSendNameRegistryRequest(CFSocketSignature *signature, CFDi
 static void __CFSocketValidateSignature(const CFSocketSignature *providedSignature, CFSocketSignature *signature, uint16_t defaultPortNumber) {
     struct sockaddr_in sain, *sainp;
     memset(&sain, 0, sizeof(sain));
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     sain.sin_len = sizeof(sain);
 #endif
     sain.sin_family = AF_INET;
@@ -3173,7 +3179,7 @@ static void __CFSocketValidateSignature(const CFSocketSignature *providedSignatu
         } else {
             sainp = (struct sockaddr_in *)CFDataGetBytePtr(providedSignature->address);
             if ((int)sizeof(struct sockaddr_in) <= CFDataGetLength(providedSignature->address) && (AF_INET == sainp->sin_family || 0 == sainp->sin_family)) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
                 sain.sin_len = sizeof(sain);
 #endif
                 sain.sin_family = AF_INET;
index b082d4fb6901baaf3eb20d4b037740729a4f849b..80ddad92232adb088e790fe50cddc471e8c2c5d8 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocket.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSOCKET__)
@@ -113,12 +113,11 @@ filled in properly when passing in an address.
 */
 
 /* Values for CFSocketError */
-enum {
+typedef CF_ENUM(CFIndex, CFSocketError) {
     kCFSocketSuccess = 0,
-    kCFSocketError = -1,
-    kCFSocketTimeout = -2
+    kCFSocketError = -1L,
+    kCFSocketTimeout = -2L
 };
-typedef CFIndex CFSocketError;
 
 typedef struct {
     SInt32     protocolFamily;
@@ -128,7 +127,7 @@ typedef struct {
 } CFSocketSignature;
 
 /* Values for CFSocketCallBackType */
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFSocketCallBackType) {
     kCFSocketNoCallBack = 0,
     kCFSocketReadCallBack = 1,
     kCFSocketAcceptCallBack = 2,
@@ -136,7 +135,6 @@ enum {
     kCFSocketConnectCallBack = 4,
     kCFSocketWriteCallBack = 8
 };
-typedef CFOptionFlags CFSocketCallBackType;
 
 /* Socket flags */
 enum {
@@ -144,9 +142,7 @@ enum {
     kCFSocketAutomaticallyReenableAcceptCallBack = 2,
     kCFSocketAutomaticallyReenableDataCallBack = 3,
     kCFSocketAutomaticallyReenableWriteCallBack = 8,
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    kCFSocketLeaveErrors = 64,
-#endif
+    kCFSocketLeaveErrors CF_ENUM_AVAILABLE(10_5, 2_0) = 64,
     kCFSocketCloseOnInvalidate = 128
 };
 
@@ -172,8 +168,9 @@ CF_EXPORT CFTypeID  CFSocketGetTypeID(void);
 CF_EXPORT CFSocketRef  CFSocketCreate(CFAllocatorRef allocator, SInt32 protocolFamily, SInt32 socketType, SInt32 protocol, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
 CF_EXPORT CFSocketRef  CFSocketCreateWithNative(CFAllocatorRef allocator, CFSocketNativeHandle sock, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
 CF_EXPORT CFSocketRef  CFSocketCreateWithSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context);
+/* CFSocketCreateWithSocketSignature() creates a socket of the requested type and binds its address (using CFSocketSetAddress()) to the requested address.  If this fails, it returns NULL. */
 CF_EXPORT CFSocketRef  CFSocketCreateConnectedToSocketSignature(CFAllocatorRef allocator, const CFSocketSignature *signature, CFOptionFlags callBackTypes, CFSocketCallBack callout, const CFSocketContext *context, CFTimeInterval timeout);
-/* CFSocketCreateWithSignature creates a socket of the requested type and binds its address (using CFSocketSetAddress) to the requested address.  If this fails, it returns NULL.  CFSocketCreateConnectedToSignature creates a socket suitable for connecting to the requested type and address, and connects it (using CFSocketConnectToAddress).  If this fails, it returns NULL. */
+/* CFSocketCreateConnectedToSocketSignature() creates a socket suitable for connecting to the requested type and address, and connects it (using CFSocketConnectToAddress()).  If this fails, it returns NULL. */
 
 CF_EXPORT CFSocketError        CFSocketSetAddress(CFSocketRef s, CFDataRef address);
 CF_EXPORT CFSocketError        CFSocketConnectToAddress(CFSocketRef s, CFDataRef address, CFTimeInterval timeout);
index 0124c81f2704c2e03a010bef4c1ebd6b04db7787..bb9ca57adcc8f430de5ab8317c129aa0a07b0db1 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFSocketStream.c
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
        Responsibility: Jeremy Wyld
 */
 //     Original Author: Becky Willrich
@@ -60,11 +60,8 @@ CONST_STRING_DECL(kCFStreamSocketSecurityLevelNegotiatedSSL, "kCFStreamSocketSec
 #endif
 
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
 typedef void (*CF_SOCKET_STREAM_PAIR)(CFAllocatorRef, CFStringRef, UInt32, CFSocketNativeHandle, const CFSocketSignature*, CFReadStreamRef*, CFWriteStreamRef*);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
 // These are duplicated in CFNetwork, who actually externs them in its headers
@@ -106,11 +103,8 @@ enum {
 static struct {
     CFSpinLock_t lock;
     UInt32     flags;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
     HMODULE    image;
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     void (*_CFSocketStreamCreatePair)(CFAllocatorRef, CFStringRef, UInt32, CFSocketNativeHandle, const CFSocketSignature*, CFReadStreamRef*, CFWriteStreamRef*);
     CFErrorRef (*_CFErrorCreateWithStreamError)(CFAllocatorRef, CFStreamError*);
@@ -118,11 +112,8 @@ static struct {
 } CFNetworkSupport = {
     CFSpinLockInit,
     0x0,
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
     NULL,
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     NULL,
     NULL,
@@ -135,8 +126,6 @@ static struct {
 #define CFNETWORK_LOAD_SYM(sym)   __CFLookupCFNetworkFunction(#sym)
 #elif DEPLOYMENT_TARGET_WINDOWS
 #define CFNETWORK_LOAD_SYM(sym)   (void *)GetProcAddress(CFNetworkSupport.image, #sym)
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
 static void initializeCFNetworkSupport(void) {
@@ -176,8 +165,6 @@ static void initializeCFNetworkSupport(void) {
         CFNetworkSupport._CFErrorCreateWithStreamError = (CFErrorRef(*)(CFAllocatorRef, CFStreamError *))CFNETWORK_LOAD_SYM(_CFErrorCreateWithStreamError);
         CFNetworkSupport._CFStreamErrorFromCFError = (CFStreamError(*)(CFErrorRef))CFNETWORK_LOAD_SYM(_CFStreamErrorFromCFError);
     }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
     if (!CFNetworkSupport._CFSocketStreamCreatePair) CFLog(__kCFLogAssertion, CFSTR("CoreFoundation: failed to dynamically link symbol _CFSocketStreamCreatePair"));
index 44ac7339916cb04259424b7693eda7312293e87a..40cdc9425c13cf13cbb72b77ac314fac146975ce 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFSortFunctions.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -31,6 +31,9 @@
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
 #include <dispatch/dispatch.h>
 #endif
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#include <dispatch/private.h>
+#endif
 
 enum {
     kCFSortConcurrent = (1 << 0),
index 380f9220cca5069ef75d408a6de67e451649264c..22652dd4553593e5464aa2cd1e78e74611d662ac 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStorage.c
- Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+ Copyright (c) 1999-2012, Apple Inc. All rights reserved.
  Responsibility: Ali Ozer
  */
 
@@ -162,7 +162,7 @@ CF_INLINE void __CFStorageAllocLeafNodeMemory(CFAllocatorRef allocator, CFStorag
 }
 
 #if 0
-#define ASSERT(x) do { if (! (x)) { fprintf(stderr, "Assertion %s failed on line %d\n", #x, __LINE__); abort(); } } while (0)
+#define ASSERT(x) do { if (! (x)) { fprintf(stderr, "Assertion %s failed on line %d\n", #x, __LINE__); HALT; } } while (0)
 #else
 #define ASSERT(x) do { if (0 && ! (x)) { } } while(0)
 #endif
index 75999c9e478fb0a8dbfee9e27e3ec56e2d4e83ff..7431f0b6d357ad17a4218817a7bb8c8d3868e609 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStorage.h
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
 */
 /*!
         @header CFStorage
@@ -52,10 +52,9 @@ storage was a single block.
 
 #include <CoreFoundation/CFBase.h>
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFStorageEnumerationOptionFlags) {
         kCFStorageEnumerationConcurrent = (1UL << 0) /* Allow enumeration to proceed concurrently */
 };
-typedef CFOptionFlags CFStorageEnumerationOptionFlags;
 
 CF_EXTERN_C_BEGIN
 
index 81c9ce256ca3019003f658c5c3dbfd4469e19efc..b4c52fd9cb19f0212a6825133095da5aaf3a106d 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStream.c
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
@@ -37,6 +37,7 @@
 #include <assert.h>
 #endif
 
+
 struct CFStreamAux {
        CFSpinLock_t streamLock;
     CFArrayRef previousRunloopsAndModes;
@@ -720,7 +721,7 @@ static void _wakeUpRunLoop(struct _CFStream *stream) {
     CFArrayRef rlArray = _CFStreamCopyRunLoopsAndModes(stream);
     if (rlArray) {
         CFIndex cnt = CFArrayGetCount(rlArray);
-        CFRunLoopRef rl;
+        CFRunLoopRef rl = NULL;
 
         if (cnt == 2) {
             rl = (CFRunLoopRef)CFArrayGetValueAtIndex(rlArray, 0);
@@ -749,8 +750,8 @@ static void _wakeUpRunLoop(struct _CFStream *stream) {
         }
         if (NULL != rl && CFRunLoopIsWaiting(rl)) 
             CFRunLoopWakeUp(rl);
+        CFRelease(rlArray);
     }
-    CFRelease(rlArray);
 }
 
 __private_extern__ void _CFStreamSignalEvent(struct _CFStream *stream, CFStreamEventType event, CFErrorRef error, Boolean synchronousAllowed) {
@@ -865,12 +866,12 @@ __private_extern__ CFStreamStatus _CFStreamGetStatus(struct _CFStream *stream) {
 }
 
 CF_EXPORT CFStreamStatus CFReadStreamGetStatus(CFReadStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFReadStreamTypeID, CFStreamStatus, stream, "streamStatus");
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, CFStreamStatus, (NSInputStream *)stream, streamStatus);
     return _CFStreamGetStatus((struct _CFStream *)stream);
 }
 
 CF_EXPORT CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFWriteStreamTypeID, CFStreamStatus, stream, "streamStatus");
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFStreamStatus, (NSOutputStream *)stream, streamStatus);
     return _CFStreamGetStatus((struct _CFStream *)stream);
 }
 
@@ -890,12 +891,12 @@ static CFStreamError _CFStreamGetStreamError(struct _CFStream *stream) {
 }
 
 CF_EXPORT CFStreamError CFReadStreamGetError(CFReadStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFReadStreamTypeID, CFStreamError, stream, "_cfStreamError");
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, CFStreamError, (NSInputStream *)stream, _cfStreamError);
     return _CFStreamGetStreamError((struct _CFStream *)stream);
 }
 
 CF_EXPORT CFStreamError CFWriteStreamGetError(CFWriteStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFWriteStreamTypeID, CFStreamError, stream, "_cfStreamError");
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFStreamError, (NSOutputStream *)stream, _cfStreamError);
     return _CFStreamGetStreamError((struct _CFStream *)stream);
 }
 
@@ -911,13 +912,13 @@ static CFErrorRef _CFStreamCopyError(struct _CFStream *stream) {
 }
 
 CF_EXPORT CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFReadStreamTypeID, CFErrorRef, stream, "streamError");
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, CFErrorRef, (NSInputStream *)stream, streamError);
     return _CFStreamCopyError((struct _CFStream *)stream);
 }
 
 CF_EXPORT CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) {
     return _CFStreamCopyError((struct _CFStream *)stream);
-    CF_OBJC_FUNCDISPATCH0(__kCFWriteStreamTypeID, CFErrorRef, stream, "streamError");
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFErrorRef, (NSOutputStream *)stream, streamError);
 }
 
 __private_extern__ Boolean _CFStreamOpen(struct _CFStream *stream) {
@@ -961,7 +962,7 @@ __private_extern__ Boolean _CFStreamOpen(struct _CFStream *stream) {
 
 CF_EXPORT Boolean CFReadStreamOpen(CFReadStreamRef stream) {
     if(CF_IS_OBJC(__kCFReadStreamTypeID, stream)) {
-        CF_OBJC_VOIDCALL0(stream, "open");
+        (void)CF_OBJC_CALLV((NSInputStream *)stream, open);
         return TRUE;
     }
     return _CFStreamOpen((struct _CFStream *)stream);
@@ -969,24 +970,24 @@ CF_EXPORT Boolean CFReadStreamOpen(CFReadStreamRef stream) {
 
 CF_EXPORT Boolean CFWriteStreamOpen(CFWriteStreamRef stream) {
     if(CF_IS_OBJC(__kCFWriteStreamTypeID, stream)) {
-        CF_OBJC_VOIDCALL0(stream, "open");
+        (void)CF_OBJC_CALLV((NSOutputStream *)stream, open);
         return TRUE;
     }
     return _CFStreamOpen((struct _CFStream *)stream);
 }
 
 CF_EXPORT void CFReadStreamClose(CFReadStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFReadStreamTypeID, void, stream, "close");
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, void, (NSInputStream *)stream, close);
     _CFStreamClose((struct _CFStream *)stream);
 }
 
 CF_EXPORT void CFWriteStreamClose(CFWriteStreamRef stream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFWriteStreamTypeID, void, stream, "close");
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, void, (NSOutputStream *)stream, close);
     _CFStreamClose((struct _CFStream *)stream);
 }
 
 CF_EXPORT Boolean CFReadStreamHasBytesAvailable(CFReadStreamRef readStream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFReadStreamTypeID, Boolean, readStream, "hasBytesAvailable");
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, Boolean, (NSInputStream *)readStream, hasBytesAvailable);
     struct _CFStream *stream = (struct _CFStream *)readStream;
     CFStreamStatus status = _CFStreamGetStatus(stream);
     const struct _CFStreamCallBacks *cb;
@@ -1015,7 +1016,7 @@ CF_EXPORT Boolean CFReadStreamHasBytesAvailable(CFReadStreamRef readStream) {
 
 static void waitForOpen(struct _CFStream *stream);
 CFIndex CFReadStreamRead(CFReadStreamRef readStream, UInt8 *buffer, CFIndex bufferLength) {
-    CF_OBJC_FUNCDISPATCH2(__kCFReadStreamTypeID, CFIndex, readStream, "read:maxLength:", buffer, bufferLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, CFIndex, (NSInputStream *)readStream, read:(uint8_t *)buffer maxLength:(NSUInteger)bufferLength);
     struct _CFStream *stream = (struct _CFStream *)readStream;
     CFStreamStatus status = _CFStreamGetStatus(stream);
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
@@ -1063,8 +1064,7 @@ CFIndex CFReadStreamRead(CFReadStreamRef readStream, UInt8 *buffer, CFIndex buff
 CF_EXPORT const UInt8 *CFReadStreamGetBuffer(CFReadStreamRef readStream, CFIndex maxBytesToRead, CFIndex *numBytesRead) {
     if (CF_IS_OBJC(__kCFReadStreamTypeID, readStream)) {
         uint8_t *bufPtr = NULL;
-        Boolean gotBytes;
-        CF_OBJC_CALL2(Boolean, gotBytes, readStream, "getBuffer:length:", &bufPtr, numBytesRead); 
+        Boolean gotBytes = (Boolean) CF_OBJC_CALLV((NSInputStream *)readStream, getBuffer:&bufPtr length:(NSUInteger *)numBytesRead);
         if(gotBytes) {
             return (const UInt8 *)bufPtr;
         } else {
@@ -1122,7 +1122,7 @@ CF_EXPORT const UInt8 *CFReadStreamGetBuffer(CFReadStreamRef readStream, CFIndex
 }
 
 CF_EXPORT Boolean CFWriteStreamCanAcceptBytes(CFWriteStreamRef writeStream) {
-    CF_OBJC_FUNCDISPATCH0(__kCFWriteStreamTypeID, Boolean, writeStream, "hasSpaceAvailable");
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, Boolean, (NSOutputStream *)writeStream, hasSpaceAvailable);
     struct _CFStream *stream = (struct _CFStream *)writeStream;
     CFStreamStatus status = _CFStreamGetStatus(stream);
     const struct _CFStreamCallBacks *cb;
@@ -1150,7 +1150,7 @@ CF_EXPORT Boolean CFWriteStreamCanAcceptBytes(CFWriteStreamRef writeStream) {
 }
 
 CF_EXPORT CFIndex CFWriteStreamWrite(CFWriteStreamRef writeStream, const UInt8 *buffer, CFIndex bufferLength) {
-    CF_OBJC_FUNCDISPATCH2(__kCFWriteStreamTypeID, CFIndex, writeStream, "write:maxLength:", buffer, bufferLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFIndex, (NSOutputStream *)writeStream, write:(const uint8_t *)buffer maxLength:(NSUInteger)bufferLength);
     struct _CFStream *stream = (struct _CFStream *)writeStream;
     CFStreamStatus status = _CFStreamGetStatus(stream);
     const struct _CFStreamCallBacks *cb = _CFStreamGetCallBackPtr(stream);
@@ -1204,12 +1204,12 @@ __private_extern__ CFTypeRef _CFStreamCopyProperty(struct _CFStream *stream, CFS
 }
 
 CF_EXPORT CFTypeRef CFReadStreamCopyProperty(CFReadStreamRef stream, CFStringRef propertyName) {
-    CF_OBJC_FUNCDISPATCH1(__kCFReadStreamTypeID, CFTypeRef, stream, "propertyForKey:", propertyName);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, CFTypeRef, (NSInputStream *)stream, propertyForKey:(NSString *)propertyName);
     return _CFStreamCopyProperty((struct _CFStream *)stream, propertyName);
 }
 
 CF_EXPORT CFTypeRef CFWriteStreamCopyProperty(CFWriteStreamRef stream, CFStringRef propertyName) {
-    CF_OBJC_FUNCDISPATCH1(__kCFWriteStreamTypeID, CFTypeRef, stream, "propertyForKey:", propertyName);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, CFTypeRef, (NSOutputStream *)stream, propertyForKey:(NSString *)propertyName);
     return _CFStreamCopyProperty((struct _CFStream *)stream, propertyName);
 }
 
@@ -1228,13 +1228,13 @@ __private_extern__ Boolean _CFStreamSetProperty(struct _CFStream *stream, CFStri
 
 CF_EXPORT
 Boolean CFReadStreamSetProperty(CFReadStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue) {
-    CF_OBJC_FUNCDISPATCH2(__kCFReadStreamTypeID, Boolean, stream, "setProperty:forKey:", propertyValue, propertyName);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, Boolean, (NSInputStream *)stream, setProperty:(id)propertyValue forKey:(NSString *)propertyName);
     return _CFStreamSetProperty((struct _CFStream *)stream, propertyName, propertyValue);
 }
 
 CF_EXPORT
 Boolean CFWriteStreamSetProperty(CFWriteStreamRef stream, CFStringRef propertyName, CFTypeRef propertyValue) {
-    CF_OBJC_FUNCDISPATCH2(__kCFWriteStreamTypeID, Boolean, stream, "setProperty:forKey:", propertyValue, propertyName);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, Boolean, (NSOutputStream *)stream, setProperty:(id)propertyValue forKey:(NSString *)propertyName);
     return _CFStreamSetProperty((struct _CFStream *)stream, propertyName, propertyValue);
 }
 
@@ -1293,13 +1293,13 @@ __private_extern__ Boolean _CFStreamSetClient(struct _CFStream *stream, CFOption
 }
 
 CF_EXPORT Boolean CFReadStreamSetClient(CFReadStreamRef readStream, CFOptionFlags streamEvents, CFReadStreamClientCallBack clientCB, CFStreamClientContext *clientContext) {
-    CF_OBJC_FUNCDISPATCH3(__kCFReadStreamTypeID, Boolean, readStream, "_setCFClientFlags:callback:context:", streamEvents, clientCB, clientContext);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, Boolean, (NSInputStream *)readStream, _setCFClientFlags:streamEvents callback:clientCB context:clientContext);
     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_FUNCDISPATCH3(__kCFWriteStreamTypeID, Boolean, writeStream, "_setCFClientFlags:callback:context:", streamEvents, clientCB, clientContext);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, Boolean, (NSOutputStream *)writeStream, _setCFClientFlags:streamEvents callback:clientCB context:clientContext);
     streamEvents &= ~kCFStreamEventHasBytesAvailable;
     return _CFStreamSetClient((struct _CFStream *)writeStream, streamEvents, (void (*)(struct _CFStream *, CFStreamEventType, void *))clientCB, clientContext);
 }
@@ -1478,12 +1478,12 @@ __private_extern__ void _CFStreamScheduleWithRunLoop(struct _CFStream *stream, C
 }
 
 CF_EXPORT void CFReadStreamScheduleWithRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCH2(__kCFReadStreamTypeID, void, stream, "_scheduleInCFRunLoop:forMode:", runLoop, runLoopMode);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, void, (NSInputStream *)stream, _scheduleInCFRunLoop:runLoop forMode:runLoopMode);
     _CFStreamScheduleWithRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
 CF_EXPORT void CFWriteStreamScheduleWithRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCH2(__kCFWriteStreamTypeID, void, stream, "_scheduleInCFRunLoop:forMode:", runLoop, runLoopMode);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, void, (NSOutputStream *)stream, _scheduleInCFRunLoop:runLoop forMode:runLoopMode);
     _CFStreamScheduleWithRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
@@ -1545,12 +1545,12 @@ __private_extern__ void _CFStreamUnscheduleFromRunLoop(struct _CFStream *stream,
 }
 
 CF_EXPORT void CFReadStreamUnscheduleFromRunLoop(CFReadStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCH2(__kCFReadStreamTypeID, void, stream, "_unscheduleFromCFRunLoop:forMode:", runLoop, runLoopMode);
+    CF_OBJC_FUNCDISPATCHV(__kCFReadStreamTypeID, void, (NSInputStream *)stream, _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode);
     _CFStreamUnscheduleFromRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
 void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef runLoop, CFStringRef runLoopMode) {
-    CF_OBJC_FUNCDISPATCH2(__kCFWriteStreamTypeID, void, stream, "_unscheduleFromCFRunLoop:forMode:", runLoop, runLoopMode);
+    CF_OBJC_FUNCDISPATCHV(__kCFWriteStreamTypeID, void, (NSOutputStream *)stream, _unscheduleFromCFRunLoop:runLoop forMode:runLoopMode);
     _CFStreamUnscheduleFromRunLoop((struct _CFStream *)stream, runLoop, runLoopMode);
 }
 
@@ -1750,8 +1750,7 @@ CF_EXPORT CFIndex _CFStreamInstanceSize(void) {
     return sizeof(struct _CFStream);
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#elif DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_WINDOWS
 void __CFStreamCleanup(void) {
     __CFSpinLock(&sSourceLock);
     if (sSharedSources) {
@@ -1780,7 +1779,5 @@ void __CFStreamCleanup(void) {
     }
     __CFSpinUnlock(&sSourceLock);
 }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
index 19d17c26504b749bfb601f7ed47845d75ffb434a..0bd5dffc0586b795cd279c888221804d29d48e1e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStream.h
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAM__)
 #include <CoreFoundation/CFSocket.h>
 #include <CoreFoundation/CFError.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
-enum {
+typedef CF_ENUM(CFIndex, CFStreamStatus) {
     kCFStreamStatusNotOpen = 0,
     kCFStreamStatusOpening,  /* open is in-progress */
     kCFStreamStatusOpen,
@@ -48,9 +49,8 @@ enum {
     kCFStreamStatusClosed,
     kCFStreamStatusError
 };
-typedef CFIndex CFStreamStatus;
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFStreamEventType) {
     kCFStreamEventNone = 0,
     kCFStreamEventOpenCompleted = 1,
     kCFStreamEventHasBytesAvailable = 2,
@@ -58,7 +58,6 @@ enum {
     kCFStreamEventErrorOccurred = 8,
     kCFStreamEventEndEncountered = 16
 };
-typedef CFOptionFlags CFStreamEventType;
 
 typedef struct {
     CFIndex version;
@@ -102,8 +101,10 @@ CF_EXPORT
 CFReadStreamRef CFReadStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL);
 CF_EXPORT
 CFWriteStreamRef CFWriteStreamCreateWithFile(CFAllocatorRef alloc, CFURLRef fileURL);
+CF_IMPLICIT_BRIDGING_DISABLED
 CF_EXPORT
 void CFStreamCreateBoundPair(CFAllocatorRef alloc, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream, CFIndex transferBufferSize);
+CF_IMPLICIT_BRIDGING_ENABLED
 
 /* Property for file write streams; value should be a CFBoolean.  Set to TRUE to append to a file, rather than to replace its contents */
 CF_EXPORT
@@ -127,6 +128,7 @@ const CFStringRef kCFStreamPropertySocketRemoteHostName;
 CF_EXPORT
 const CFStringRef kCFStreamPropertySocketRemotePortNumber;
 
+CF_IMPLICIT_BRIDGING_DISABLED
 /* Socket streams; the returned streams are paired such that they use the same socket; pass NULL if you want only the read stream or the write stream */
 CF_EXPORT
 void CFStreamCreatePairWithSocket(CFAllocatorRef alloc, CFSocketNativeHandle sock, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
@@ -134,6 +136,7 @@ CF_EXPORT
 void CFStreamCreatePairWithSocketToHost(CFAllocatorRef alloc, CFStringRef host, UInt32 port, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
 CF_EXPORT
 void CFStreamCreatePairWithPeerSocketSignature(CFAllocatorRef alloc, const CFSocketSignature *signature, CFReadStreamRef *readStream, CFWriteStreamRef *writeStream);
+CF_IMPLICIT_BRIDGING_ENABLED
 
 
 /* Returns the current state of the stream */
@@ -260,12 +263,11 @@ void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef ru
 
 
 /* The following API is deprecated starting in 10.5; please use CFRead/WriteStreamCopyError(), above, instead */
-enum {
-    kCFStreamErrorDomainCustom = -1,      /* custom to the kind of stream in question */
+typedef CF_ENUM(CFIndex, CFStreamErrorDomain) {
+    kCFStreamErrorDomainCustom = -1L,      /* custom to the kind of stream in question */
     kCFStreamErrorDomainPOSIX = 1,        /* POSIX errno; interpret using <sys/errno.h> */
     kCFStreamErrorDomainMacOSStatus      /* OSStatus type from Carbon APIs; interpret using <MacTypes.h> */
 };
-typedef CFIndex CFStreamErrorDomain;
 
 typedef struct {
     CFIndex domain; 
@@ -278,5 +280,6 @@ CFStreamError CFWriteStreamGetError(CFWriteStreamRef stream);
 
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFSTREAM__ */
index fa17b5f804bc745023947dc8e109e7821be92a9f..ab4d070a5b4e1a7c5dfb50d9a83d7e6777ad4fcf 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStreamAbstract.h
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAMABSTRACT__)
index 257ab735ef94b4398c0977b192df7a31b6a7bc57..37ee6f0598c24029ece362fe2ea8de58237b3d2e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStreamPriv.h
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTREAMPRIV__)
@@ -197,5 +197,14 @@ void __CFSocketSetSocketReadBufferAttrs(CFSocketRef s, CFTimeInterval timeout, C
 
 CF_EXTERN_C_END
 
+/*
+ * for CF{Read/Write}StreamCopyProperty created from a file.  The
+ * result is a CFDataRef containing sizeof(int) bytes in machine byte
+ * ordering representing the file descriptor of the underlying open
+ * file.  If the underlying file descriptor is not open, the property
+ * value will be NULL (as opposed to containing ((int) -1)).
+ */
+CF_EXPORT const CFStringRef _kCFStreamPropertyFileNativeHandle CF_AVAILABLE_IOS(5_0);
+
 #endif /* ! __COREFOUNDATION_CFSTREAMPRIV__ */
 
index e86a9a45d0d715f1e66c09b59eca3b3d6cd4aca1..e59d7d782dd22879d372b9f4205de12872615745 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFString.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, 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.
 #include <CoreFoundation/CFUnicodePrecomposition.h>
 #include <CoreFoundation/CFPriv.h>
 #include <CoreFoundation/CFNumber.h>
+#include <CoreFoundation/CFNumberFormatter.h>
 #include "CFInternal.h"
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #include "CFLocaleInternal.h"
+#endif
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -104,7 +107,7 @@ static void __CFRecordStringAllocationEvent(const char *encoding, const char *by
 
 typedef Boolean (*UNI_CHAR_FUNC)(UInt32 flags, UInt8 ch, UniChar *unicodeChar);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 extern size_t malloc_good_size(size_t size);
 #endif
 extern void __CFStrConvertBytesToUnicode(const uint8_t *bytes, UniChar *buffer, CFIndex numChars);
@@ -420,7 +423,7 @@ static CFStringEncoding __CFDefaultFileSystemEncoding = kCFStringEncodingInvalid
 CFStringEncoding __CFDefaultEightBitStringEncoding = kCFStringEncodingInvalidId;
 
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #define __defaultEncoding kCFStringEncodingMacRoman
 #elif DEPLOYMENT_TARGET_WINDOWS
 #define __defaultEncoding kCFStringEncodingWindowsLatin1
@@ -447,7 +450,7 @@ CF_INLINE CFStringEncoding __CFStringGetSystemEncoding(void) {
 
 CFStringEncoding CFStringFileSystemEncoding(void) {
     if (__CFDefaultFileSystemEncoding == kCFStringEncodingInvalidId) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
         __CFDefaultFileSystemEncoding = kCFStringEncodingUTF8;
 #else
         __CFDefaultFileSystemEncoding = CFStringGetSystemEncoding();
@@ -530,7 +533,33 @@ CFStringEncoding __CFStringComputeEightBitStringEncoding(void) {
 */
 CF_INLINE Boolean __CFBytesInASCII(const uint8_t *bytes, CFIndex len) {
 #if __LP64__
-    /* Go by 8s in 64 bit */
+    /* 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;
@@ -613,7 +642,7 @@ CF_INLINE CFIndex __CFStrNewCapacity(CFMutableStringRef str, unsigned long reqCa
             }
            if (__CFStrHasContentsAllocator(str)) {     /* Also apply any preferred size from the allocator  */
                 newCapacity = CFAllocatorGetPreferredSizeForSize(__CFStrContentsAllocator(str), newCapacity, 0);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
             } else {
                 newCapacity = malloc_good_size(newCapacity);
 #endif
@@ -854,27 +883,26 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange *
     
         CFAssert1(hasLengthAndNullBytes == __CFStrHasNullByte(str), __kCFLogAssertion, "%s(): Invalid state in 8-bit string", __PRETTY_FUNCTION__);
     
-        if (hasLengthAndNullBytes) curContents++;
-        if (useLengthAndNullBytes) newContents++;
-    
+        // Calculate pointers to the actual string content (skipping over the length byte, if present).  Note that keeping a reference to the base is needed for newContents under GC, since the copy may take a long time.
+        const uint8_t *curContentsBody = hasLengthAndNullBytes ? (curContents+1) : curContents;
+        uint8_t *newContentsBody = useLengthAndNullBytes ? (newContents+1) : newContents;
+        
         if (curContents) {
             if (oldIsUnicode == newIsUnicode) {
-                if (newContents == curContents) {
-                    rearrangeBlocks(newContents, curLength, newCharSize, deleteRanges, numDeleteRanges, insertLength);
+                if (newContentsBody == curContentsBody) {
+                    rearrangeBlocks(newContentsBody, curLength, newCharSize, deleteRanges, numDeleteRanges, insertLength);
                 } else {
-                    copyBlocks(curContents, newContents, curLength, oldIsUnicode, newIsUnicode, deleteRanges, numDeleteRanges, insertLength);
+                    copyBlocks(curContentsBody, newContentsBody, curLength, oldIsUnicode, newIsUnicode, deleteRanges, numDeleteRanges, insertLength);
                 }
             } else if (newIsUnicode) { /* this implies we have a new buffer */
-                copyBlocks(curContents, newContents, curLength, oldIsUnicode, newIsUnicode, deleteRanges, numDeleteRanges, insertLength);
+                copyBlocks(curContentsBody, newContentsBody, curLength, oldIsUnicode, newIsUnicode, deleteRanges, numDeleteRanges, insertLength);
             }
-            if (hasLengthAndNullBytes) curContents--;  /* Undo the damage from above */
             if (allocNewBuffer && __CFStrFreeContentsWhenDone(str)) __CFStrDeallocateMutableContents(str, (void *)curContents);
         }
-    
+        
         if (!newIsUnicode) {
             if (useLengthAndNullBytes) {
-                newContents[newLength] = 0;    /* Always have null byte, if not unicode */
-                newContents--; /* Undo the damage from above */
+                newContentsBody[newLength] = 0;        /* Always have null byte, if not unicode */
                 newContents[0] = __CFCanUseLengthByte(newLength) ? (uint8_t)newLength : 0;
                 if (!hasLengthAndNullBytes) __CFStrSetHasLengthAndNullBytes(str);
             } else {
@@ -886,7 +914,7 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange *
             if (hasLengthAndNullBytes) __CFStrClearHasLengthAndNullBytes(str);
         }
         __CFStrSetExplicitLength(str, newLength);
-    
+        
         if (allocNewBuffer) {
             __CFStrSetCapacity(str, newCapacity);
             __CFStrClearCapacityProvidedExternally(str);
@@ -1114,14 +1142,14 @@ CFHashCode CFStringHashNSString(CFStringRef str) {
     CFIndex bufLen;            // Number of characters in the buffer for hashing
     CFIndex len = 0;   // Actual length of the string
     
-    CF_OBJC_CALL0(CFIndex, len, str, "length");
-   if (len <= HashEverythingLimit) {
-        CF_OBJC_VOIDCALL2(str, "getCharacters:range:", buffer, CFRangeMake(0, len));
+    len = CF_OBJC_CALLV((NSString *)str, length);
+    if (len <= HashEverythingLimit) {
+        (void)CF_OBJC_CALLV((NSString *)str, getCharacters:buffer range:NSMakeRange(0, len));
         bufLen = len;
     } else {
-        CF_OBJC_VOIDCALL2(str, "getCharacters:range:", buffer, CFRangeMake(0, 32));
-        CF_OBJC_VOIDCALL2(str, "getCharacters:range:", buffer+32, CFRangeMake((len >> 1) - 16, 32));
-        CF_OBJC_VOIDCALL2(str, "getCharacters:range:", buffer+64, CFRangeMake(len - 32, 32));
+        (void)CF_OBJC_CALLV((NSString *)str, getCharacters:buffer range:NSMakeRange(0, 32));
+        (void)CF_OBJC_CALLV((NSString *)str, getCharacters:buffer+32 range:NSMakeRange((len >> 1) - 16, 32));
+        (void)CF_OBJC_CALLV((NSString *)str, getCharacters:buffer+64 range:NSMakeRange(len - 32, 32));
         bufLen = HashEverythingLimit;
     }
     return __CFStrHashCharacters(buffer, bufLen, len);
@@ -1176,7 +1204,7 @@ CFTypeID CFStringGetTypeID(void) {
 
 
 static Boolean CFStrIsUnicode(CFStringRef str) {
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, Boolean, str, "_encodingCantBeStoredInEightBitCFString");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, Boolean, (NSString *)str, _encodingCantBeStoredInEightBitCFString);
     return __CFStrIsUnicode(str);
 }
 
@@ -1251,7 +1279,7 @@ __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(
     // First check to see if the data needs to be converted...
     // ??? We could be more efficient here and in some cases (Unicode data) eliminate a copy
 
-    if ((encoding == kCFStringEncodingUnicode && possiblyExternalFormat) || encoding != kCFStringEncodingUnicode && ! stringSupportsEightBitCFRepresentation) {
+    if ((encoding == kCFStringEncodingUnicode && possiblyExternalFormat) || (encoding != kCFStringEncodingUnicode && ! stringSupportsEightBitCFRepresentation)) {
         const void *realBytes = (uint8_t *) bytes + (hasLengthByte ? 1 : 0);
         CFIndex realNumBytes = numBytes - (hasLengthByte ? 1 : 0);
         Boolean usingPassedInMemory = false;
@@ -1562,7 +1590,7 @@ CFStringRef  CFStringCreateWithFormat(CFAllocatorRef alloc, CFDictionaryRef form
 }
 
 CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, CFRange range) {
-//      CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, CFStringRef , str, "_createSubstringWithRange:", CFRangeMake(range.location, range.length));
+//      CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFStringRef , (NSString *)str, _createSubstringWithRange:NSMakeRange(range.location, range.length));
 
     __CFAssertIsString(str);
     __CFAssertRangeIsInStringBounds(str, range.location, range.length);
@@ -1579,7 +1607,7 @@ CFStringRef CFStringCreateWithSubstring(CFAllocatorRef alloc, CFStringRef str, C
 }
 
 CFStringRef CFStringCreateCopy(CFAllocatorRef alloc, CFStringRef str) {
-//  CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFStringRef, str, "copy");
+//  CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFStringRef, (NSString *)str, copy);
 
     __CFAssertIsString(str);
     if (!__CFStrIsMutable((CFStringRef)str) &&                                                                 // If the string is not mutable
@@ -1688,9 +1716,10 @@ CFStringRef __CFStringMakeConstantString(const char *cStr) {
        if (__CFStrIsEightBit(result)) {        
            key = (char *)__CFStrContents(result) + __CFStrSkipAnyLengthByte(result);
        } else {        // For some reason the string is not 8-bit!
-           key = (char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, strlen(cStr) + 1, 0);
+           CFIndex keySize = strlen(cStr) + 1;
+           key = (char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, keySize, 0);
            if (__CFOASafe) __CFSetLastAllocationEventName((void *)key, "CFString (CFSTR key)");
-           strlcpy(key, cStr, strlen(cStr) + 1);       // !!! We will leak this, if the string is removed from the table (or table is freed)
+           strlcpy(key, cStr, keySize);        // !!! We will leak this, if the string is removed from the table (or table is freed)
        }
 
        {
@@ -1856,7 +1885,7 @@ CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength
 CFMutableStringRef  CFStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFStringRef string) {
     CFMutableStringRef newString;
 
-    //  CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFMutableStringRef, string, "mutableCopy");
+    //  CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFMutableStringRef, (NSString *)string, mutableCopy);
 
     __CFAssertIsString(string);
 
@@ -1876,7 +1905,7 @@ __private_extern__ void _CFStrSetDesiredCapacity(CFMutableStringRef str, CFIndex
 /* This one is for CF
 */
 CFIndex CFStringGetLength(CFStringRef str) {
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFIndex, str, "length");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFIndex, (NSString *)str, length);
 
     __CFAssertIsString(str);
     return __CFStrLength(str);
@@ -1909,7 +1938,7 @@ CF_INLINE UniChar __CFStringGetCharacterAtIndexGuts(CFStringRef str, CFIndex idx
 /* This one is for the CF API
 */
 UniChar CFStringGetCharacterAtIndex(CFStringRef str, CFIndex idx) {
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, UniChar, str, "characterAtIndex:", idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, UniChar, (NSString *)str, characterAtIndex:(NSUInteger)idx);
 
     __CFAssertIsString(str);
     __CFAssertIndexIsInStringBounds(str, idx);
@@ -1940,7 +1969,7 @@ CF_INLINE void __CFStringGetCharactersGuts(CFStringRef str, CFRange range, UniCh
 /* This one is for the CF API
 */
 void CFStringGetCharacters(CFStringRef str, CFRange range, UniChar *buffer) {
-    CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "getCharacters:range:", buffer, range);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSString *)str, getCharacters:(unichar *)buffer range:NSMakeRange(range.location, range.length));
 
     __CFAssertIsString(str);
     __CFAssertRangeIsInStringBounds(str, range.location, range.length);
@@ -2004,7 +2033,7 @@ 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?
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, const char *, str, "_fastCStringContents:", true);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, const char *, (NSString *)str, _fastCStringContents:true);
 
     __CFAssertIsString(str);
 
@@ -2033,7 +2062,7 @@ const char * CFStringGetCStringPtr(CFStringRef str, CFStringEncoding encoding) {
 
 const UniChar *CFStringGetCharactersPtr(CFStringRef str) {
 
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, const UniChar *, str, "_fastCharacterContents");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, const UniChar *, (NSString *)str, _fastCharacterContents);
     
     __CFAssertIsString(str);
     if (__CFStrIsUnicode(str)) return (const UniChar *)__CFStrContents(str);
@@ -2092,7 +2121,7 @@ Boolean CFStringGetCString(CFStringRef str, char *buffer, CFIndex bufferSize, CF
     __CFAssertIsNotNegative(bufferSize);
     if (bufferSize < 1) return false;
 
-    CF_OBJC_FUNCDISPATCH3(__kCFStringTypeID, Boolean, str, "_getCString:maxLength:encoding:", buffer, bufferSize - 1, encoding);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, Boolean, (NSString *)str, _getCString:buffer maxLength:(NSUInteger)bufferSize - 1 encoding:encoding);
 
     __CFAssertIsString(str);
 
@@ -2166,6 +2195,8 @@ static const char *_CFStrGetLanguageIdentifierForLocale(CFLocaleRef locale) {
             langID = "tr";
         } else if (!strncmp(string, "nl", 2)) { // Dutch
             langID = "nl";
+        } else if (!strncmp(string, "el", 2)) { // Greek
+            langID = "el";
         }
     }
 
@@ -2783,7 +2814,7 @@ CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef string, CFStr
 
 CFComparisonResult CFStringCompareWithOptions(CFStringRef string, CFStringRef string2, CFRange rangeToCompare, CFStringCompareFlags compareOptions) { return CFStringCompareWithOptionsAndLocale(string, string2, rangeToCompare, compareOptions, NULL); }
 
-CFComparisonResult CFStringCompare(CFStringRef string, CFStringRef str2, CFOptionFlags options) {
+CFComparisonResult CFStringCompare(CFStringRef string, CFStringRef str2, CFStringCompareFlags options) {
     return CFStringCompareWithOptions(string, str2, CFRangeMake(0, CFStringGetLength(string)), options);
 }
 
@@ -3789,12 +3820,12 @@ static void __CFStringGetLineOrParagraphBounds(CFStringRef string, CFRange range
 }
 
 void CFStringGetLineBounds(CFStringRef string, CFRange range, CFIndex *lineBeginIndex, CFIndex *lineEndIndex, CFIndex *contentsEndIndex) {
-    CF_OBJC_FUNCDISPATCH4(__kCFStringTypeID, void, string, "getLineStart:end:contentsEnd:forRange:", lineBeginIndex, lineEndIndex, contentsEndIndex, range);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSString *)string, getLineStart:(NSUInteger *)lineBeginIndex end:(NSUInteger *)lineEndIndex contentsEnd:(NSUInteger *)contentsEndIndex forRange:NSMakeRange(range.location, range.length));
     __CFStringGetLineOrParagraphBounds(string, range, lineBeginIndex, lineEndIndex, contentsEndIndex, true);
 }
 
 void CFStringGetParagraphBounds(CFStringRef string, CFRange range, CFIndex *parBeginIndex, CFIndex *parEndIndex, CFIndex *contentsEndIndex) {
-    CF_OBJC_FUNCDISPATCH4(__kCFStringTypeID, void, string, "getParagraphStart:end:contentsEnd:forRange:", parBeginIndex, parEndIndex, contentsEndIndex, range);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSString *)string, getParagraphStart:(NSUInteger *)parBeginIndex end:(NSUInteger *)parEndIndex contentsEnd:(NSUInteger *)contentsEndIndex forRange:NSMakeRange(range.location, range.length));
     __CFStringGetLineOrParagraphBounds(string, range, parBeginIndex, parEndIndex, contentsEndIndex, false);
 }
 
@@ -3934,7 +3965,7 @@ CFDataRef CFStringCreateExternalRepresentation(CFAllocatorRef alloc, CFStringRef
     if (((encoding & 0x0FFF) == kCFStringEncodingUnicode) && ((encoding == kCFStringEncodingUnicode) || ((encoding > kCFStringEncodingUTF8) && (encoding <= kCFStringEncodingUTF32LE)))) {
         guessedByteLength = (length + 1) * ((((encoding >> 26)  & 2) == 0) ? sizeof(UTF16Char) : sizeof(UTF32Char)); // UTF32 format has the bit set
     } else if (((guessedByteLength = CFStringGetMaximumSizeForEncoding(length, encoding)) > length) && !CF_IS_OBJC(__kCFStringTypeID, string)) { // Multi byte encoding
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
         if (__CFStrIsUnicode(string)) {
             CFIndex aLength = CFStringEncodingByteLengthForCharacters(encoding, kCFStringEncodingPrependBOM, __CFStrContents(string), __CFStrLength(string));
             if (aLength > 0) guessedByteLength = aLength;
@@ -3948,7 +3979,7 @@ CFDataRef CFStringCreateExternalRepresentation(CFAllocatorRef alloc, CFStringRef
         if (guessedByteLength == length && __CFStrIsEightBit(string) && __CFStringEncodingIsSupersetOfASCII(encoding)) { // It's all ASCII !!
             return CFDataCreate(alloc, ((uint8_t *)__CFStrContents(string) + __CFStrSkipAnyLengthByte(string)), __CFStrLength(string));
         }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
         }
 #endif
     }
@@ -3968,7 +3999,7 @@ CFDataRef CFStringCreateExternalRepresentation(CFAllocatorRef alloc, CFStringRef
 
 CFStringEncoding CFStringGetSmallestEncoding(CFStringRef str) {
     CFIndex len;
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFStringEncoding, str, "_smallestEncodingInCFStringEncoding");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFStringEncoding, (NSString *)str, _smallestEncodingInCFStringEncoding);
     __CFAssertIsString(str);
 
     if (__CFStrIsEightBit(str)) return __CFStringGetEightBitStringEncoding();
@@ -3980,7 +4011,7 @@ CFStringEncoding CFStringGetSmallestEncoding(CFStringRef str) {
 
 
 CFStringEncoding CFStringGetFastestEncoding(CFStringRef str) {
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, CFStringEncoding, str, "_fastestEncodingInCFStringEncoding");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFStringEncoding, (NSString *)str, _fastestEncodingInCFStringEncoding);
     __CFAssertIsString(str);
     return __CFStrIsEightBit(str) ? __CFStringGetEightBitStringEncoding() : kCFStringEncodingUnicode;  /* ??? */
 }
@@ -4023,7 +4054,7 @@ void CFStringSetExternalCharactersNoCopy(CFMutableStringRef string, UniChar *cha
 
 
 void CFStringInsert(CFMutableStringRef str, CFIndex idx, CFStringRef insertedStr) {
-    CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "insertString:atIndex:", insertedStr, idx);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, insertString:(NSString *)insertedStr atIndex:(NSUInteger)idx);
     __CFAssertIsStringAndMutable(str);
     CFAssert3(idx >= 0 && idx <= __CFStrLength(str), __kCFLogAssertion, "%s(): string index %d out of bounds (length %d)", __PRETTY_FUNCTION__, idx, __CFStrLength(str));
     __CFStringReplace(str, CFRangeMake(idx, 0), insertedStr);
@@ -4031,7 +4062,7 @@ void CFStringInsert(CFMutableStringRef str, CFIndex idx, CFStringRef insertedStr
 
 
 void CFStringDelete(CFMutableStringRef str, CFRange range) {
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, str, "deleteCharactersInRange:", range);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, deleteCharactersInRange:NSMakeRange(range.location, range.length));
     __CFAssertIsStringAndMutable(str);
     __CFAssertRangeIsInStringBounds(str, range.location, range.length);
     __CFStringChangeSize(str, range, 0, false);
@@ -4039,7 +4070,7 @@ void CFStringDelete(CFMutableStringRef str, CFRange range) {
 
 
 void CFStringReplace(CFMutableStringRef str, CFRange range, CFStringRef replacement) {
-    CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "replaceCharactersInRange:withString:", range, replacement);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, replaceCharactersInRange:NSMakeRange(range.location, range.length) withString:(NSString *)replacement);
     __CFAssertIsStringAndMutable(str);
     __CFAssertRangeIsInStringBounds(str, range.location, range.length);
     __CFStringReplace(str, range, replacement);
@@ -4047,14 +4078,14 @@ void CFStringReplace(CFMutableStringRef str, CFRange range, CFStringRef replacem
 
 
 void CFStringReplaceAll(CFMutableStringRef str, CFStringRef replacement) {
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, str, "setString:", replacement);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, setString:(NSString *)replacement);
     __CFAssertIsStringAndMutable(str);
     __CFStringReplace(str, CFRangeMake(0, __CFStrLength(str)), replacement);
 }
 
 
 void CFStringAppend(CFMutableStringRef str, CFStringRef appended) {
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, str, "appendString:", appended);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, appendString:(NSString *)appended);
     __CFAssertIsStringAndMutable(str);
     __CFStringReplace(str, CFRangeMake(__CFStrLength(str), 0), appended);
 }
@@ -4065,7 +4096,7 @@ void CFStringAppendCharacters(CFMutableStringRef str, const UniChar *chars, CFIn
 
     __CFAssertIsNotNegative(appendedLength);
 
-    CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "appendCharacters:length:", chars, appendedLength);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, appendCharacters:chars length:(NSUInteger)appendedLength);
 
     __CFAssertIsStringAndMutable(str);
 
@@ -4129,9 +4160,9 @@ void __CFStringAppendBytes(CFMutableStringRef str, const char *cStr, CFIndex app
 
     if (CF_IS_OBJC(__kCFStringTypeID, str)) {
        if (!appendedIsUnicode && !demoteAppendedUnicode) {
-           CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "_cfAppendCString:length:", cStr, appendedLength);
+           CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, _cfAppendCString:(const unsigned char *)cStr length:(NSInteger)appendedLength);
        } else {
-           CF_OBJC_FUNCDISPATCH2(__kCFStringTypeID, void, str, "appendCharacters:length:", cStr, appendedLength);
+           CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)str, appendCharacters:(const unichar *)cStr length:(NSUInteger)appendedLength);
        }
     } else {
         CFIndex strLength;
@@ -4182,7 +4213,7 @@ void CFStringAppendFormat(CFMutableStringRef str, CFDictionaryRef formatOptions,
 
 
 CFIndex CFStringFindAndReplace(CFMutableStringRef string, CFStringRef stringToFind, CFStringRef replacementString, CFRange rangeToSearch, CFStringCompareFlags compareOptions) {
-    CF_OBJC_FUNCDISPATCH4(__kCFStringTypeID, CFIndex, string, "replaceOccurrencesOfString:withString:options:range:", stringToFind, replacementString, compareOptions, rangeToSearch);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, CFIndex, (NSMutableString *)string, replaceOccurrencesOfString:(NSString *)stringToFind withString:(NSString *)replacementString options:(NSStringCompareOptions)compareOptions range:NSMakeRange(rangeToSearch.location, rangeToSearch.length));
     CFRange foundRange;
     Boolean backwards = ((compareOptions & kCFCompareBackwards) != 0);
     UInt32 endIndex = rangeToSearch.location + rangeToSearch.length;
@@ -4268,7 +4299,7 @@ void CFStringPad(CFMutableStringRef string, CFStringRef padString, CFIndex lengt
     __CFAssertIsNotNegative(length);
     __CFAssertIsNotNegative(indexIntoPad);
  
-    CF_OBJC_FUNCDISPATCH3(__kCFStringTypeID, void, string, "_cfPad:length:padIndex:", padString, length, indexIntoPad);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfPad:padString length:(uint32_t)length padIndex:(uint32_t)indexIntoPad);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -4319,7 +4350,7 @@ void CFStringTrim(CFMutableStringRef string, CFStringRef trimString) {
     CFIndex newStartIndex;
     CFIndex length;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, string, "_cfTrim:", trimString);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfTrim:trimString);
 
     __CFAssertIsStringAndMutable(string);
     __CFAssertIsString(trimString);
@@ -4353,7 +4384,7 @@ void CFStringTrimWhitespace(CFMutableStringRef string) {
     CFIndex length;
     CFStringInlineBuffer buffer;
 
-    CF_OBJC_FUNCDISPATCH0(__kCFStringTypeID, void, string, "_cfTrimWS");
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfTrimWS);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -4389,7 +4420,7 @@ void CFStringLowercase(CFMutableStringRef string, CFLocaleRef locale) {
     const uint8_t *langCode;
     Boolean isEightBit = __CFStrIsEightBit(string);
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, string, "_cfLowercase:", locale);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfLowercase:(const void *)locale);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -4480,7 +4511,7 @@ void CFStringUppercase(CFMutableStringRef string, CFLocaleRef locale) {
     const uint8_t *langCode;
     Boolean isEightBit = __CFStrIsEightBit(string);
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, string, "_cfUppercase:", locale);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfUppercase:(const void *)locale);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -4574,7 +4605,7 @@ void CFStringCapitalize(CFMutableStringRef string, CFLocaleRef locale) {
     Boolean isLastCased = false;
     const uint8_t *caseIgnorableForBMP;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, string, "_cfCapitalize:", locale);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfCapitalize:(const void *)locale);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -4713,7 +4744,7 @@ void CFStringNormalize(CFMutableStringRef string, CFStringNormalizationForm theF
     CFIndex length;
     bool needToReorder = true;
 
-    CF_OBJC_FUNCDISPATCH1(__kCFStringTypeID, void, string, "_cfNormalize:", theForm);
+    CF_OBJC_FUNCDISPATCHV(__kCFStringTypeID, void, (NSMutableString *)string, _cfNormalize:theForm);
 
     __CFAssertIsStringAndMutable(string);
 
@@ -5012,7 +5043,7 @@ void CFStringNormalize(CFMutableStringRef string, CFStringNormalizationForm theF
     }
 }
 
-void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, CFLocaleRef locale) {
+void CFStringFold(CFMutableStringRef theString, CFOptionFlags theFlags, CFLocaleRef locale) {
     CFStringInlineBuffer stringBuffer;
     CFIndex length = CFStringGetLength(theString);
     CFIndex currentIndex = 0;
@@ -5167,11 +5198,12 @@ void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, C
 }
 
 enum {
-       kCFStringFormatZeroFlag = (1 << 0),     // if not, padding is space char
-       kCFStringFormatMinusFlag = (1 << 1),    // if not, no flag implied
-       kCFStringFormatPlusFlag = (1 << 2),     // if not, no flag implied, overrides space
-       kCFStringFormatSpaceFlag = (1 << 3),    // if not, no flag implied
-       kCFStringFormatExternalSpecFlag = (1 << 4) // using config dict
+       kCFStringFormatZeroFlag = (1 << 0),         // if not, padding is space char
+       kCFStringFormatMinusFlag = (1 << 1),        // if not, no flag implied
+       kCFStringFormatPlusFlag = (1 << 2),         // if not, no flag implied, overrides space
+       kCFStringFormatSpaceFlag = (1 << 3),        // if not, no flag implied
+       kCFStringFormatExternalSpecFlag = (1 << 4), // using config dict
+        kCFStringFormatLocalizable = (1 << 5)       // explicitly mark the specs we can localize
 };
 
 typedef struct {
@@ -5186,6 +5218,7 @@ typedef struct {
     int8_t precArgNum;
     int8_t widthArgNum;
     int8_t configDictIndex;
+    int8_t numericFormatStyle;        // Only set for localizable numeric quantities
 } CFFormatSpec;
 
 typedef struct {
@@ -5216,8 +5249,13 @@ enum {
     CFFormatSizePointer = CFFormatSize4
 #endif
 };
-
-
+        
+enum {
+    CFFormatStyleDecimal = (1 << 0),
+    CFFormatStyleScientific = (1 << 1),
+    CFFormatStyleDecimalOrScientific = CFFormatStyleDecimal|CFFormatStyleScientific,
+    CFFormatStyleUnsigned = (1 << 2)
+};
 
 enum {
     CFFormatLiteralType = 32,
@@ -5233,6 +5271,201 @@ enum {
     CFFormatDummyPointerType = 42      /* special case for %n */
 };
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+/* Only come in here if spec->type is CFFormatLongType or CFFormatDoubleType. Pass in 0 for width or precision if not specified. Returns false if couldn't do the format (with the assumption the caller falls back to unlocalized).
+*/
+static Boolean __CFStringFormatLocalizedNumber(CFMutableStringRef output, CFLocaleRef locale, const CFPrintValue *values, const CFFormatSpec *spec, SInt32 width, SInt32 precision, Boolean hasPrecision) {
+    static CFSpinLock_t formatterLock = CFSpinLockInit;
+    // These formatters are recached if the locale argument is different
+    static CFNumberFormatterRef decimalFormatter = NULL;
+    static CFNumberFormatterRef scientificFormatter = NULL;
+    static CFNumberFormatterRef gFormatter = NULL;  // for %g
+    static SInt32 groupingSize = 0;
+    static SInt32 secondaryGroupingSize = 0;
+    
+    // !!! This code should be removed before shipping
+    static char disableLocalizedFormatting = -1;
+    if (disableLocalizedFormatting == -1) disableLocalizedFormatting = (getenv("CFStringDisableLocalizedNumberFormatting") != NULL) ? 1 : 0;
+    if (disableLocalizedFormatting) return false;
+
+    CFNumberFormatterRef formatter;
+    
+    __CFSpinLock(&formatterLock);   // We use the formatter from one thread at one time; if this proves to be a bottleneck we need to get fancier
+
+    switch (spec->numericFormatStyle) {
+        case CFFormatStyleUnsigned:
+        case CFFormatStyleDecimal:
+                if (!decimalFormatter || !CFEqual(CFNumberFormatterGetLocale(decimalFormatter), locale)) {  // cache or recache if the locale is different
+                    if (decimalFormatter) CFRelease(decimalFormatter);
+                    decimalFormatter = CFNumberFormatterCreate(NULL, locale, kCFNumberFormatterDecimalStyle);  // since this is shared, remember to reset all its properties!
+                }
+                formatter = decimalFormatter;
+                break;
+        case CFFormatStyleScientific:
+                if (!scientificFormatter || !CFEqual(CFNumberFormatterGetLocale(scientificFormatter), locale)) {  // cache or recache if the locale is different
+                    if (scientificFormatter) CFRelease(scientificFormatter);
+                    scientificFormatter = CFNumberFormatterCreate(NULL, locale, kCFNumberFormatterScientificStyle);
+                    CFStringRef pattern = CFSTR("#E+00");     // the default pattern does not have the sign if the exponent is positive and it is single digit
+                    CFNumberFormatterSetFormat(scientificFormatter, pattern);
+                    CFNumberFormatterSetProperty(scientificFormatter, kCFNumberFormatterUseSignificantDigitsKey, kCFBooleanTrue);
+                }
+                formatter = scientificFormatter;
+                break;
+        case CFFormatStyleDecimalOrScientific:
+                if (!gFormatter || !CFEqual(CFNumberFormatterGetLocale(gFormatter), locale)) {  // cache or recache if the locale is different
+                    if (gFormatter) CFRelease(gFormatter);
+                    gFormatter = CFNumberFormatterCreate(NULL, locale, kCFNumberFormatterDecimalStyle);
+                    // when we update the locale in gFormatter, we also need to update the two grouping sizes
+                    CFNumberRef num = (CFNumberRef) CFNumberFormatterCopyProperty(gFormatter, kCFNumberFormatterGroupingSizeKey);
+                    CFNumberGetValue(num, kCFNumberSInt32Type, &groupingSize);
+                    CFRelease(num);
+                    num = (CFNumberRef) CFNumberFormatterCopyProperty(gFormatter, kCFNumberFormatterSecondaryGroupingSizeKey);
+                    CFNumberGetValue(num, kCFNumberSInt32Type, &secondaryGroupingSize);
+                    CFRelease(num);
+                }
+                formatter = gFormatter;
+                break;
+    }
+    
+    SInt32 prec = hasPrecision ? precision : ((spec->type == CFFormatLongType) ? 0 : 6); // default precision of printf is 6
+    
+    // pattern must be set before setting width and padding
+    // otherwise, the pattern will take over those settings
+    if (spec->numericFormatStyle == CFFormatStyleDecimalOrScientific) {
+        if (prec == 0) prec = 1; // at least one sig fig
+        CFMutableStringRef pattern = CFStringCreateMutable(NULL, 0);
+        // use significant digits pattern
+        CFStringAppendCString(pattern, "@", kCFStringEncodingASCII);
+        CFStringPad(pattern, CFSTR("#"), prec, 0);
+        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
+        }
+#endif
+        double max = pow(10.0, (double)prec);   // if the value requires more digits than the number of sig figs, we need to use scientific format
+        double min = 0.0001;                    // if the value is less than 10E-4, scientific format is the shorter form
+        if (((targetValue > 0 && (targetValue > max || targetValue < min)) || (targetValue < 0 && (targetValue < -max || targetValue > -min)))){
+            CFStringAppendCString(pattern, "E+00", kCFStringEncodingASCII);
+        } else if (prec > groupingSize && groupingSize != 0) {
+            CFStringInsert(pattern, prec-groupingSize, CFSTR(","));  // if we are not using scientific format, we need to set the pattern to use grouping separator
+            if (secondaryGroupingSize != 0 && prec > (groupingSize + secondaryGroupingSize)) CFStringInsert(pattern, prec-groupingSize-secondaryGroupingSize, CFSTR(","));
+        }
+        CFNumberFormatterSetFormat(formatter, pattern);
+        CFRelease(pattern);
+    }
+    
+    CFNumberRef tmp;
+    
+    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);
+    }
+    CFRelease(tmp);
+
+
+    // ??? use the right zero here for Arabic
+    Boolean padZero = spec->flags & kCFStringFormatZeroFlag;
+    if (hasPrecision && spec->type == CFFormatLongType) {  // if we have precision and %d or %u, we pad 0
+        padZero = true;
+    }
+    CFNumberFormatterSetProperty(formatter, kCFNumberFormatterPaddingCharacterKey, padZero ? CFSTR("0") : CFSTR(" "));
+    
+        
+    // Left (default) or right padding
+    SInt32 p = (spec->flags & kCFStringFormatMinusFlag) ? kCFNumberFormatterPadAfterSuffix : (padZero ? kCFNumberFormatterPadAfterPrefix : kCFNumberFormatterPadBeforePrefix);
+    if (hasPrecision && spec->type == CFFormatLongType) {
+        SInt32 tmpP = kCFNumberFormatterPadAfterPrefix;
+        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &tmpP);
+    } else {
+        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &p); 
+    }
+    CFNumberFormatterSetProperty(formatter, kCFNumberFormatterPaddingPositionKey, tmp);
+    CFRelease(tmp);
+
+    CFStringRef pattern = CFNumberFormatterGetFormat(formatter);
+    if (spec->flags & kCFStringFormatPlusFlag) {
+        if (CFStringGetCharacterAtIndex(pattern, 0) != '+') {
+            CFMutableStringRef newPattern = CFStringCreateMutableCopy(NULL, 0, CFSTR("+"));
+            CFStringAppend(newPattern, pattern);
+            CFNumberFormatterSetFormat(formatter, newPattern);
+            CFRelease(newPattern);
+        }
+    } else {
+        if (CFStringGetCharacterAtIndex(pattern, 0) == '+') {
+            CFStringRef newPattern = CFStringCreateWithSubstring(NULL, pattern, CFRangeMake(1, CFStringGetLength(pattern)-1));
+            CFNumberFormatterSetFormat(formatter, newPattern);
+            CFRelease(newPattern);
+        }
+    }
+
+    // width == 0 seems to be CFNumberFormatter's default setting
+    if (hasPrecision && spec->type == CFFormatLongType) { // if we have precision and %d or %u, we pad 0 according to precision first
+        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &prec);
+    } else {
+        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &width); 
+    }
+    CFNumberFormatterSetProperty(formatter, kCFNumberFormatterFormatWidthKey, tmp);
+    CFRelease(tmp);
+
+    if (spec->numericFormatStyle == CFFormatStyleScientific) {
+        prec++;  // for %e, precision+1 is the number of sig fig
+        tmp = CFNumberCreate(NULL, kCFNumberSInt32Type, &prec);
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMinSignificantDigitsKey, tmp);
+        CFNumberFormatterSetProperty(formatter, kCFNumberFormatterMaxSignificantDigitsKey, tmp);
+        CFRelease(tmp);
+    }
+    
+    CFStringRef localizedNumberString = NULL;
+    switch (spec->type) {
+        case CFFormatLongType:
+            // ??? Need to do unsigned
+            localizedNumberString = CFNumberFormatterCreateStringWithValue(NULL, formatter, kCFNumberSInt64Type, &(values[spec->mainArgNum].value.int64Value));
+            break;
+        case CFFormatDoubleType: {
+#if LONG_DOUBLE_SUPPORT
+            if (CFFormatSize16 == values[spec->mainArgNum].size) {
+                double doubleValue = values[spec->mainArgNum].value.longDoubleValue; // losing precision
+                localizedNumberString = CFNumberFormatterCreateStringWithValue(NULL, formatter, kCFNumberDoubleType, &doubleValue);
+            } else
+#endif
+            {
+                localizedNumberString = CFNumberFormatterCreateStringWithValue(NULL, formatter, kCFNumberDoubleType, &(values[spec->mainArgNum].value.doubleValue));
+            }
+            break;
+        }
+    }
+    __CFSpinUnlock(&formatterLock);
+    
+    if (localizedNumberString) {
+        // we need to pad space if we have %d or %u
+        if (spec->type == CFFormatLongType && hasPrecision && CFStringGetLength(localizedNumberString) < width) {
+            CFMutableStringRef finalStr = NULL;
+            if (p == kCFNumberFormatterPadAfterSuffix) {
+                finalStr = CFStringCreateMutableCopy(NULL, 0, localizedNumberString);
+                CFStringPad(finalStr, CFSTR(" "), width, 0);
+            } else {
+                finalStr = CFStringCreateMutable(NULL, 0);
+                CFStringPad(finalStr, CFSTR(" "), width - CFStringGetLength(localizedNumberString), 0);
+                CFStringAppend(finalStr, localizedNumberString);
+            }
+            CFRelease(localizedNumberString);
+            localizedNumberString = finalStr;
+        }
+        CFStringAppend(output, localizedNumberString);
+        CFRelease(localizedNumberString);
+        return true;
+    }
+    return false;
+}
+#endif
+
 CF_INLINE void __CFParseFormatSpec(const UniChar *uformat, const uint8_t *cformat, SInt32 *fmtIdx, SInt32 fmtLen, CFFormatSpec *spec, CFStringRef *configKeyPointer) {
     Boolean seenDot = false;
     Boolean seenSharp = false;
@@ -5282,6 +5515,10 @@ reswtch:switch (ch) {
            spec->flags &= ~kCFStringFormatSpaceFlag;   // remove space flag
            break;
        case '0':
+            if (seenDot) {    // after we see '.' and then we see '0', it is 0 precision. We should not see '.' after '0' if '0' is the zero padding flag
+                spec->precArg = 0;
+                break;
+            }
            if (!(spec->flags & kCFStringFormatMinusFlag)) spec->flags |= kCFStringFormatZeroFlag;
            break;
        case 'h':
@@ -5326,16 +5563,32 @@ reswtch:switch (ch) {
            spec->type = CFFormatLongType;
            spec->size = CFFormatSize1;
            return;
-       case 'O': case 'o': case 'D': case 'd': case 'i': case 'U': case 'u': case 'x': case 'X':
-           spec->type = CFFormatLongType;
+        case 'D': case 'd': case 'i': case 'U': case 'u':
+            // we can localize all but octal or hex
+            if (_CFExecutableLinkedOnOrAfter(CFSystemVersionMountainLion)) spec->flags |= kCFStringFormatLocalizable;
+            spec->numericFormatStyle = CFFormatStyleDecimal;
+            if (ch == 'u' || ch == 'U') spec->numericFormatStyle = CFFormatStyleUnsigned;
+            // fall thru
+        case 'O': case 'o': case 'x': case 'X':
+            spec->type = CFFormatLongType;
             // Seems like if spec->size == 0, we should spec->size = CFFormatSize4. However, 0 is handled correctly.
            return;
-       case 'a': case 'A': case 'e': case 'E': case 'f': case 'F': case 'g': case 'G':
+        case 'f': case 'F': case 'g': case 'G': case 'e': case 'E': {
+                // we can localize all but hex float output
+                if (_CFExecutableLinkedOnOrAfter(CFSystemVersionMountainLion)) spec->flags |= kCFStringFormatLocalizable;
+                char lch = (ch >= 'A' && ch <= 'Z') ? (ch - 'A' + 'a') : ch;
+                spec->numericFormatStyle = ((lch == 'e' || lch == 'g') ? CFFormatStyleScientific : 0) | ((lch == 'f' || lch == 'g') ? CFFormatStyleDecimal : 0);
+                if (seenDot && spec->precArg == -1 && spec->precArgNum == -1) { // for the cases that we have '.' but no precision followed, not even '*'
+                    spec->precArg = 0;
+                }
+            }
+            // fall thru
+        case 'a': case 'A':
            spec->type = CFFormatDoubleType;
            if (spec->size != CFFormatSize16) spec->size = CFFormatSize8;
            return;
        case 'n':               /* %n is not handled correctly; for Leopard or newer apps, we disable it further */
-           spec->type = _CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard) ? CFFormatDummyPointerType : CFFormatPointerType;
+           spec->type = 1 ? CFFormatDummyPointerType : CFFormatPointerType;
            spec->size = CFFormatSizePointer;  // 4 or 8 depending on LP64
            return;
        case 'p':       
@@ -5408,27 +5661,29 @@ reswtch:switch (ch) {
     }
 }
 
-/* ??? It ignores the formatOptions argument.
-   ??? %s depends on handling of encodings by __CFStringAppendBytes
+/* ??? %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);
 }
+        
+// Length of the buffer to call sprintf() with
+#define BUFFER_LEN 512
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define SNPRINTF(TYPE, WHAT) {                         \
     TYPE value = (TYPE) WHAT;                          \
     if (-1 != specs[curSpec].widthArgNum) {            \
        if (-1 != specs[curSpec].precArgNum) {          \
-           snprintf_l(buffer, 255, NULL, formatBuffer, width, precision, value); \
+           snprintf_l(buffer, BUFFER_LEN-1, NULL, formatBuffer, width, precision, value); \
        } else {                                        \
-           snprintf_l(buffer, 255, NULL, formatBuffer, width, value); \
+           snprintf_l(buffer, BUFFER_LEN-1, NULL, formatBuffer, width, value); \
        }                                               \
     } else {                                           \
        if (-1 != specs[curSpec].precArgNum) {          \
-           snprintf_l(buffer, 255, NULL, formatBuffer, precision, value); \
+           snprintf_l(buffer, BUFFER_LEN-1, NULL, formatBuffer, precision, value); \
         } else {                                       \
-           snprintf_l(buffer, 255, NULL, formatBuffer, value); \
+           snprintf_l(buffer, BUFFER_LEN-1, NULL, formatBuffer, value);        \
        }                                               \
     }}
 #else
@@ -5459,8 +5714,8 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
     const UniChar *uformat = NULL;
     UniChar *formatChars = NULL;
     UniChar localFormatBuffer[FORMAT_BUFFER_LEN];
-
-    #define VPRINTF_BUFFER_LEN 61
+    
+#define VPRINTF_BUFFER_LEN 61
     CFFormatSpec localSpecsBuffer[VPRINTF_BUFFER_LEN];
     CFFormatSpec *specs;
     CFPrintValue localValuesBuffer[VPRINTF_BUFFER_LEN];
@@ -5471,7 +5726,6 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
     CFIndex numConfigs;
     CFAllocatorRef tmpAlloc = NULL;
     intmax_t dummyLocation;        // A place for %n to do its thing in; should be the widest possible int value
-    va_list copiedArgs;
 
     numSpecs = 0;
     sizeSpecs = 0;
@@ -5558,10 +5812,11 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
     if (values != localValuesBuffer && __CFOASafe) __CFSetLastAllocationEventName(values, "CFString (temp)");
     memset(values, 0, sizeArgNum * sizeof(CFPrintValue));
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
     // va_copy is a C99 extension. No support on Windows
+    va_list copiedArgs;
     if (numConfigs > 0) va_copy(copiedArgs, args); // we need to preserve the original state for passing down
-#endif /* DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD */
+#endif
 
     /* Compute values array */
     argNum = initialArgPosition;
@@ -5690,15 +5945,21 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
        switch (specs[curSpec].type) {
        case CFFormatLongType:
        case CFFormatDoubleType:
-       case CFFormatPointerType: {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+            if (formatOptions && (specs[curSpec].flags & kCFStringFormatLocalizable) && (CFGetTypeID(formatOptions) == CFLocaleGetTypeID())) {    // We have a locale, so we do localized formatting
+                if (__CFStringFormatLocalizedNumber(outputString, (CFLocaleRef)formatOptions, values, &specs[curSpec], width, precision, hasPrecision)) break;
+            }
+            /* Otherwise fall-thru to the next case! */
+#endif
+         case CFFormatPointerType: {
                 char formatBuffer[128];
 #if defined(__GNUC__)
-                char buffer[256 + width + precision];
+                char buffer[BUFFER_LEN + width + precision];
 #else
-                char stackBuffer[512];
+                char stackBuffer[BUFFER_LEN];
                 char *dynamicBuffer = NULL;
                 char *buffer = stackBuffer;
-                if (256+width+precision > 512) {
+                if (256+width+precision > BUFFER_LEN) {
                     dynamicBuffer = (char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, 256+width+precision, 0);
                     buffer = dynamicBuffer;
                 }
@@ -5752,7 +6013,11 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
                        }
                        // See if we need to localize the decimal point
                         if (formatOptions) {   // We have localization info
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
                            CFStringRef decimalSeparator = (CFGetTypeID(formatOptions) == CFLocaleGetTypeID()) ? (CFStringRef)CFLocaleGetValue((CFLocaleRef)formatOptions, kCFLocaleDecimalSeparatorKey) : (CFStringRef)CFDictionaryGetValue(formatOptions, CFSTR("NSDecimalSeparator"));
+#else
+                            CFStringRef decimalSeparator = CFSTR(".");
+#endif
                             if (decimalSeparator != NULL) {    // We have a decimal separator in there
                                 CFIndex decimalPointLoc = 0;
                                 while (buffer[decimalPointLoc] != 0 && buffer[decimalPointLoc] != '.') decimalPointLoc++;
@@ -5769,12 +6034,12 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
                 }
                 if (!appended) CFStringAppendCString(outputString, (const char *)buffer, __CFStringGetEightBitStringEncoding());            
 #if !defined(__GNUC__)
-                               if (dynamicBuffer) {
-                                       CFAllocatorDeallocate(kCFAllocatorSystemDefault, dynamicBuffer);
-                               }
+                if (dynamicBuffer) {
+                        CFAllocatorDeallocate(kCFAllocatorSystemDefault, dynamicBuffer);
+                }
 #endif
-                       }
-                break;
+            }
+            break;
        case CFFormatLiteralType:
             if (cformat) {
                 __CFStringAppendBytes(outputString, (const char *)(cformat+specs[curSpec].loc), specs[curSpec].len, __CFStringGetEightBitStringEncoding());
@@ -5989,10 +6254,10 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString
         }
     }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
     // va_copy is a C99 extension. No support on Windows
     if (numConfigs > 0) va_end(copiedArgs);
-#endif /* DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD */
+#endif 
     if (specs != localSpecsBuffer) CFAllocatorDeallocate(tmpAlloc, specs);
     if (values != localValuesBuffer) CFAllocatorDeallocate(tmpAlloc, values);
     if (formatChars && (formatChars != localFormatBuffer)) CFAllocatorDeallocate(tmpAlloc, formatChars);
index af0c7d32effecda54aa27c7e0f5ecc235690dafe..3ce34cb4995fff58b49b2d01015407eb43893043 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFString.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRING__)
@@ -36,6 +36,7 @@
 #include <CoreFoundation/CFLocale.h>
 #include <stdarg.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*
@@ -118,7 +119,7 @@ typedef UInt32 CFStringEncoding;
    Call CFStringGetSystemEncoding() to get the default system encoding.
 */
 #define kCFStringEncodingInvalidId (0xffffffffU)
-enum {
+typedef CF_ENUM(CFStringEncoding, CFStringBuiltInEncodings) {
     kCFStringEncodingMacRoman = 0,
     kCFStringEncodingWindowsLatin1 = 0x0500, /* ANSI codepage 1252 */
     kCFStringEncodingISOLatin1 = 0x0201, /* ISO 8859-1 */
@@ -136,7 +137,6 @@ enum {
     kCFStringEncodingUTF32BE = 0x18000100, /* kTextEncodingUnicodeDefault + kUnicodeUTF32BEFormat */
     kCFStringEncodingUTF32LE = 0x1c000100 /* kTextEncodingUnicodeDefault + kUnicodeUTF32LEFormat */
 };
-typedef CFStringEncoding CFStringBuiltInEncodings;
 
 
 /* CFString type ID */
@@ -385,21 +385,17 @@ CFStringRef CFStringCreateWithFileSystemRepresentation(CFAllocatorRef alloc, con
 
 /* Find and compare flags; these are OR'ed together and provided as CFStringCompareFlags in the various functions. 
 */
-enum { 
+typedef CF_OPTIONS(CFOptionFlags, CFStringCompareFlags) {
     kCFCompareCaseInsensitive = 1,     
     kCFCompareBackwards = 4,           /* Starting from the end of the string */
     kCFCompareAnchored = 8,            /* Only at the specified starting point */
     kCFCompareNonliteral = 16,         /* If specified, loose equivalence is performed (o-umlaut == o, umlaut) */
     kCFCompareLocalized = 32,          /* User's default locale is used for the comparisons */
-    kCFCompareNumerically = 64         /* Numeric comparison is used; that is, Foo2.txt < Foo7.txt < Foo25.txt */
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    ,
-    kCFCompareDiacriticInsensitive = 128, /* If specified, ignores diacritics (o-umlaut == o) */
-    kCFCompareWidthInsensitive = 256, /* If specified, ignores width differences ('a' == UFF41) */
-    kCFCompareForcedOrdering = 512 /* If specified, comparisons are forced to return either kCFCompareLessThan or kCFCompareGreaterThan if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with kCFCompareCaseInsensitive specified) */
-#endif /* MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED */
+    kCFCompareNumerically = 64,                /* Numeric comparison is used; that is, Foo2.txt < Foo7.txt < Foo25.txt */
+    kCFCompareDiacriticInsensitive CF_ENUM_AVAILABLE(10_5, 2_0) = 128, /* If specified, ignores diacritics (o-umlaut == o) */
+    kCFCompareWidthInsensitive CF_ENUM_AVAILABLE(10_5, 2_0) = 256, /* If specified, ignores width differences ('a' == UFF41) */
+    kCFCompareForcedOrdering CF_ENUM_AVAILABLE(10_5, 2_0) = 512 /* If specified, comparisons are forced to return either kCFCompareLessThan or kCFCompareGreaterThan if the strings are equivalent but not strictly equal, for stability when sorting (e.g. "aaa" > "AAA" with kCFCompareCaseInsensitive specified) */
 };
-typedef CFOptionFlags CFStringCompareFlags;
 
 /* The main comparison routine; compares specified range of the first string to (the full range of) the second string.
 locale == NULL indicates canonical locale (the return value from CFLocaleGetSystem()).
@@ -662,13 +658,12 @@ void CFStringCapitalize(CFMutableStringRef theString, CFLocaleRef locale);
        Unicode Technical Report #15. To normalize for use with file
        system calls, use CFStringGetFileSystemRepresentation().
 */
-enum {
+typedef CF_ENUM(CFIndex, CFStringNormalizationForm) {
        kCFStringNormalizationFormD = 0, // Canonical Decomposition
        kCFStringNormalizationFormKD, // Compatibility Decomposition
        kCFStringNormalizationFormC, // Canonical Decomposition followed by Canonical Composition
        kCFStringNormalizationFormKC // Compatibility Decomposition followed by Canonical Composition
 };
-typedef CFIndex CFStringNormalizationForm;
 
 /*!
        @function CFStringNormalize
@@ -889,5 +884,6 @@ CF_EXPORT
 CFStringRef  __CFStringMakeConstantString(const char *cStr);   /* Private; do not use */
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFSTRING__ */
index a0850648b99a089d76372fed8ae84cf05b82bb32..f209328642101724d111cd63b657a6ba6d33a3aa 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringDefaultEncoding.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGDEFAULTENCODING__)
index dc9797f4975430f942de04943c332a52437a8718..5ce9c40656d2709d8ac6c8ace7e30c9891df3e70 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverter.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -36,9 +36,6 @@
 #include "CFStringEncodingConverterExt.h"
 #include "CFStringEncodingConverterPriv.h"
 #include <stdlib.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#include <pthread.h>
-#endif
 
 typedef CFIndex (*_CFToBytesProc)(const void *converter, uint32_t flags, const UniChar *characters, CFIndex numChars, uint8_t *bytes, CFIndex maxByteLen, CFIndex *usedByteLen);
 typedef CFIndex (*_CFToUnicodeProc)(const void *converter, uint32_t flags, const uint8_t *bytes, CFIndex numBytes, UniChar *characters, CFIndex maxCharLen, CFIndex *usedCharLen);
@@ -550,9 +547,11 @@ CF_INLINE _CFEncodingConverter *__CFEncodingConverterFromDefinition(const CFStri
             converter->toCanonicalUnicode = __CFToCanonicalUnicodeCheapMultiByteWrapper;
             break;
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         case kCFStringEncodingConverterICU:
             converter->toBytes = (_CFToBytesProc)__CFStringEncodingGetICUName(encoding);
             break;
+#endif
 
         case kCFStringEncodingConverterPlatformSpecific:
             break;
@@ -605,14 +604,14 @@ static const _CFEncodingConverter *__CFGetConverter(uint32_t encoding) {
        case kCFStringEncodingUTF8: commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[0]); break;
 
            /* the swith here should avoid possible bootstrap issues in the default: case below when invoked from CFStringGetSystemEncoding() */
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
        case kCFStringEncodingMacRoman: commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[1]); break;
 #elif DEPLOYMENT_TARGET_WINDOWS
        case kCFStringEncodingWindowsLatin1: commonConverterSlot = (const _CFEncodingConverter **)(&(commonConverters[1])); break;
 #else
 #warning This case must match __defaultEncoding value defined in CFString.c
        case kCFStringEncodingISOLatin1: commonConverterSlot = (const _CFEncodingConverter **)(&(commonConverters[1])); break;
-#endif /* DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED */
+#endif
 
        default: if (CFStringGetSystemEncoding() == encoding) commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[2]); break;
     }
@@ -699,7 +698,9 @@ uint32_t CFStringEncodingUnicodeToBytes(uint32_t encoding, uint32_t flags, const
             }
         }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         if (kCFStringEncodingConverterICU == converter->definition->encodingClass) return __CFStringEncodingICUToBytes((const char *)converter->toBytes, flags, characters, numChars, usedCharLen, bytes, maxByteLen, usedByteLen);
+#endif
 
         /* Platform converter */
         if (kCFStringEncodingConverterPlatformSpecific == converter->definition->encodingClass) return __CFStringEncodingPlatformUnicodeToBytes(encoding, flags, characters, numChars, usedCharLen, bytes, maxByteLen, usedByteLen);
@@ -816,7 +817,9 @@ uint32_t CFStringEncodingBytesToUnicode(uint32_t encoding, uint32_t flags, const
 
     if (!converter) return kCFStringEncodingConverterUnavailable;
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (kCFStringEncodingConverterICU == converter->definition->encodingClass) return __CFStringEncodingICUToUnicode((const char *)converter->toBytes, flags, bytes, numBytes, usedByteLen, characters, maxCharLen, usedCharLen);
+#endif
 
     /* Platform converter */
     if (kCFStringEncodingConverterPlatformSpecific == converter->definition->encodingClass) return __CFStringEncodingPlatformBytesToUnicode(encoding, flags, bytes, numBytes, usedByteLen, characters, maxCharLen, usedCharLen);
@@ -858,8 +861,10 @@ __private_extern__ CFIndex CFStringEncodingCharLengthForBytes(uint32_t encoding,
     const _CFEncodingConverter *converter = __CFGetConverter(encoding);
 
     if (converter) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         if (kCFStringEncodingConverterICU == converter->definition->encodingClass) return __CFStringEncodingICUCharLength((const char *)converter->toBytes, flags, bytes, numBytes);
-
+#endif
+        
         if (kCFStringEncodingConverterPlatformSpecific == converter->definition->encodingClass) return __CFStringEncodingPlatformCharLengthForBytes(encoding, flags, bytes, numBytes);
 
         if (1 == converter->definition->maxBytesPerChar) return numBytes;
@@ -900,7 +905,9 @@ __private_extern__ CFIndex CFStringEncodingByteLengthForCharacters(uint32_t enco
     const _CFEncodingConverter *converter = __CFGetConverter(encoding);
 
     if (converter) {
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         if (kCFStringEncodingConverterICU == converter->definition->encodingClass) return __CFStringEncodingICUByteLength((const char *)converter->toBytes, flags, characters, numChars);
+#endif
 
         if (kCFStringEncodingConverterPlatformSpecific == converter->definition->encodingClass) return __CFStringEncodingPlatformByteLengthForCharacters(encoding, flags, characters, numChars);
 
@@ -983,7 +990,11 @@ __private_extern__ const CFStringEncoding *CFStringEncodingListOfAvailableEncodi
     if (NULL == encodings) {
         CFStringEncoding *list = (CFStringEncoding *)__CFBuiltinEncodings;
         CFIndex numICUConverters = 0, numPlatformConverters = 0;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         CFStringEncoding *icuConverters = __CFStringEncodingCreateICUEncodings(NULL, &numICUConverters);
+#else
+        CFStringEncoding *icuConverters = NULL;
+#endif
         CFStringEncoding *platformConverters = __CFStringEncodingCreateListOfAvailablePlatformConverters(NULL, &numPlatformConverters);
 
         if ((NULL != icuConverters) || (NULL != platformConverters)) {
index 921245d0a074187519282b24e81c74302410b196..ea1f9eca7d86e614f41f7c284c1b531c415ac296 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverter.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERTER__)
index 89bfd110271f4e74bffa6a9b5b0f3e204b8c76b4..9c1328ff3333f9d28c9ea7c4ee4b82f602d99e40 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverterExt.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERETEREXT__)
index af1ddfc7a742cb54de9c143599b63561e5ef6929..91a5ed11c9f2ac80394c6453904a853499f4374a 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingConverterPriv.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGCONVERTERPRIV__)
index 064e830bb078c738a00c11fa03d8b511142313c1..50116da51a6b97a5763813100ab8c8367f2c382e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingDatabase.c
-       Copyright (c) 2005-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2005-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
index 525edaf686e9f0f2dced1365676425417af56765..c8f334eb7aaeeb9ef0f750b72cd2aa5d427236b2 100644 (file)
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by Aki Inoue on 07/12/05.
- *  Copyright (c) 2007-2011, Apple Inc. All rights reserved.
+ *  Copyright (c) 2007-2012, Apple Inc. All rights reserved.
  *
  */
 
index a88bf36ebf7c48916897fe03bc00d4114c09e6c3..77fd9164a8c1c2a610ab94303d0545a9cbd94154 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodingExt.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFSTRINGENCODINGEXT__)
@@ -32,7 +32,7 @@
 
 CF_EXTERN_C_BEGIN
 
-enum {
+typedef CF_ENUM(CFIndex, CFStringEncodings) {
 /*  kCFStringEncodingMacRoman = 0L, defined in CoreFoundation/CFString.h */
     kCFStringEncodingMacJapanese = 1,
     kCFStringEncodingMacChineseTrad = 2,
@@ -144,9 +144,7 @@ enum {
     kCFStringEncodingJIS_X0208_90 = 0x0622,
     kCFStringEncodingJIS_X0212_90 = 0x0623,
     kCFStringEncodingJIS_C6226_78 = 0x0624,
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    kCFStringEncodingShiftJIS_X0213 = 0x0628, /* Shift-JIS format encoding of JIS X0213 planes 1 and 2*/
-#endif
+    kCFStringEncodingShiftJIS_X0213 CF_ENUM_AVAILABLE(10_5, 2_0) = 0x0628, /* Shift-JIS format encoding of JIS X0213 planes 1 and 2*/
     kCFStringEncodingShiftJIS_X0213_MenKuTen = 0x0629, /* JIS X0213 in plane-row-column notation */
     kCFStringEncodingGB_2312_80 = 0x0630,
     kCFStringEncodingGBK_95 = 0x0631,          /* annex to GB 13000-93; for Windows 95 */
@@ -191,15 +189,12 @@ enum {
     kCFStringEncodingEBCDIC_US = 0x0C01,       /* basic EBCDIC-US */
     kCFStringEncodingEBCDIC_CP037 = 0x0C02,    /* code page 037, extended EBCDIC (Latin-1 set) for US,Canada... */
 
-#if MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED
-    kCFStringEncodingUTF7 = 0x04000100, /* kTextEncodingUnicodeDefault + kUnicodeUTF7Format RFC2152 */
-    kCFStringEncodingUTF7_IMAP = 0x0A10, /* UTF-7 (IMAP folder variant) RFC3501 */
-#endif /* MAC_OS_X_VERSION_10_6 <= MAC_OS_X_VERSION_MAX_ALLOWED */
+    kCFStringEncodingUTF7 CF_ENUM_AVAILABLE(10_6, 4_0) = 0x04000100, /* kTextEncodingUnicodeDefault + kUnicodeUTF7Format RFC2152 */
+    kCFStringEncodingUTF7_IMAP CF_ENUM_AVAILABLE(10_6, 4_0) = 0x0A10, /* UTF-7 (IMAP folder variant) RFC3501 */
 
     /* Deprecated constants */
     kCFStringEncodingShiftJIS_X0213_00 = 0x0628 /* Shift-JIS format encoding of JIS X0213 planes 1 and 2 (DEPRECATED) */
 };
-typedef CFIndex CFStringEncodings;
 
 CF_EXTERN_C_END
 
index 3de33661f78c524c5fd3f4bfa72fcf7f9c9141d2..f0f9db064a39fb074aa195eb563fb45e42d5afdc 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringEncodings.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
 #include <CoreFoundation/CFStringDefaultEncoding.h>
 #endif
 
-static UInt32 __CFWantsToUseASCIICompatibleConversion = (UInt32)-1;
-CF_INLINE UInt32 __CFGetASCIICompatibleFlag(void) {
-    if (__CFWantsToUseASCIICompatibleConversion == (UInt32)-1) {
-        __CFWantsToUseASCIICompatibleConversion = false;
-    }
-    return (__CFWantsToUseASCIICompatibleConversion ? kCFStringEncodingASCIICompatibleConversion : 0);
-}
+static bool __CFWantsToUseASCIICompatibleConversion = false;
+CF_INLINE UInt32 __CFGetASCIICompatibleFlag(void) { return __CFWantsToUseASCIICompatibleConversion; }
 
 void _CFStringEncodingSetForceASCIICompatibility(Boolean flag) {
     __CFWantsToUseASCIICompatibleConversion = (flag ? (UInt32)true : (UInt32)false);
@@ -232,7 +227,7 @@ Boolean __CFStringDecodeByteStream3(const uint8_t *bytes, CFIndex len, CFStringE
         bool swap = false;
         static bool strictUTF32 = (bool)-1;
 
-        if ((bool)-1 == strictUTF32) strictUTF32 = (_CFExecutableLinkedOnOrAfter(CFSystemVersionLeopard) != 0);
+        if ((bool)-1 == strictUTF32) strictUTF32 = (1 != 0);
 
         if (kCFStringEncodingUTF32 == encoding) {
             UTF32Char bom = ((*src == 0xFFFE0000) || (*src == 0x0000FEFF) ? *(src++) : 0);
index ebed16fa932b0b8ea113f996643811378b57f777..a5f16278eb7fa88d61dcd2f7e211be9da882936a 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringScanner.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Ali Ozer
 */
 
index 9d7ae352e93a610f607fd7178fc8879e00f69140..637326a5efa0c32ec5a8026975f877dc94bb9205 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFStringUtilities.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
 #include <CoreFoundation/CFStringEncodingExt.h>
 #include "CFStringEncodingDatabase.h"
 #include "CFICUConverters.h"
-#include <CoreFoundation/CFPreferences.h>
 #include <limits.h>
 #include <stdlib.h>
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #include <unicode/ucol.h>
 #include <unicode/ucoleitr.h>
+#endif
 #include <string.h>
 
 #if  DEPLOYMENT_TARGET_WINDOWS
@@ -105,8 +106,10 @@ CFStringEncoding CFStringConvertIANACharSetNameToEncoding(CFStringRef charsetNam
 
     encoding = __CFStringEncodingGetFromCanonicalName(name);
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     if (kCFStringEncodingInvalidId == encoding) encoding = __CFStringEncodingGetFromICUName(name);
-
+#endif
+    
 
     return encoding;
 }
@@ -246,6 +249,7 @@ CFStringEncoding CFStringGetMostCompatibleMacStringEncoding(CFStringEncoding enc
 
 #define kCFStringCompareAllocationIncrement (128)
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 
 // -------------------------------------------------------------------------------------------------
 //     CompareSpecials - ignore case & diacritic differences
@@ -515,6 +519,8 @@ static OSStatus __CompareTextDefault(UCollator *collator, CFOptionFlags options,
        return 0; // noErr
 }
 
+#endif // DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
+
 static inline CFIndex __extendLocationBackward(CFIndex location, CFStringInlineBuffer *str, const uint8_t *nonBaseBMP, const uint8_t *punctBMP) {
     while (location > 0) {
         UTF32Char ch = CFStringGetCharacterFromInlineBuffer(str, location);
@@ -557,11 +563,13 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
     CFRange range1 = str1Range;
     CFRange range2 = str2Range;
     SInt32 order;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
     Boolean isEqual;
     bool forcedOrdering = ((options & kCFCompareForcedOrdering) ? true : false);
 
     UCollator *collator = NULL;
     bool defaultCollator = true;
+#endif
     static const uint8_t *alnumBMP = NULL;
     static const uint8_t *nonBaseBMP = NULL;
     static const uint8_t *punctBMP = NULL;
@@ -589,6 +597,7 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
        range2.location = __extendLocationBackward(range2.location - 1, str2, nonBaseBMP, punctBMP);
     }
     
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     // First we try to use the last one used on this thread, if the locale is the same,
     // otherwise we try to check out a default one, or then we create one.
@@ -607,7 +616,8 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     }
 #endif
-
+#endif
+    
     characters1 = CFStringGetCharactersPtrFromInlineBuffer(str1, range1);
     characters2 = CFStringGetCharactersPtrFromInlineBuffer(str2, range2);
 
@@ -615,9 +625,12 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
        range1.length = (str1Range.location + str1Range.length) - range1.location;
        range2.length = (str2Range.location + str2Range.length) - range2.location;
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
         if ((NULL != collator) && (__CompareTextDefault(collator, options, characters1, range1.length, characters2, range2.length, &isEqual, &order) == 0 /* noErr */)) {
             compResult = ((isEqual && !forcedOrdering) ? kCFCompareEqualTo : ((order < 0) ? kCFCompareLessThan : kCFCompareGreaterThan));
-        } else {
+        } else 
+#endif
+        {
             compResult = ((memcmp(characters1, characters2, sizeof(UniChar) * range1.length) < 0) ? kCFCompareLessThan : kCFCompareGreaterThan);
         }
     } else {
@@ -682,12 +695,15 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
                 }
             }
 
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
             if ((NULL != collator) && (__CompareTextDefault(collator, options, characters1, range1.length, characters2, range2.length, &isEqual, &order) ==  0 /* noErr */)) {
                 if (isEqual) {
                     if (forcedOrdering && (kCFCompareEqualTo == compResult) && (0 != order)) compResult = ((order < 0) ? kCFCompareLessThan : kCFCompareGreaterThan);
                     order = 0;
                 }
-            } else {
+            } else 
+#endif
+            {
                 order = memcmp(characters1, characters2, sizeof(UTF16Char) * ((range1.length < range2.length) ? range1.length : range2.length));
                 if (0 == order) {
                     if (range1.length < range2.length) {
@@ -726,7 +742,7 @@ __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInline
        _CFSetTSD(__CFTSDKeyCollatorLocale, (void *)CFRetain(compareLocale), NULL);
     }
 #endif
-
+    
     return compResult;
 }
 
index 4bf5924ceadeae1f9efbf45f0a04ddbd8293e041..6efe1a2da537de65f909c1eae9961dc73681476e 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFSystemDirectories.c
-       Copyright (c) 1997-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1997-2012, Apple Inc. All rights reserved.
        Responsibility: Kevin Perry
 */
 
index d08737338559b026c4cb65108f7dba0502b47211..5e40803a231d944992bd6dc7205baabef6178f58 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFTimeZone.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -1124,7 +1124,7 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
        if (NULL != tzName) {
            tempURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, tzName, false);
            if (NULL != tempURL) {
-               if (_CFReadBytesFromFile(kCFAllocatorSystemDefault, tempURL, &bytes, &length, 0)) {
+               if (_CFReadBytesFromFile(kCFAllocatorSystemDefault, tempURL, &bytes, &length, 0, 0)) {
                    data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, bytes, length, kCFAllocatorSystemDefault);
                }
                CFRelease(tempURL);
@@ -1161,7 +1161,7 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
        tzName = name;
        tempURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorSystemDefault, baseURL, tzName, false);
        if (NULL != tempURL) {
-           if (_CFReadBytesFromFile(kCFAllocatorSystemDefault, tempURL, &bytes, &length, 0)) {
+           if (_CFReadBytesFromFile(kCFAllocatorSystemDefault, tempURL, &bytes, &length, 0, 0)) {
                data = CFDataCreateWithBytesNoCopy(kCFAllocatorSystemDefault, bytes, length, kCFAllocatorSystemDefault);
            }
            CFRelease(tempURL);
@@ -1183,13 +1183,13 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam
 }
 
 CFStringRef CFTimeZoneGetName(CFTimeZoneRef tz) {
-    CF_OBJC_FUNCDISPATCH0(CFTimeZoneGetTypeID(), CFStringRef, tz, "name");
+    CF_OBJC_FUNCDISPATCHV(CFTimeZoneGetTypeID(), CFStringRef, (NSTimeZone *)tz, name);
     __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     return tz->_name;
 }
 
 CFDataRef CFTimeZoneGetData(CFTimeZoneRef tz) {
-    CF_OBJC_FUNCDISPATCH0(CFTimeZoneGetTypeID(), CFDataRef, tz, "data");
+    CF_OBJC_FUNCDISPATCHV(CFTimeZoneGetTypeID(), CFDataRef, (NSTimeZone *)tz, data);
     __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     return tz->_data;
 }
@@ -1239,7 +1239,7 @@ Boolean CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz, CFAbsoluteTime at) {
 }
 
 CFTimeInterval CFTimeZoneGetDaylightSavingTimeOffset(CFTimeZoneRef tz, CFAbsoluteTime at) {
-    CF_OBJC_FUNCDISPATCH1(CFTimeZoneGetTypeID(), CFTimeInterval, tz, "_daylightSavingTimeOffsetForAbsoluteTime:", at);
+    CF_OBJC_FUNCDISPATCHV(CFTimeZoneGetTypeID(), CFTimeInterval, (NSTimeZone *)tz, _daylightSavingTimeOffsetForAbsoluteTime:at);
     __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     CFIndex idx = __CFBSearchTZPeriods(tz, at);
     if (__CFTZPeriodIsDST(&(tz->_periods[idx]))) {
@@ -1254,7 +1254,7 @@ CFTimeInterval CFTimeZoneGetDaylightSavingTimeOffset(CFTimeZoneRef tz, CFAbsolut
 }
 
 CFAbsoluteTime CFTimeZoneGetNextDaylightSavingTimeTransition(CFTimeZoneRef tz, CFAbsoluteTime at) {
-    CF_OBJC_FUNCDISPATCH1(CFTimeZoneGetTypeID(), CFTimeInterval, tz, "_nextDaylightSavingTimeTransitionAfterAbsoluteTime:", at);
+    CF_OBJC_FUNCDISPATCHV(CFTimeZoneGetTypeID(), CFTimeInterval, (NSTimeZone *)tz, _nextDaylightSavingTimeTransitionAfterAbsoluteTime:at);
     __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     CFIndex idx = __CFBSearchTZPeriods(tz, at);
     if (tz->_periodCnt <= idx + 1) {
@@ -1268,7 +1268,7 @@ extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRe
 #define BUFFER_SIZE 768
 
 CFStringRef CFTimeZoneCopyLocalizedName(CFTimeZoneRef tz, CFTimeZoneNameStyle style, CFLocaleRef locale) {
-    CF_OBJC_FUNCDISPATCH2(CFTimeZoneGetTypeID(), CFStringRef, tz, "localizedName:locale:", style, locale);
+    CF_OBJC_FUNCDISPATCHV(CFTimeZoneGetTypeID(), CFStringRef, (NSTimeZone *)tz, localizedName:(NSTimeZoneNameStyle)style locale:(NSLocale *)locale);
     __CFGenericValidateType(tz, CFTimeZoneGetTypeID());
     __CFGenericValidateType(locale, CFLocaleGetTypeID());
 
index f42152d4fbaa194ae73db44a64f6909fb65eaf84..c30f7c79f8689d5cbfd25862a0519ae17c9056d1 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFTimeZone.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFTIMEZONE__)
@@ -35,6 +35,7 @@
 #include <CoreFoundation/CFDictionary.h>
 #include <CoreFoundation/CFString.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 CF_EXPORT
@@ -91,17 +92,14 @@ CFTimeInterval CFTimeZoneGetDaylightSavingTimeOffset(CFTimeZoneRef tz, CFAbsolut
 CF_EXPORT
 CFAbsoluteTime CFTimeZoneGetNextDaylightSavingTimeTransition(CFTimeZoneRef tz, CFAbsoluteTime at) CF_AVAILABLE(10_5, 2_0);
 
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
-enum {
+typedef CF_ENUM(CFIndex, CFTimeZoneNameStyle) {
        kCFTimeZoneNameStyleStandard,
        kCFTimeZoneNameStyleShortStandard,
        kCFTimeZoneNameStyleDaylightSaving,
        kCFTimeZoneNameStyleShortDaylightSaving,
        kCFTimeZoneNameStyleGeneric,
        kCFTimeZoneNameStyleShortGeneric
-};
-#endif
-typedef CFIndex CFTimeZoneNameStyle;
+} CF_ENUM_AVAILABLE(10_5, 2_0);
 
 CF_EXPORT
 CFStringRef CFTimeZoneCopyLocalizedName(CFTimeZoneRef tz, CFTimeZoneNameStyle style, CFLocaleRef locale) CF_AVAILABLE(10_5, 2_0);
@@ -110,6 +108,7 @@ CF_EXPORT
 const CFStringRef kCFTimeZoneSystemTimeZoneDidChangeNotification CF_AVAILABLE(10_5, 2_0);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFTIMEZONE__ */
 
index d6c6fb188de11ea5e0edb2a53f39b92e5b759e73..dd08b99edcafe0ce40bbd1d86afbff0d6c13c653 100644 (file)
--- a/CFTree.c
+++ b/CFTree.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFTree.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Christopher Kane
 */
 
@@ -105,11 +105,13 @@ static CFStringRef __CFTreeCopyDescription(CFTypeRef cf) {
 static void __CFTreeDeallocate(CFTypeRef cf) {
     CFTreeRef tree = (CFTreeRef)cf;
     const struct __CFTreeCallBacks *cb;
+#if DEPLOYMENT_TARGET_MACOSX
     CFAllocatorRef allocator = __CFGetAllocator(tree);
     if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
         // GC:  keep the tree intact during finalization.
         CFTreeRemoveAllChildren(tree);
     }
+#endif
     cb = __CFTreeGetCallBacks(tree);
     if (NULL != cb->release) {
         INVOKE_CALLBACK1(cb->release, tree->_info);
index 49a9c3dc5441724aa7a9dc9da44e45029b10b37a..277eb1f97e64a9c066c3d73e51b40d11af3e6f03 100644 (file)
--- a/CFTree.h
+++ b/CFTree.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFTree.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 /*!
         @header CFTree
@@ -35,6 +35,7 @@
 
 #include <CoreFoundation/CFBase.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 /*!
@@ -342,6 +343,7 @@ CF_EXPORT
 void CFTreeSortChildren(CFTreeRef tree, CFComparatorFunction comparator, void *context);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFTREE__ */
 
diff --git a/CFURL.c b/CFURL.c
index d8fc4ca3e30ad4bcf58bed9b79f7f357c02adffd..b15658c85552f6fe0d1b4fab705f8aea4c8abb5a 100644 (file)
--- a/CFURL.c
+++ b/CFURL.c
@@ -22,7 +22,7 @@
  */
 
 /*     CFURL.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: John Iarocci
 */
 
@@ -36,7 +36,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#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 DEPLOYMENT_TARGET_MACOSX
 #include <CoreFoundation/CFNumberFormatter.h>
 #endif
 #include <CoreFoundation/CFURLPriv.h>
 #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);
 #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);
 CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLRef anURL, CFURLPathStyle fsType, Boolean resolveAgainstBase);
 CF_EXPORT CFURLRef _CFURLCreateCurrentDirectoryURL(CFAllocatorRef allocator);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir);
+#if DEPLOYMENT_TARGET_MACOSX
+static Boolean _CFURLHasFileURLScheme(CFURLRef url, Boolean *hasScheme);
 #endif
 
 
 
+
 #ifndef DEBUG_URL_MEMORY_USAGE
 #define DEBUG_URL_MEMORY_USAGE 0
 #endif
 
 #if DEBUG_URL_MEMORY_USAGE
-static CFAllocatorRef URLAllocator = NULL;
-static UInt32 numFileURLsCreated = 0;
-static UInt32 numFileURLsConverted = 0;
-static UInt32 numFileURLsDealloced = 0;
 static UInt32 numURLs = 0;
 static UInt32 numDealloced = 0;
+static UInt32 numFileURLsCreated = 0;
 static UInt32 numExtraDataAllocated = 0;
 static UInt32 numURLsWithBaseURL = 0;
 static UInt32 numNonUTF8EncodedURLs = 0;
 #endif
 
 /* The bit flags in myURL->_flags */
-#define HAS_SCHEME      (0x0001)
-#define HAS_USER        (0x0002)
-#define HAS_PASSWORD    (0x0004)
-#define HAS_HOST        (0x0008)
-#define HAS_PORT        (0x0010)
-#define HAS_PATH        (0x0020)
-#define HAS_PARAMETERS  (0x0040)
-#define HAS_QUERY       (0x0080)
-#define HAS_FRAGMENT    (0x0100)
-#define HAS_HTTP_SCHEME (0x0200)
-// Last free bit (0x200) in lower word goes here!
-#define IS_IPV6_ENCODED (0x0400)
-#define IS_OLD_UTF8_STYLE (0x0800)
-#define IS_DIRECTORY    (0x1000)
-#define IS_PARSED       (0x2000)
-#define IS_ABSOLUTE     (0x4000)
-#define IS_DECOMPOSABLE (0x8000)
-
-#define PATH_TYPE_MASK                 (0x000F0000)
-/* POSIX_AND_URL_PATHS_MATCH will only be true if the URL and POSIX paths are identical, character for character, except for the presence/absence of a trailing slash on directories */
-#define POSIX_AND_URL_PATHS_MATCH      (0x00100000)
-#define ORIGINAL_AND_URL_STRINGS_MATCH (0x00200000)
-
-/* If ORIGINAL_AND_URL_STRINGS_MATCH is false, these bits determine where they differ */
-// Scheme can actually never differ because if there were escaped characters prior to the colon, we'd interpret the string as a relative path
-//     #define SCHEME_DIFFERS     (0x00400000) unused
-#define USER_DIFFERS       (0x00800000)
-#define PASSWORD_DIFFERS   (0x01000000)
-#define HOST_DIFFERS       (0x02000000)
-// Port can actually never differ because if there were a non-digit following a colon in the net location, we'd interpret the whole net location as the host 
-#define PORT_DIFFERS       (0x04000000)
-//     #define PATH_DIFFERS       (0x08000000) unused
-// #define PARAMETERS_DIFFER  (0x10000000)     unused
-// #define QUERY_DIFFERS      (0x20000000)     unused
-#define PATH_HAS_FILE_ID    (0x40000000)
-#define HAS_FILE_SCHEME                (0x80000000)
-
-// Number of bits to shift to get from HAS_FOO to FOO_DIFFERS flag
-#define BIT_SHIFT_FROM_COMPONENT_TO_DIFFERS_FLAG (22)
+// component bits
+#define HAS_SCHEME                      (0x00000001)
+#define HAS_USER                        (0x00000002)
+#define HAS_PASSWORD                    (0x00000004)
+#define HAS_HOST                        (0x00000008)
+#define HAS_PORT                        (0x00000010)
+#define HAS_PATH                        (0x00000020)
+#define HAS_PARAMETERS                  (0x00000040)
+#define HAS_QUERY                       (0x00000080)
+#define HAS_FRAGMENT                    (0x00000100)
+// various boolean flags
+#define IS_IPV6_ENCODED                 (0x00000400)
+#define IS_DIRECTORY                    (0x00000800)
+#define IS_CANONICAL_FILE_URL           (0x00001000)
+#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)
+// scheme bits and amount to shift it to translate to the kXXXXScheme enums
+#define SCHEME_TYPE_MASK                (0xE0000000)
+#define SCHEME_SHIFT                    29
+enum {
+    kHasUncommonScheme  = 0,
+    kHasHttpScheme      = 1,
+    kHasHttpsScheme     = 2,
+    kHasFileScheme      = 3,
+    kHasDataScheme      = 4,
+    kHasFtpScheme       = 5,
+    kMaxScheme
+};
+// accessors for the scheme bits in _flags
+CF_INLINE UInt32 _getSchemeTypeFromFlags(UInt32 flags);
+CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType);
 
 // Other useful defines
 #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.
+// 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 )
+
+// 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)
 
-/* URL_PATH_TYPE(anURL) will be one of the CFURLPathStyle constants, in which case string is a file system path, or will be FULL_URL_REPRESENTATION, in which case the string is the full URL string. One caveat - string always has a trailing path delimiter if the url is a directory URL.  This must be stripped before returning file system representations!  */
-#define URL_PATH_TYPE(url) (((url->_flags) & PATH_TYPE_MASK) >> 16)
-#define PATH_DELIM_FOR_TYPE(fsType) ((fsType) == kCFURLHFSPathStyle ? ':' : (((fsType) == kCFURLWindowsPathStyle) ? '\\' : '/'))
-#define PATH_DELIM_AS_STRING_FOR_TYPE(fsType) ((fsType) == kCFURLHFSPathStyle ? CFSTR(":") : (((fsType) == kCFURLWindowsPathStyle) ? CFSTR("\\") : CFSTR("/")))
+/* The bit flags in _CFURLAdditionalData->_additionalDataFlags */
+/* If ORIGINAL_AND_URL_STRINGS_MATCH in myURL->_flags is false, these bits determine where they differ. XXXX_DIFFERS must match the HAS_XXXX */
+#define SCHEME_DIFFERS                  HAS_SCHEME      // Scheme can actually never differ because if there were escaped characters prior to the colon, we'd interpret the string as a relative path
+#define USER_DIFFERS                    HAS_USER
+#define PASSWORD_DIFFERS                HAS_PASSWORD
+#define HOST_DIFFERS                    HAS_HOST
+#define PORT_DIFFERS                    HAS_PORT        // Port can actually never differ because if there were a non-digit following a colon in the net location, we'd interpret the whole net location as the host 
+#define PATH_DIFFERS                    HAS_PATH        // unused
+#define PARAMETERS_DIFFER               HAS_PARAMETERS  // unused
+#define QUERY_DIFFER                    HAS_QUERY       // unused
+#define FRAGMENT_DIFFER                 HAS_FRAGMENT    // unused
 
 #define FILE_ID_PREFIX ".file"
 #define FILE_ID_KEY "id"
 #define FILE_ID_PREAMBLE "/.file/id="
 #define FILE_ID_PREAMBLE_LENGTH 10
 
-#define ASSERT_CHECK_PATHSTYLE(x) 0
-
-#if DEPLOYMENT_TARGET_WINDOWS
-#define PATH_SEP '\\'
-#define PATH_MAX MAX_PATH
-#else
-#define PATH_SEP '/'
-#endif
+#define FILE_PREFIX "file://"
+#define FILE_PREFIX_WITH_AUTHORITY "file://localhost"
+static const UInt8 fileURLPrefixWithAuthority[] = FILE_PREFIX_WITH_AUTHORITY;
 
 //     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.
 struct _CFURLAdditionalData {
     void *_reserved; // Reserved for URLHandle's use.
-    CFMutableStringRef _sanitizedString; // The fully compliant RFC string.  This is only non-NULL if ORIGINAL_AND_URL_STRINGS_MATCH is false.  This should never be mutated except when the sanatized string is first computed
-    CFHashCode hashValue;
+    CFStringRef _sanitizedString; // The fully compliant RFC string.  This is only non-NULL if ORIGINAL_AND_URL_STRINGS_MATCH is false.
+    UInt32 _additionalDataFlags; // these flags only apply to things we need to keep state for in _CFURLAdditionalData (like the XXXX_DIFFERS flags)
 };
 
 struct __CFURL {
     CFRuntimeBase _cfBase;
     UInt32 _flags;
-    CFStringEncoding _encoding; // The encoding to use when asked to remove percent escapes; this is never consulted if IS_OLD_UTF8_STYLE is set.
-    CFStringRef _string; // Never NULL; the meaning of _string depends on URL_PATH_TYPE(myURL) (see above)
+    CFStringEncoding _encoding; // The encoding to use when asked to remove percent escapes
+    CFStringRef _string; // Never NULL
     CFURLRef _base;
-    CFRange *ranges;
-    struct _CFURLAdditionalData* extra;
+    CFRange *_ranges;
+    struct _CFURLAdditionalData* _extra;
     void *_resourceInfo;    // For use by CarbonCore to cache property values. Retained and released by CFURL.
 };
 
 
 CF_INLINE void* _getReserved ( const struct __CFURL* url )
 {
-       if ( url && url->extra )
-                       return url->extra->_reserved;
-
-       return NULL;
+    if ( url && url->_extra ) {
+        return ( url->_extra->_reserved );
+    }
+    else {
+        return ( NULL );
+    }
 }
 
-CF_INLINE CFMutableStringRef _getSanitizedString ( const struct __CFURL* url )
+CF_INLINE CFStringRef _getSanitizedString(const struct __CFURL* url)
 {
-       if ( url && url->extra )
-               return url->extra->_sanitizedString;
+    if ( url && url->_extra ) {
+        return ( url->_extra->_sanitizedString );
+    }
+    else {
+       return ( NULL );
+    }
+}
 
-       return NULL;
+CF_INLINE UInt32 _getAdditionalDataFlags(const struct __CFURL* url)
+{
+    if ( url && url->_extra ) {
+        return ( url->_extra->_additionalDataFlags );
+    }
+    else {
+       return ( 0 );
+    }
 }
 
-static void* _getResourceInfo ( const struct __CFURL* url )
+CF_INLINE void* _getResourceInfo ( const struct __CFURL* url )
 {
     if ( url ) {
         return url->_resourceInfo;
     }
-
-    return NULL;
+    else {
+        return NULL;
+    }
 }
 
 static void _CFURLAllocateExtraDataspace( struct __CFURL* url )
 {      
-    if ( url && ! url->extra )
+    if ( url && ! url->_extra )
     {  struct _CFURLAdditionalData* extra = (struct _CFURLAdditionalData*) CFAllocatorAllocate( CFGetAllocator( url), sizeof( struct _CFURLAdditionalData ), __kCFAllocatorGCScannedMemory);
        
        extra->_reserved = _getReserved( url );
-       extra->_sanitizedString = _getSanitizedString( url );
-       extra->hashValue = 0;
+        extra->_additionalDataFlags = _getAdditionalDataFlags(url);
+       extra->_sanitizedString = _getSanitizedString(url);
        
-       url->extra = extra;
+       url->_extra = extra;
        
        #if DEBUG_URL_MEMORY_USAGE
        numExtraDataAllocated ++;
@@ -206,31 +226,52 @@ static void _CFURLAllocateExtraDataspace( struct __CFURL* url )
 
 CF_INLINE void _setReserved ( struct __CFURL* url, void* reserved )
 {
-       if ( url )
-       {
-               //      Don't allocate extra space if we're just going to be storing NULL
-               if ( ! url->extra && reserved )
-                       _CFURLAllocateExtraDataspace( url );
-               
-               if ( url->extra )
-                       __CFAssignWithWriteBarrier((void **)&url->extra->_reserved, reserved);
-       }
+    if ( url )
+    {
+        // Don't allocate extra space if we're just going to be storing NULL
+        if ( !url->_extra && reserved )
+            _CFURLAllocateExtraDataspace( url );
+        
+        if ( url->_extra )
+            __CFAssignWithWriteBarrier((void **)&url->_extra->_reserved, reserved);
+    }
 }
 
-CF_INLINE void _setSanitizedString ( struct __CFURL* url, CFMutableStringRef sanitizedString )
+CF_INLINE void _setSanitizedString( struct __CFURL* url, CFMutableStringRef sanitizedString )
 {
-       if ( url )
-       {
-               //      Don't allocate extra space if we're just going to be storing NULL
-               if ( ! url->extra && sanitizedString )
-                       _CFURLAllocateExtraDataspace( url );
-               
-               if ( url->extra )
-                       url->extra->_sanitizedString = sanitizedString;
-       }
+    if ( url )
+    {
+        // Don't allocate extra space if we're just going to be storing NULL
+        if ( !url->_extra && sanitizedString ) {
+            _CFURLAllocateExtraDataspace( url );
+        }
+        
+        if ( url->_extra ) {
+            if ( url->_extra->_sanitizedString ) {
+                CFRelease(url->_extra->_sanitizedString);
+            }
+            url->_extra->_sanitizedString = CFStringCreateCopy(CFGetAllocator(url), sanitizedString);
+
+        }
+    }
+}
+
+CF_INLINE void _setAdditionalDataFlags(struct __CFURL* url, UInt32 additionalDataFlags)
+{
+    if ( url )
+    {
+        // Don't allocate extra space if we're just going to be storing 0
+        if ( !url->_extra && (additionalDataFlags != 0) ) {
+            _CFURLAllocateExtraDataspace( url );
+        }
+        
+        if ( url->_extra ) {
+            url->_extra->_additionalDataFlags = additionalDataFlags;
+        }
+    }
 }
 
-static void _setResourceInfo ( struct __CFURL* url, void* resourceInfo )
+CF_INLINE void _setResourceInfo ( struct __CFURL* url, void* resourceInfo )
 {
     // Must be atomic
     // Never a GC object
@@ -239,8 +280,72 @@ static void _setResourceInfo ( struct __CFURL* url, void* resourceInfo )
     }
 }
 
-static void _convertToURLRepresentation(struct __CFURL *url);
-static CFURLRef _CFURLCopyAbsoluteFileURL(CFURLRef relativeURL);
+CF_INLINE UInt32 _getSchemeTypeFromFlags(UInt32 flags)
+{
+    return ( (flags & SCHEME_TYPE_MASK) >> SCHEME_SHIFT );
+}
+
+CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType)
+{
+    CFAssert2((schemeType >= kHasUncommonScheme) &&  (schemeType < kMaxScheme), __kCFLogAssertion, "%s(): Received bad schemeType %d", __PRETTY_FUNCTION__, 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);
@@ -253,19 +358,7 @@ static CFStringRef _resolvedPath(UniChar *pathStr, UniChar *end, UniChar pathDel
 
 
 CF_INLINE void _parseComponentsOfURL(CFURLRef url) {
-    _parseComponents(CFGetAllocator(url), url->_string, url->_base, &(((struct __CFURL *)url)->_flags), &(((struct __CFURL *)url)->ranges));
-}
-
-static Boolean _createOldUTF8StyleURLs = false;
-
-CF_INLINE Boolean createOldUTF8StyleURLs(void) {
-    return (_createOldUTF8StyleURLs);
-}
-
-// Our backdoor in case removing the UTF8 constraint for URLs creates unexpected problems.  See radar 2902530 -- REW
-CF_EXPORT
-void _CFURLCreateOnlyUTF8CompatibleURLs(Boolean createUTF8URLs) {
-    _createOldUTF8StyleURLs = createUTF8URLs;
+    _parseComponents(CFGetAllocator(url), url->_string, url->_base, &(((struct __CFURL *)url)->_flags), &(((struct __CFURL *)url)->_ranges));
 }
 
 enum {
@@ -276,124 +369,156 @@ enum {
        HEXDIGIT = 16
 };
 
-static const unsigned char sURLValidCharacters[] = {
-       /* ' '  32 */   0,
-       /* '!'  33 */   VALID | UNRESERVED | 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 ,
-       /* '+'  43 */   VALID | SCHEME | PATHVALID ,
-       /* ','  44 */   VALID | PATHVALID ,
-       /* '-'  45 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
-       /* '.'  46 */   VALID | UNRESERVED | 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 ,
-       /* ':'  58 */   VALID ,
-       /* ';'  59 */   VALID ,
-       /* '<'  60 */   0,
-       /* '='  61 */   VALID | PATHVALID ,
-       /* '>'  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 ,
-       /* '['  91 */   0,
-       /* '\'  92 */   0,
-       /* ']'  93 */   0,
-       /* '^'  94 */   0,
-       /* '_'  95 */   VALID | UNRESERVED | 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 ,
-       /* '{' 123 */   0,
-       /* '|' 124 */   0,
-       /* '}' 125 */   0,
-       /* '~' 126 */   VALID | UNRESERVED | PATHVALID ,
-       /* '' 127 */    0
+static const unsigned char sURLValidCharacters[128] = {
+    /* 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 */   VALID | UNRESERVED | 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 ,
+    /* '+'  43 */   VALID | SCHEME | PATHVALID ,
+    /* ','  44 */   VALID | PATHVALID ,
+    /* '-'  45 */   VALID | UNRESERVED | SCHEME | PATHVALID ,
+    /* '.'  46 */   VALID | UNRESERVED | 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 ,
+    /* ':'  58 */   VALID ,
+    /* ';'  59 */   VALID ,
+    /* '<'  60 */   0,
+    /* '='  61 */   VALID | PATHVALID ,
+    /* '>'  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 ,
+    /* '['  91 */   0,
+    /* '\'  92 */   0,
+    /* ']'  93 */   0,
+    /* '^'  94 */   0,
+    /* '_'  95 */   VALID | UNRESERVED | 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 ,
+    /* '{' 123 */   0,
+    /* '|' 124 */   0,
+    /* '}' 125 */   0,
+    /* '~' 126 */   VALID | UNRESERVED | PATHVALID ,
+    /* del 127 */   0,
 };
 
 CF_INLINE Boolean isURLLegalCharacter(UniChar ch) {
-       return ( ( 32 <= ch ) && ( ch <= 127 ) ) ? ( sURLValidCharacters[ ch - 32 ] & VALID ) : false;
+    return (ch <= 127) ? (sURLValidCharacters[ch] & VALID) : false;
 }
 
 CF_INLINE Boolean scheme_valid(UniChar ch) {
-       return ( ( 32 <= ch ) && ( ch <= 127 ) ) ? ( sURLValidCharacters[ ch - 32 ] & SCHEME ) : false;
+    return (ch <= 127) ? (sURLValidCharacters[ch] & SCHEME) : false;
 }
 
 // "Unreserved" as defined by RFC 2396
 CF_INLINE Boolean isUnreservedCharacter(UniChar ch) {
-       return ( ( 32 <= ch ) && ( ch <= 127 ) ) ? ( sURLValidCharacters[ ch - 32 ] & UNRESERVED ) : false;
+    return (ch <= 127) ? (sURLValidCharacters[ch] & UNRESERVED) : false;
 }
 
 CF_INLINE Boolean isPathLegalCharacter(UniChar ch) {
-       return ( ( 32 <= ch ) && ( ch <= 127 ) ) ? ( sURLValidCharacters[ ch - 32 ] & PATHVALID ) : false;
+    return (ch <= 127) ? (sURLValidCharacters[ch] & PATHVALID) : false;
 }
 
 CF_INLINE Boolean isHexDigit(UniChar ch) {
-       return ( ( 32 <= ch ) && ( ch <= 127 ) ) ? ( sURLValidCharacters[ ch - 32 ] & HEXDIGIT ) : false;
+    return (ch <= 127) ? (sURLValidCharacters[ch] & HEXDIGIT) : false;
 }
 
 // Returns false if ch1 or ch2 isn't properly formatted
@@ -417,53 +542,121 @@ CF_INLINE Boolean _haveTestedOriginalString(CFURLRef url) {
     return ((url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) != 0) || (_getSanitizedString(url) != NULL);
 }
 
-typedef CFStringRef (*StringTransformation)(CFAllocatorRef, CFStringRef, CFIndex);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-static CFArrayRef copyStringArrayWithTransformation(CFArrayRef array, StringTransformation transformation) {
-    CFAllocatorRef alloc = CFGetAllocator(array);
-    CFMutableArrayRef mArray = NULL;
-    CFIndex i, c = CFArrayGetCount(array);
-    for (i = 0; i < c; i ++) {
-        CFStringRef origComp = (CFStringRef)CFArrayGetValueAtIndex(array, i);
-        CFStringRef unescapedComp = transformation(alloc, origComp, i);
-        if (!unescapedComp) { 
-            break;
+/*
+ CreateStringFromFileSystemRepresentationByAddingPercentEscapes creates a CFString
+ for the path-absolute form of a URI path component 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 CreateStringFromFileSystemRepresentationByAddingPercentEscapes(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, Boolean windowsPath)
+{
+    static const UInt8 hexchars[] = "0123456789ABCDEF";
+    STACK_BUFFER_DECL(UInt8, stackBuf, PATH_MAX * 3);   // worst case is every byte needs to be percent-escaped
+    UInt8 *bufStartPtr;
+    UInt8 *bufBytePtr;
+    const UInt8 *bytePtr = bytes;
+    CFIndex idx;
+    CFStringRef result;
+   
+    // 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);
+    }
+    
+    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
+                    *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;
+            }
+            ++bytePtr;
         }
-        if (unescapedComp != origComp) {
-            if (!mArray) {
-                mArray = CFArrayCreateMutableCopy(alloc, c, array);
+        
+        // did we convert numBytes?
+        if ( idx == numBytes ) {
+            // create the result
+            result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), kCFStringEncodingUTF8, FALSE);
+        }
+        else {
+            // 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 ) {
+                // do nothing
+            }
+            if ( idx == numBytes ) {
+                // create the result
+                result = CFStringCreateWithBytes(alloc, bufStartPtr, (CFIndex)(bufBytePtr-bufStartPtr), kCFStringEncodingUTF8, FALSE);
+            }
+            else {
+                // the remaining bytes were not all nul
+                result = NULL;
             }
-            CFArraySetValueAtIndex(mArray, i, unescapedComp);
         }
-        CFRelease(unescapedComp);
+        
+        // free the buffer if we malloc'd it
+        if ( bufStartPtr != &stackBuf[0] ) {
+            free(bufStartPtr);
+        }
     }
-    if (i != c) {
-        if (mArray) CFRelease(mArray);
-        return NULL;
-    } else if (mArray) {
-        return mArray;
-    } else {
-        CFRetain(array);
-        return array;
+    else {
+        result = NULL;
     }
+    return ( result );
 }
-#endif
 
 // Returns NULL if str cannot be converted for whatever reason, str if str contains no characters in need of escaping, or a newly-created string with the appropriate % escape codes in place.  Caller must always release the returned string.
 CF_INLINE CFStringRef _replacePathIllegalCharacters(CFStringRef str, CFAllocatorRef alloc, Boolean preserveSlashes) {
-    if (preserveSlashes) {
-        return CFURLCreateStringByAddingPercentEscapes(alloc, str, NULL, CFSTR(";?"), kCFStringEncodingUTF8);
-    } else {
-        return CFURLCreateStringByAddingPercentEscapes(alloc, str, NULL, CFSTR(";?/"), kCFStringEncodingUTF8);
+    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);
     }
+    return result;
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-static CFStringRef escapePathComponent(CFAllocatorRef alloc, CFStringRef origComponent, CFIndex componentIndex) {
-    return CFURLCreateStringByAddingPercentEscapes(alloc, origComponent, NULL, CFSTR(";?/"), kCFStringEncodingUTF8);
-}
-#endif
-
 // 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];
@@ -867,202 +1060,60 @@ CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef all
     strings[1] = legalURLCharactersToBeEscaped;
     return _addPercentEscapesToString(allocator, originalString, _shouldPercentReplaceChar, NULL, encoding, strings);
 }
-
-#if 0
-static Boolean __CFURLCompare(CFTypeRef  cf1, CFTypeRef  cf2) {
-    CFURLRef  url1 = (CFURLRef)cf1;
-    CFURLRef  url2 = (CFURLRef)cf2;
-    UInt32 pathType1, pathType2;
-    
-    __CFGenericValidateType(cf1, CFURLGetTypeID());
-    __CFGenericValidateType(cf2, CFURLGetTypeID());
-    
-    if (url1 == url2) return kCFCompareEqualTo;
-    
-    if ( url1->_base ) {
-        if (! url2->_base) return kCFCompareEqualTo;
-        if (!CFEqual( url1->_base, url2->_base )) return false;
-    } else if ( url2->_base) {
-        return false;
-    }
-    
-    pathType1 = URL_PATH_TYPE(url1);
-    pathType2 = URL_PATH_TYPE(url2);
-    if (pathType1 == pathType2) {
-        if (pathType1 != FULL_URL_REPRESENTATION) {
-            return CFEqual(url1->_string, url2->_string);
-        } else {
-            // Do not compare the original strings; compare the sanatized strings.
-            return CFEqual(CFURLGetString(url1), CFURLGetString(url2));
-        }
-    } else {
-        // Try hard to avoid the expensive conversion from a file system representation to the canonical form
-        CFStringRef scheme1 = CFURLCopyScheme(url1);
-        CFStringRef scheme2 = CFURLCopyScheme(url2);
-        Boolean eq;
-        if (scheme1 && scheme2) {
-            eq = CFEqual(scheme1, scheme2);
-            CFRelease(scheme1);
-            CFRelease(scheme2);
-        } else if (!scheme1 && !scheme2) {
-            eq = TRUE;
-        } else {
-            eq = FALSE;
-            if (scheme1) CFRelease(scheme1);
-            else CFRelease(scheme2);
-        }
-        if (!eq) return false;
-       
-        if (pathType1 == FULL_URL_REPRESENTATION) {
-            if (!(url1->_flags & IS_PARSED)) {
-                _parseComponentsOfURL(url1);
-            }
-            if (url1->_flags & (HAS_USER | HAS_PORT | HAS_PASSWORD | HAS_QUERY | HAS_PARAMETERS | HAS_FRAGMENT )) {
-                return false;
-            }
-        }
-       
-        if (pathType2 == FULL_URL_REPRESENTATION) {
-            if (!(url2->_flags & IS_PARSED)) {
-                _parseComponentsOfURL(url2);
-            }
-            if (url2->_flags & (HAS_USER | HAS_PORT | HAS_PASSWORD | HAS_QUERY | HAS_PARAMETERS | HAS_FRAGMENT )) {
-                return false;
-            }
-        }
-       
-        // No help for it; we now must convert to the canonical representation and compare.
-        return CFEqual(CFURLGetString(url1), CFURLGetString(url2));
-    }
-}
-#endif
 
 static Boolean __CFURLEqual(CFTypeRef  cf1, CFTypeRef  cf2) {
+    Boolean result;
     CFURLRef  url1 = (CFURLRef)cf1;
     CFURLRef  url2 = (CFURLRef)cf2;
-    UInt32 pathType1, pathType2;
     
     __CFGenericValidateType(cf1, CFURLGetTypeID());
     __CFGenericValidateType(cf2, CFURLGetTypeID());
 
-    if (url1 == url2) return true;
-    if ((url1->_flags & IS_PARSED) && (url2->_flags & IS_PARSED) && (url1->_flags & IS_DIRECTORY) != (url2->_flags & IS_DIRECTORY)) return false;
-    if ( url1->_base ) {
-        if (! url2->_base) return false;
-        if (!CFEqual( url1->_base, url2->_base )) return false;
-    } else if ( url2->_base) {
-        return false;
+    if ( url1 == url2 ) {
+        result = true;
     }
-    
-    pathType1 = URL_PATH_TYPE(url1);
-    pathType2 = URL_PATH_TYPE(url2);
-    if (pathType1 == pathType2) {
-        if (pathType1 != FULL_URL_REPRESENTATION) {
-            return CFEqual(url1->_string, url2->_string);
-        } else {
-            // Do not compare the original strings; compare the sanatized strings.
-            return CFEqual(CFURLGetString(url1), CFURLGetString(url2));
-        }
-    } else {
-        // Try hard to avoid the expensive conversion from a file system representation to the canonical form
-        CFStringRef scheme1 = CFURLCopyScheme(url1);
-        CFStringRef scheme2 = CFURLCopyScheme(url2);
-        Boolean eq;
-        if (scheme1 && scheme2) {
-            eq = CFEqual(scheme1, scheme2);
-            CFRelease(scheme1);
-            CFRelease(scheme2);
-        } else if (!scheme1 && !scheme2) {
-            eq = TRUE;
-        } else {
-            eq = FALSE;
-            if (scheme1) CFRelease(scheme1);
-            else CFRelease(scheme2);
-        }
-        if (!eq) return false;
-
-        if (pathType1 == FULL_URL_REPRESENTATION) {
-            if (!(url1->_flags & IS_PARSED)) {
-                _parseComponentsOfURL(url1);
-            }
-            if (url1->_flags & (HAS_USER | HAS_PORT | HAS_PASSWORD | HAS_QUERY | HAS_PARAMETERS | HAS_FRAGMENT )) {
-                return false;
-            }
+    else {
+        if ( (url1->_flags & EQUAL_FLAGS_MASK) != (url2->_flags & EQUAL_FLAGS_MASK) ) {
+            result = false;
         }
-
-        if (pathType2 == FULL_URL_REPRESENTATION) {
-            if (!(url2->_flags & IS_PARSED)) {
-                _parseComponentsOfURL(url2);
+        else {
+            if ( (url1->_base && !url2->_base) ||
+                (!url1->_base && url2->_base) ||
+                (url1->_base && url2->_base && !CFEqual(url1->_base, url2->_base)) ) {
+                result = false;
             }
-            if (url2->_flags & (HAS_USER | HAS_PORT | HAS_PASSWORD | HAS_QUERY | HAS_PARAMETERS | HAS_FRAGMENT )) {
-                return false;
+            else {
+                // no base urls, so compare the URL strings
+                // Do not compare the original strings; compare the sanatized strings.
+                result = CFEqual(CFURLGetString(url1), CFURLGetString(url2));
             }
         }
-
-        // No help for it; we now must convert to the canonical representation and compare.
-        return CFEqual(CFURLGetString(url1), CFURLGetString(url2));
     }
+    return ( result ) ;
 }
 
-static CFHashCode __CFURLHash(CFTypeRef  cf) {
-    /* This is tricky, because we do not want the hash value to change as a file system URL is changed to its canonical representation, nor do we wish to force the conversion to the canonical representation. We choose instead to take the last path component (or "/" in the unlikely case that the path is empty), then hash on that. */
-    struct __CFURL*  url = (struct __CFURL*)cf;
-    CFHashCode result = 0;
+static CFHashCode __CFURLHash(CFTypeRef cf)
+{
+    CFHashCode result;
     
-    if ( url )
-    {
-       //  Allocate our extra space if it isn't already allocated
-       if ( url && ! url->extra )
-           _CFURLAllocateExtraDataspace( url );
-       
-       if ( url->extra ) {
-           result = url->extra->hashValue;
-           
-           if ( ! result ) {
-               if (CFURLCanBeDecomposed(url)) {
-                   CFStringRef lastComp = CFURLCopyLastPathComponent(url);
-                   CFStringRef hostNameRef = CFURLCopyHostName(url );
-                   
-                   result = 0;
-                   
-                   if (lastComp) {
-                       result = CFHash(lastComp);
-                       CFRelease(lastComp);
-                   }
-                   
-                   if ( hostNameRef ) {
-                       result ^= CFHash( hostNameRef );
-                       CFRelease( hostNameRef );
-                   }
-               } else {
-                   result = CFHash(CFURLGetString(url));
-               }
-               
-               if ( ! result )     //  never store a 0 value for the hashed value
-                   result = 1;
-               
-               url->extra->hashValue = result;
-           }
-       }
+    if ( cf ) {
+        // use the CFHashCode of the URL
+        result = CFHash(CFURLGetString((CFURLRef)cf));
+    }
+    else {
+        // no object, no hashcode
+        result = 0;
     }
     
-    return result;
+    return ( result );
 }
 
 static CFStringRef  __CFURLCopyFormattingDescription(CFTypeRef  cf, CFDictionaryRef formatOptions) {
     CFURLRef  url = (CFURLRef)cf;
     __CFGenericValidateType(cf, CFURLGetTypeID());
     if (! url->_base) {
-#if DEPLOYMENT_TARGET_MACOSX
-        {
-            CFRetain(url->_string);
-            return url->_string;
-        }
-#else
         CFRetain(url->_string);
         return url->_string;
-#endif
     } else {
         // Do not dereference url->_base; it may be an ObjC object
         return CFStringCreateWithFormat(CFGetAllocator(url), NULL, CFSTR("%@ -- %@"), url->_string, url->_base);
@@ -1076,10 +1127,10 @@ static CFStringRef __CFURLCopyDescription(CFTypeRef cf) {
     CFAllocatorRef alloc = CFGetAllocator(url);
     if ( url->_base) {
         CFStringRef baseString = CFCopyDescription(url->_base);
-        result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{type = %d, string = %@, encoding = %d\n\tbase = %@}"), cf, alloc, URL_PATH_TYPE(url), url->_string, url->_encoding, baseString);
+        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]>{type = %d, string = %@, encoding = %d, base = (null)}"), cf, alloc, URL_PATH_TYPE(url), url->_string, url->_encoding);
+        result = CFStringCreateWithFormat(alloc, NULL, CFSTR("<CFURL %p [%p]>{string = %@, encoding = %d, base = (null)}"), cf, alloc, url->_string, url->_encoding);
     }
     return result;
 }
@@ -1087,10 +1138,9 @@ static CFStringRef __CFURLCopyDescription(CFTypeRef cf) {
 #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 converted; %d destroyed.  %d urls had 'extra' data allocated, %d had base urls, %d were not UTF8 encoded\n"), numURLs, numDealloced, numFileURLsCreated, numFileURLsConverted, numFileURLsDealloced, numExtraDataAllocated, numURLsWithBaseURL, numNonUTF8EncodedURLs );
+    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);
-    // if (URLAllocator) CFCountingAllocatorPrintPointers(URLAllocator);
 }
 #endif
 
@@ -1101,43 +1151,47 @@ static void __CFURLDeallocate(CFTypeRef  cf) {
     alloc = CFGetAllocator(url);
 #if DEBUG_URL_MEMORY_USAGE
     numDealloced ++;
-    if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-        numFileURLsDealloced ++;
-    }
 #endif
     if (url->_string) CFRelease(url->_string); // GC: 3879914
     if (url->_base) CFRelease(url->_base);
-    if (url->ranges) CFAllocatorDeallocate(alloc, url->ranges);
-    if (_getSanitizedString(url)) CFRelease(_getSanitizedString(url));
-    if ( url->extra != NULL ) CFAllocatorDeallocate( alloc, url->extra );
+    if (url->_ranges) CFAllocatorDeallocate(alloc, url->_ranges);
+    CFStringRef sanitizedString = _getSanitizedString(url);
+    if (sanitizedString) CFRelease(sanitizedString);
+    if ( url->_extra != NULL ) CFAllocatorDeallocate( alloc, url->_extra );
     if (_getResourceInfo(url)) CFRelease(_getResourceInfo(url));
 }
 
 static CFTypeID __kCFURLTypeID = _kCFRuntimeNotATypeID;
 
 static const CFRuntimeClass __CFURLClass = {
-    0,
-    "CFURL",
-    NULL,      // init
-    NULL,      // copy
-    __CFURLDeallocate,
-    __CFURLEqual,
-    __CFURLHash,
-    __CFURLCopyFormattingDescription,
-    __CFURLCopyDescription
+    0,                                  // version
+    "CFURL",                            // className
+    NULL,                               // init
+    NULL,                               // copy
+    __CFURLDeallocate,                  // finalize
+    __CFURLEqual,                       // equal
+    __CFURLHash,                        // hash
+    __CFURLCopyFormattingDescription,   // copyFormattingDesc
+    __CFURLCopyDescription,             // copyDebugDesc
+    NULL,                               // reclaim
+    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(kCFURLHTTPScheme, "http")
+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(kCFURLHTTPScheme, "http")
+CONST_STRING_DECL(kCFURLFTPScheme, "ftp")
 CONST_STRING_DECL(kCFURLLocalhost, "localhost")
 #endif
 __private_extern__ void __CFURLInitialize(void) {
@@ -1146,7 +1200,7 @@ __private_extern__ void __CFURLInitialize(void) {
 
 /* Toll-free bridging support; get the true CFURL from an NSURL */
 CF_INLINE CFURLRef _CFURLFromNSURL(CFURLRef url) {
-    CF_OBJC_FUNCDISPATCH0(__kCFURLTypeID, CFURLRef, url, "_cfurl");
+    CF_OBJC_FUNCDISPATCHV(__kCFURLTypeID, CFURLRef, (NSURL *)url, _cfurl);
     return url;
 }
 
@@ -1164,23 +1218,6 @@ __private_extern__ void CFShowURL(CFURLRef url) {
         fprintf(stdout, "ObjC bridged object}\n");
         return;
     }
-    fprintf(stdout, "\n\tPath type: ");
-    switch (URL_PATH_TYPE(url)) {
-        case kCFURLPOSIXPathStyle:
-            fprintf(stdout, "POSIX");
-            break;
-        case kCFURLHFSPathStyle:
-            fprintf(stdout, "HFS");
-            break;
-        case kCFURLWindowsPathStyle:
-            fprintf(stdout, "NTFS");
-            break;
-        case FULL_URL_REPRESENTATION:
-            fprintf(stdout, "Native URL");
-            break;
-        default:
-            fprintf(stdout, "UNRECOGNIZED PATH TYPE %d", (char)URL_PATH_TYPE(url));
-    }
     fprintf(stdout, "\n\tRelative string: ");
     CFShow(url->_string);
     fprintf(stdout, "\tBase URL: ");
@@ -1197,12 +1234,12 @@ __private_extern__ void CFShowURL(CFURLRef url) {
 /***************************************************/
 /* URL creation and String/Data creation from URLS */
 /***************************************************/
-static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, const char **cstring, const UniChar **ustring, Boolean *useCString, Boolean *freeCharacters) {
+static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, Boolean useEightBitStringEncoding, UInt8 *inBuffer, CFIndex inBufferSize, const char **cstring, const UniChar **ustring, Boolean *useCString, Boolean *freeCharacters) {
     CFIndex neededLength;
     CFIndex length;
     CFRange rg;
 
-    *cstring = CFStringGetCStringPtr(string, kCFStringEncodingISOLatin1);
+    *cstring = CFStringGetCStringPtr(string, (useEightBitStringEncoding ? __CFStringGetEightBitStringEncoding() : kCFStringEncodingISOLatin1));
     if (*cstring) {
         *ustring = NULL;
         *useCString = true;
@@ -1217,20 +1254,35 @@ static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, const cha
         return;
     } 
 
-    *freeCharacters = true;
     length = CFStringGetLength(string);
     rg = CFRangeMake(0, length);
     CFStringGetBytes(string, rg, kCFStringEncodingISOLatin1, 0, false, NULL, INT_MAX, &neededLength);
     if (neededLength == length) {
-        char *buf = (char *)CFAllocatorAllocate(alloc, length, 0);
+        char *buf;
+        if ( (inBuffer != NULL) && (length <= inBufferSize) ) {
+            buf = (char *)inBuffer;
+            *freeCharacters = false;
+        }
+        else {
+            buf = (char *)CFAllocatorAllocate(alloc, length, 0);
+            *freeCharacters = true;
+        }
         CFStringGetBytes(string, rg, kCFStringEncodingISOLatin1, 0, false, (uint8_t *)buf, length, NULL);
         *cstring = buf;
         *useCString = true;
     } else {
-        UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, length * sizeof(UniChar), 0);
+        UniChar *buf;
+        if ( (inBuffer != NULL) && ((length * sizeof(UniChar)) <= inBufferSize) ) {
+            buf = (UniChar *)inBuffer;
+            *freeCharacters = false;
+        }
+        else {
+            buf = (UniChar *)CFAllocatorAllocate(alloc, length * sizeof(UniChar), 0);
+            *freeCharacters = true;
+        }
         CFStringGetCharacters(string, rg, buf);
-        *useCString = false;
         *ustring = buf;
+        *useCString = false;
     }
 }
 
@@ -1241,14 +1293,17 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef
 
     CFIndex idx, base_idx = 0;
     CFIndex string_length;
-    UInt32 flags = (IS_PARSED | *theFlags);
+    UInt32 flags = *theFlags;
+    Boolean useEightBitStringEncoding = (flags & USES_EIGHTBITSTRINGENCODING) != 0;
     Boolean useCString, freeCharacters, isCompliant;
     uint8_t numRanges = 0;
     const char *cstring = NULL;
     const UniChar *ustring = NULL;
+    CFIndex stackBufferSize = 4096;
+    STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize);
     
     string_length = CFStringGetLength(string);
-    constructBuffers(alloc, string, &cstring, &ustring, &useCString, &freeCharacters);
+    constructBuffers(alloc, string, useEightBitStringEncoding, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters);
     
     // Algorithm is as described in RFC 1808
     // 1: parse the fragment; remainder after left-most "#" is fragment
@@ -1272,13 +1327,27 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef
             ranges[0].length = idx;
             numRanges ++;
             base_idx = idx + 1;
-            // optimization for http urls
-            if (idx == 4 && STRING_CHAR(0) == 'h' && STRING_CHAR(1) == 't' && STRING_CHAR(2) == 't' && STRING_CHAR(3) == 'p') {
-               flags |= HAS_HTTP_SCHEME;
+            // 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 file urls
-            if (idx == 4 && STRING_CHAR(0) == 'f' && STRING_CHAR(1) == 'i' && STRING_CHAR(2) == 'l' && STRING_CHAR(3) == 'e') {
-                flags |= HAS_FILE_SCHEME;
+            // 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)) {
@@ -1431,7 +1500,7 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef
                     break;
                 }
             }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#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) {
@@ -1441,8 +1510,6 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef
             if (!sawPercent) {
                 flags |= POSIX_AND_URL_PATHS_MATCH;
             }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
             ch = STRING_CHAR(pathRg.location + pathRg.length - 1);
@@ -1507,24 +1574,24 @@ static Boolean scanCharacters(CFAllocatorRef alloc, CFMutableStringRef *escapedS
         } else {
             shouldEscape = true;
         }
-        if (!shouldEscape) continue;
-        
-        sawIllegalChar = true;
-        if (componentFlag && flags) {
-            *flags |= (componentFlag << BIT_SHIFT_FROM_COMPONENT_TO_DIFFERS_FLAG);
-        }
-        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);
+        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
         }
-        *mark = idx + 1;
-        _appendPercentEscapesForCharacter(ch, encoding, *escapedString); // This can never fail because anURL->_string was constructed from the encoding passed in
     }
     return sawIllegalChar;
 } 
@@ -1537,48 +1604,53 @@ static void computeSanitizedString(CFURLRef url) {
     const UniChar *ustring = NULL;
     CFIndex base; // where to scan from
     CFIndex mark; // first character not-yet copied to sanitized string
-    if (!(url->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(url);
-    }
-    constructBuffers(alloc, url->_string, &cstring, &ustring, &useCString, &freeCharacters);
+    CFIndex stackBufferSize = 4096;
+    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);
     if (!(url->_flags & IS_DECOMPOSABLE)) {
         // Impossible to have a problem character in the scheme
-               CFMutableStringRef      sanitizedString = NULL;
-        base = _rangeForComponent(url->_flags, url->ranges, HAS_SCHEME).length + 1;
+        base = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME).length + 1;
         mark = 0;
-        if (!scanCharacters(alloc, & sanitizedString, &(((struct __CFURL *)url)->_flags), cstring, ustring, useCString, base, string_length, &mark, 0, url->_encoding)) {
+        if (!scanCharacters(alloc, &sanitizedString, &additionalDataFlags, cstring, ustring, useCString, base, string_length, &mark, 0, url->_encoding)) {
             ((struct __CFURL *)url)->_flags |= ORIGINAL_AND_URL_STRINGS_MATCH;
         }
         if ( sanitizedString ) {
-            _setSanitizedString( (struct __CFURL*) url, sanitizedString );
+            _setAdditionalDataFlags((struct __CFURL*)url, additionalDataFlags);
         }
     } else {
         // Go component by component
         CFIndex currentComponent = HAS_USER;
-        CFMutableStringRef sanitizedString = NULL;
         mark = 0;
         while (currentComponent < (HAS_FRAGMENT << 1)) {
-            CFRange componentRange = _rangeForComponent(url->_flags, url->ranges, currentComponent);
+            CFRange componentRange = _rangeForComponent(url->_flags, url->_ranges, currentComponent);
             if (componentRange.location != kCFNotFound) {
-                scanCharacters(alloc, & sanitizedString, &(((struct __CFURL *)url)->_flags), 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;
         }
         if (sanitizedString) {
-            _setSanitizedString((struct __CFURL *)url, sanitizedString);
+            _setAdditionalDataFlags((struct __CFURL*)url, additionalDataFlags);
         } else {
             ((struct __CFURL *)url)->_flags |= ORIGINAL_AND_URL_STRINGS_MATCH;
         }
     }
-    if (_getSanitizedString(url) && mark != string_length) {
+    if (sanitizedString && mark != string_length) {
         if (useCString) {
             CFStringRef tempString = CFStringCreateWithBytes(alloc, (uint8_t *)&(cstring[mark]), string_length - mark, kCFStringEncodingISOLatin1, false);
-            CFStringAppend(_getSanitizedString(url), tempString);
+            CFStringAppend(sanitizedString, tempString);
             CFRelease(tempString);
         } else {
-            CFStringAppendCharacters(_getSanitizedString(url), &(ustring[mark]), string_length - mark);
+            CFStringAppendCharacters(sanitizedString, &(ustring[mark]), string_length - mark);
         }
     }
+    if ( sanitizedString ) {
+        _setSanitizedString((struct __CFURL*) url, sanitizedString);
+        CFRelease(sanitizedString);
+    }
     if (freeCharacters) {
         CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring);
     }
@@ -1593,8 +1665,10 @@ static CFStringRef correctedComponent(CFStringRef comp, UInt32 compFlag, CFStrin
     const UniChar *ustring = NULL;
     CFIndex mark = 0; // first character not-yet copied to sanitized string
     CFMutableStringRef result = NULL;
+    CFIndex stackBufferSize = 1024;
+    STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize);
 
-    constructBuffers(alloc, comp, &cstring, &ustring, &useCString, &freeCharacters);
+    constructBuffers(alloc, comp, false, 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) {
@@ -1622,57 +1696,46 @@ CF_EXPORT CFURLRef _CFURLAlloc(CFAllocatorRef allocator) {
     struct __CFURL *url;
 #if DEBUG_URL_MEMORY_USAGE
     numURLs ++;
-    // if (!URLAllocator) {
-       // URLAllocator = CFCountingAllocatorCreate(NULL);
-    // }
-    allocator = URLAllocator;
 #endif
     url = (struct __CFURL *)_CFRuntimeCreateInstance(allocator, __kCFURLTypeID, sizeof(struct __CFURL) - sizeof(CFRuntimeBase), NULL);
     if (url) {
        url->_flags = 0;
-       if (createOldUTF8StyleURLs()) {
-           url->_flags |= IS_OLD_UTF8_STYLE;
-       }
        url->_encoding = kCFStringEncodingUTF8;
        url->_string = NULL;
        url->_base = NULL;
-       url->ranges = NULL;
-       url->extra = NULL;
+       url->_ranges = NULL;
+       url->_extra = NULL;
        url->_resourceInfo = NULL;
-       // url->_reserved = NULL;
-       // url->_sanatizedString = NULL;
     }
     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) || ASSERT_CHECK_PATHSTYLE(fsType), __kCFLogAssertion, "%s(): Received bad fsType %d", __PRETTY_FUNCTION__, fsType);
+    CFAssert2((fsType == FULL_URL_REPRESENTATION) || (fsType == kCFURLPOSIXPathStyle) || (fsType == kCFURLWindowsPathStyle) || (fsType == kCFURLHFSPathStyle), __kCFLogAssertion, "%s(): Received bad fsType %d", __PRETTY_FUNCTION__, fsType);
     
     // Coming in, the url has its allocator flag properly set, and its base initialized, and nothing else.    
-    url->_string = (CFStringRef)CFStringCreateCopy(CFGetAllocator(url), URLString);
-    url->_flags |= (fsType << 16);
-    
+    url->_string = CFStringCreateCopy(CFGetAllocator(url), URLString);    
     url->_base = base ? CFURLCopyAbsoluteURL(base) : NULL;
     
 #if DEBUG_URL_MEMORY_USAGE
-    if (fsType != FULL_URL_REPRESENTATION) {
+    if ( (fsType == kCFURLPOSIXPathStyle) || (fsType == kCFURLHFSPathStyle) || (fsType == kCFURLWindowsPathStyle) ) {
         numFileURLsCreated ++;
     }
-       if ( url->_base )
+    if ( url->_base ) {
         numURLsWithBaseURL ++;
+    }
 #endif
-   {
-        if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-            _convertToURLRepresentation((struct __CFURL *)url);
-        }
-        if (!(url->_flags & IS_PARSED)) {
-            _parseComponentsOfURL(url);
-        }
+    if (fsType != FULL_URL_REPRESENTATION) {
+        // _convertToURLRepresentation parses the URL
+        _convertToURLRepresentation((struct __CFURL *)url, fsType);
+    }
+    else {
+        _parseComponentsOfURL(url);
     }
 }
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#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) == '/') {
@@ -1714,8 +1777,6 @@ CF_EXPORT void _CFURLInitFSPath(CFURLRef url, CFStringRef path) {
             CFRelease(cwdURL);
     }
 }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
 
 // Exported for Foundation's use
@@ -1814,120 +1875,27 @@ struct __CFURLEncodingTranslationParameters {
     Boolean encodingsMatch;
 } ;
 
-static Boolean _shouldEscapeForEncodingConversion(UniChar ch, void *context) {
-    struct __CFURLEncodingTranslationParameters *info = (struct __CFURLEncodingTranslationParameters *)context;
-    if (info->escapeHighBit && ch > 0x7F) {
-        return true;
-    } else if (ch == '%' && info->escapePercents) {
-        return true;
-    } else if (info->addlChars) {
-        const UniChar *escChar = info->addlChars;
-        int i; 
-        for (i = 0; i < info->count; escChar ++, i ++) {
-            if (*escChar == ch) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-static CFIndex _convertEscapeSequence(CFIndex percentIndex, CFStringRef urlString, CFStringRef *newString, void *context) {
-    struct __CFURLEncodingTranslationParameters *info = (struct __CFURLEncodingTranslationParameters *)context;
-    CFMutableDataRef  newData;
-    Boolean sawNonASCIICharacter = false;
-    CFIndex i = percentIndex;
-    CFIndex length;
-    *newString = NULL;
-    if (info->encodingsMatch) return percentIndex + 3; // +3 because we want the two characters of the percent encoding to not be copied verbatim, as well
-    newData = CFDataCreateMutable(CFGetAllocator(urlString), 0);
-    length = CFStringGetLength(urlString);
-    
-    while (i < length && CFStringGetCharacterAtIndex(urlString, i) == '%') {
-        uint8_t byte;
-        if (i+2 >= length || !_translateBytes(CFStringGetCharacterAtIndex(urlString, i+1), CFStringGetCharacterAtIndex(urlString, i+2), &byte)) {
-            CFRelease(newData);
-            return -1;
-        }
-        if (byte > 0x7f) sawNonASCIICharacter = true;
-        CFDataAppendBytes(newData, &byte, 1);
-        i += 3;
-    }
-    if (!sawNonASCIICharacter && info->agreesOverASCII) {
-        CFRelease(newData);
-        return i;
-    } else {
-        CFStringRef tmp = CFStringCreateWithBytes(CFGetAllocator(urlString), CFDataGetBytePtr(newData), CFDataGetLength(newData), info->fromEnc, false);
-        CFIndex tmpIndex, tmpLen;
-        if (!tmp) {
-            CFRelease(newData);
-            return -1;
-        }
-        tmpLen = CFStringGetLength(tmp);
-        *newString = CFStringCreateMutable(CFGetAllocator(urlString), 0);
-        for (tmpIndex = 0; tmpIndex < tmpLen; tmpIndex ++) {
-            if (!_appendPercentEscapesForCharacter(CFStringGetCharacterAtIndex(tmp, tmpIndex), info->toEnc, (CFMutableStringRef)(*newString))) {
-                break;
-            }
-        }
-        CFRelease(tmp);
-        CFRelease(newData);
-        if (tmpIndex < tmpLen) {
-            CFRelease(*newString);
-            *newString = NULL;
-            return -1;
-        } else {
-            return i;
-        }
-    }
-}
-
-/* Returned string is retained for the caller; if escapePercents is true, then we do not look for any %-escape encodings in urlString */
-static CFStringRef  _convertPercentEscapes(CFStringRef urlString, CFStringEncoding fromEncoding, CFStringEncoding toEncoding, Boolean escapeAllHighBitCharacters, Boolean escapePercents, const UniChar *addlCharsToEscape, int numAddlChars) {
-    struct __CFURLEncodingTranslationParameters context;
-    context.fromEnc = fromEncoding;
-    context.toEnc = toEncoding;
-    context.addlChars = addlCharsToEscape;
-    context.count = numAddlChars;
-    context.escapeHighBit = escapeAllHighBitCharacters;
-    context.escapePercents = escapePercents;
-    context.agreesOverASCII = (__CFStringEncodingIsSupersetOfASCII(toEncoding) && __CFStringEncodingIsSupersetOfASCII(fromEncoding)) ? true : false;
-    context.encodingsMatch = (fromEncoding == toEncoding) ? true : false;
-    return _addPercentEscapesToString(CFGetAllocator(urlString), urlString, _shouldEscapeForEncodingConversion, _convertEscapeSequence, toEncoding, &context);
-}
-
 // 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 = CFStringCreateWithBytes(allocator, URLBytes, length, encoding, false);
+    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;
     }
-#if DEPLOYMENT_TARGET_MACOSX
-    if ( !baseURL && *URLBytes == '/' ) {
-       CFLog(kCFLogLevelWarning, CFSTR("CFURLCreateWithBytes was passed these invalid URLBytes: '%@' (a file system path instead of an URL string). The URL created will not work with most file URL functions. CFURLCreateFromFileSystemRepresentation should be used instead."), urlString);
-    }
-#endif
-    if (createOldUTF8StyleURLs()) {
-        if (encoding != kCFStringEncodingUTF8) {
-            CFStringRef  tmp = _convertPercentEscapes(urlString, encoding, kCFStringEncodingUTF8, false, false, NULL, 0);
-            CFRelease(urlString);
-            urlString = tmp;
-            if (!urlString) return NULL;
-        }
-    }
-    
     result = _CFURLAlloc(allocator);
     if (result) {
+        if ( useEightBitStringEncoding ) {
+            ((struct __CFURL *)result)->_flags |= USES_EIGHTBITSTRINGENCODING;
+        }
         _CFURLInitWithString(result, urlString, baseURL);
-        if (encoding != kCFStringEncodingUTF8 && !createOldUTF8StyleURLs()) {
+        if (encoding != kCFStringEncodingUTF8) {
             ((struct __CFURL *)result)->_encoding = encoding;
-       #if DEBUG_URL_MEMORY_USAGE
-           if ( encoding != kCFStringEncodingUTF8 ) {
-               numNonUTF8EncodedURLs++;
-           }
-       #endif
+#if DEBUG_URL_MEMORY_USAGE
+            numNonUTF8EncodedURLs++;
+#endif
         }
     }
     CFRelease(urlString); // it's retained by result, now.
@@ -1935,18 +1903,13 @@ CFURLRef CFURLCreateWithBytes(CFAllocatorRef allocator, const uint8_t *URLBytes,
 }
 
 CFDataRef CFURLCreateData(CFAllocatorRef allocator, CFURLRef  url, CFStringEncoding encoding, Boolean escapeWhitespace) {
-    static const UniChar whitespaceChars[4] = {' ', '\n', '\r', '\t'};
-    CFStringRef  myStr = CFURLGetString(url);  
-    CFStringRef newStr;
-    CFDataRef result;
-    if (url->_flags & IS_OLD_UTF8_STYLE) {
-        newStr = (encoding == kCFStringEncodingUTF8) ? (CFStringRef)CFRetain(myStr) : _convertPercentEscapes(myStr, kCFStringEncodingUTF8, encoding, true, false, escapeWhitespace ? whitespaceChars : NULL, escapeWhitespace ? 4 : 0);
-    } else {
-        newStr=myStr;
-        CFRetain(newStr);
-    }  
-    result = CFStringCreateExternalRepresentation(allocator, newStr, encoding, 0);
-    CFRelease(newStr);
+    CFDataRef result = NULL;
+    if ( url ) {
+        CFStringRef myStr = CFURLGetString(url);
+        if ( myStr ) {
+            result = CFStringCreateExternalRepresentation(allocator, myStr, encoding, 0);
+        }
+    }
     return result;
 }
 
@@ -1955,11 +1918,6 @@ CFURLRef CFURLCreateWithString(CFAllocatorRef allocator, CFStringRef  URLString,
     CFURLRef url;
     if (!URLString || CFStringGetLength(URLString) == 0) return NULL;
     if (!_CFStringIsLegalURLString(URLString)) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX
-    if ( !baseURL && CFStringGetCharacterAtIndex(URLString, 0) == '/' ) {
-       CFLog(kCFLogLevelWarning, CFSTR("CFURLCreateWithString was passed this invalid URL string: '%@' (a file system path instead of an URL string). The URL created will not work with most file URL functions. CFURLCreateWithFileSystemPath or CFURLCreateWithFileSystemPathRelativeToBase should be used instead."), URLString);
-    }
-#endif
     url = _CFURLAlloc(allocator);
     if (url) {
         _CFURLInitWithString(url, URLString, baseURL);
@@ -1978,30 +1936,18 @@ static CFURLRef _CFURLCreateWithArbitraryString(CFAllocatorRef allocator, CFStri
 }
 
 CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *relativeURLBytes, CFIndex length, CFStringEncoding encoding, CFURLRef baseURL, Boolean useCompatibilityMode) {
-    CFStringRef relativeString = CFStringCreateWithBytes(alloc, relativeURLBytes, length, encoding, false);
-    if (!relativeString) {
-        return NULL;
-    }
-#if DEPLOYMENT_TARGET_MACOSX
-    if ( !baseURL && *relativeURLBytes == '/' ) {
-       CFLog(kCFLogLevelWarning, CFSTR("CFURLCreateAbsoluteURLWithBytes was passed these invalid relativeURLBytes (and no baseURL): '%@' (a file system path instead of an URL string). The URL created will not work with most file URL functions. CFURLCreateFromFileSystemRepresentationRelativeToBase should be used instead."), relativeString);
-    }
-#endif
-    if (!useCompatibilityMode) {
-        CFURLRef url = _CFURLCreateWithArbitraryString(alloc, relativeString, baseURL);
-        CFRelease(relativeString);
-        if (url) {
-           ((struct __CFURL *)url)->_encoding = encoding;
-            CFURLRef absURL = CFURLCopyAbsoluteURL(url);
-       #if DEBUG_URL_MEMORY_USAGE
-           if ( encoding != kCFStringEncodingUTF8 ) {
-               numNonUTF8EncodedURLs++;
-           }
-       #endif
-            CFRelease(url);
-            return absURL;
-        } else {
-            return NULL;
+    CFURLRef result = NULL;
+    
+    // if not useCompatibilityMode, use CFURLCreateWithBytes and then CFURLCopyAbsoluteURL if there's a baseURL
+    if ( !useCompatibilityMode ) {
+        CFURLRef url = CFURLCreateWithBytes(alloc, relativeURLBytes, length, encoding, baseURL);
+        if ( url != NULL ) {
+            if ( baseURL != NULL ) {
+                result = CFURLCopyAbsoluteURL(url);
+                CFRelease(url);
+            } else {
+                result = url;
+            }
         }
     } else {
         UInt32 absFlags = 0;
@@ -2009,104 +1955,118 @@ CFURLRef CFURLCreateAbsoluteURLWithBytes(CFAllocatorRef alloc, const UInt8 *rela
         CFStringRef absString = NULL;
         Boolean absStringIsMutable = false;
         CFURLRef absURL;
-        if (!baseURL) {
-            absString = relativeString;
-        } else {
-            UniChar ch = CFStringGetCharacterAtIndex(relativeString, 0);
-            if (ch == '?' || ch == ';' || ch == '#') {
-                // Nothing but parameter + query + fragment; append to the baseURL string
-                CFStringRef baseString;
-                if (CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
-                    baseString = CFURLGetString(baseURL);
-                } else {
-                    baseString = baseURL->_string;
+        CFStringRef relativeString;
+        Boolean useEightBitStringEncoding;
+        
+        useEightBitStringEncoding = ( __CFStringEncodingIsSupersetOfASCII(encoding) && __CFBytesInASCII(relativeURLBytes, length) );
+        relativeString = CFStringCreateWithBytes(alloc, relativeURLBytes, length, useEightBitStringEncoding ? __CFStringGetEightBitStringEncoding() : encoding, false);
+        if ( relativeString != NULL ) {
+            if (!baseURL) {
+                if ( useEightBitStringEncoding ) {
+                    absFlags |= USES_EIGHTBITSTRINGENCODING;
                 }
-                absString = CFStringCreateMutable(alloc, CFStringGetLength(baseString) + CFStringGetLength(relativeString));
-                CFStringAppend((CFMutableStringRef)absString, baseString);
-                CFStringAppend((CFMutableStringRef)absString, relativeString);
-                absStringIsMutable = true;
+                absString = relativeString;
             } else {
-                UInt32 relFlags = 0;
-                CFRange *relRanges;
-                CFStringRef relString = NULL;
-                _parseComponents(alloc, relativeString, baseURL, &relFlags, &relRanges);
-                if (relFlags & HAS_SCHEME) {
-                    CFStringRef baseScheme = CFURLCopyScheme(baseURL);
-                    CFRange relSchemeRange = _rangeForComponent(relFlags, relRanges, HAS_SCHEME);
-                    if (baseScheme && CFStringGetLength(baseScheme) == relSchemeRange.length && CFStringHasPrefix(relativeString, baseScheme)) {
-                        relString = CFStringCreateWithSubstring(alloc, relativeString, CFRangeMake(relSchemeRange.length+1, CFStringGetLength(relativeString) - relSchemeRange.length - 1));
-                        CFAllocatorDeallocate(alloc, relRanges);
-                        relFlags = 0;
-                        _parseComponents(alloc, relString, baseURL, &relFlags, &relRanges);
+                UniChar ch = CFStringGetCharacterAtIndex(relativeString, 0);
+                if (ch == '?' || ch == ';' || ch == '#') {
+                    // Nothing but parameter + query + fragment; append to the baseURL string
+                    CFStringRef baseString;
+                    if (CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
+                        baseString = CFURLGetString(baseURL);
                     } else {
-                        // Discard the base string; the relative string is absolute and we're not in the funky edge case where the schemes match
-                        CFRetain(relativeString);
-                        absString = relativeString;
+                        baseString = baseURL->_string;
                     }
-                    if (baseScheme) CFRelease(baseScheme);
+                    absString = CFStringCreateMutable(alloc, CFStringGetLength(baseString) + CFStringGetLength(relativeString));
+                    CFStringAppend((CFMutableStringRef)absString, baseString);
+                    CFStringAppend((CFMutableStringRef)absString, relativeString);
+                    absStringIsMutable = true;
                 } else {
-                    CFRetain(relativeString);
-                    relString = relativeString;
-                }
-                if (!absString) {
-                    if (!CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
-                        if (!(baseURL->_flags & IS_PARSED)) {
-                            _parseComponentsOfURL(baseURL);
+                    UInt32 relFlags = 0;
+                    CFRange *relRanges;
+                    CFStringRef relString = NULL;
+                    _parseComponents(alloc, relativeString, baseURL, &relFlags, &relRanges);
+                    if (relFlags & HAS_SCHEME) {
+                        CFStringRef baseScheme = CFURLCopyScheme(baseURL);
+                        CFRange relSchemeRange = _rangeForComponent(relFlags, relRanges, HAS_SCHEME);
+                        if (baseScheme && CFStringGetLength(baseScheme) == relSchemeRange.length && CFStringHasPrefix(relativeString, baseScheme)) {
+                            relString = CFStringCreateWithSubstring(alloc, relativeString, CFRangeMake(relSchemeRange.length+1, CFStringGetLength(relativeString) - relSchemeRange.length - 1));
+                            CFAllocatorDeallocate(alloc, relRanges);
+                            relFlags = 0;
+                            _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;
                         }
-                        absString = resolveAbsoluteURLString(alloc, relString, relFlags, relRanges, baseURL->_string, baseURL->_flags, baseURL->ranges);
+                        if (baseScheme) CFRelease(baseScheme);
                     } else {
-                        CFStringRef baseString;
-                        UInt32 baseFlags = 0;
-                        CFRange *baseRanges;
-                        if (CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
-                            baseString = CFURLGetString(baseURL);
+                        CFRetain(relativeString);
+                        relString = relativeString;
+                    }
+                    if (!absString) {
+                        if (!CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
+                            absString = resolveAbsoluteURLString(alloc, relString, relFlags, relRanges, baseURL->_string, baseURL->_flags, baseURL->_ranges);
                         } else {
-                            baseString = baseURL->_string;
+                            CFStringRef baseString;
+                            UInt32 baseFlags = 0;
+                            CFRange *baseRanges;
+                            if (CF_IS_OBJC(__kCFURLTypeID, baseURL)) {
+                                baseString = CFURLGetString(baseURL);
+                            } else {
+                                baseString = baseURL->_string;
+                            }
+                            _parseComponents(alloc, baseString, NULL, &baseFlags, &baseRanges);
+                            absString = resolveAbsoluteURLString(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges);
+                            CFAllocatorDeallocate(alloc, baseRanges);
                         }
-                        _parseComponents(alloc, baseString, NULL, &baseFlags, &baseRanges);
-                        absString = resolveAbsoluteURLString(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges);
-                        CFAllocatorDeallocate(alloc, baseRanges);
+                        absStringIsMutable = true;
                     }
-                    absStringIsMutable = true;
+                    if (relString) CFRelease(relString);
+                    CFAllocatorDeallocate(alloc, relRanges);
+                }
+                CFRelease(relativeString);
+            }            
+        }
+        if ( absString ) {
+            _parseComponents(alloc, absString, NULL, &absFlags, &absRanges);
+            if (absFlags & HAS_PATH) {
+                CFRange pathRg = _rangeForComponent(absFlags, absRanges, HAS_PATH);
+                // This is expensive, but it allows us to reuse _resolvedPath.  It should be cleaned up to get this allocation removed at some point. - REW
+                UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, sizeof(UniChar) * (pathRg.length + 1), 0);
+                CFStringRef newPath;
+                CFStringGetCharacters(absString, pathRg, buf);
+                buf[pathRg.length] = '\0';
+                newPath = _resolvedPath(buf, buf + pathRg.length, '/', true, false, alloc);
+                if (CFStringGetLength(newPath) != pathRg.length) {
+                    if (!absStringIsMutable) {
+                        CFStringRef tmp = CFStringCreateMutableCopy(alloc, CFStringGetLength(absString), absString);
+                        CFRelease(absString);
+                        absString = tmp;
+                    }
+                    CFStringReplace((CFMutableStringRef)absString, pathRg, newPath);
                 }
-                if (relString) CFRelease(relString);
-                CFAllocatorDeallocate(alloc, relRanges);
+                CFRelease(newPath);
+                // Do not deallocate buf; newPath took ownership of it.
             }
-            CFRelease(relativeString);
-        }
-        _parseComponents(alloc, absString, NULL, &absFlags, &absRanges);
-        if (absFlags & HAS_PATH) {
-            CFRange pathRg = _rangeForComponent(absFlags, absRanges, HAS_PATH);
-            // This is expensive, but it allows us to reuse _resolvedPath.  It should be cleaned up to get this allocation removed at some point. - REW
-            UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, sizeof(UniChar) * (pathRg.length + 1), 0);
-            CFStringRef newPath;
-            CFStringGetCharacters(absString, pathRg, buf);
-            buf[pathRg.length] = '\0';
-            newPath = _resolvedPath(buf, buf + pathRg.length, '/', true, false, alloc);
-            if (CFStringGetLength(newPath) != pathRg.length) {
-                if (!absStringIsMutable) {
-                    CFStringRef tmp = CFStringCreateMutableCopy(alloc, CFStringGetLength(absString), absString);
-                    CFRelease(absString);
-                    absString = tmp;
+            CFAllocatorDeallocate(alloc, absRanges);
+            absURL = _CFURLCreateWithArbitraryString(alloc, absString, NULL);
+            CFRelease(absString);
+            if (absURL) {
+                ((struct __CFURL *)absURL)->_encoding = encoding;
+#if DEBUG_URL_MEMORY_USAGE
+                if ( encoding != kCFStringEncodingUTF8 ) {
+                    numNonUTF8EncodedURLs++;
                 }
-                CFStringReplace((CFMutableStringRef)absString, pathRg, newPath);
+#endif
             }
-            CFRelease(newPath);
-            // Do not deallocate buf; newPath took ownership of it.
-        }
-        CFAllocatorDeallocate(alloc, absRanges);
-        absURL = _CFURLCreateWithArbitraryString(alloc, absString, NULL);
-        CFRelease(absString);
-        if (absURL) {
-            ((struct __CFURL *)absURL)->_encoding = encoding;
-       #if DEBUG_URL_MEMORY_USAGE
-           if ( encoding != kCFStringEncodingUTF8 ) {
-               numNonUTF8EncodedURLs++;
-           }
-       #endif
+            result = absURL;
         }
-        return absURL;
     }
+    
+    return ( result );
 }
 
 /* This function is this way because I pulled it out of _resolvedURLPath (so that _resolvedFileSystemPath could use it), and I didn't want to spend a bunch of energy reworking the code.  So instead of being a bit more intelligent about inputs, it just demands a slightly perverse set of parameters, to match the old _resolvedURLPath code.  -- REW, 6/14/99 */
@@ -2318,7 +2278,6 @@ static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStrin
 
 CFURLRef CFURLCopyAbsoluteURL(CFURLRef  relativeURL) {
     CFURLRef  anURL, base;
-    CFURLPathStyle fsType;
     CFAllocatorRef alloc = CFGetAllocator(relativeURL);
     CFStringRef baseString, newString;
     UInt32 baseFlags;
@@ -2327,7 +2286,7 @@ CFURLRef CFURLCopyAbsoluteURL(CFURLRef  relativeURL) {
 
     CFAssert1(relativeURL != NULL, __kCFLogAssertion, "%s(): Cannot create an absolute URL from a NULL relative URL", __PRETTY_FUNCTION__);
     if (CF_IS_OBJC(__kCFURLTypeID, relativeURL)) {
-        CF_OBJC_CALL0(CFURLRef, anURL, relativeURL, "absoluteURL");
+        anURL = (CFURLRef) CF_OBJC_CALLV((NSURL *)relativeURL, absoluteURL);
         if (anURL) CFRetain(anURL);
         return anURL;
     } 
@@ -2339,36 +2298,11 @@ CFURLRef CFURLCopyAbsoluteURL(CFURLRef  relativeURL) {
         return (CFURLRef)CFRetain(relativeURL);
     }
     baseIsObjC = CF_IS_OBJC(__kCFURLTypeID, base);
-    fsType = URL_PATH_TYPE(relativeURL);
-
-    if (!baseIsObjC && fsType != FULL_URL_REPRESENTATION && fsType == URL_PATH_TYPE(base)) {
-        return _CFURLCopyAbsoluteFileURL(relativeURL);
-    }
-    if (fsType != FULL_URL_REPRESENTATION) {
-        _convertToURLRepresentation((struct __CFURL *)relativeURL);
-        fsType = FULL_URL_REPRESENTATION;
-    }
-    if (!(relativeURL->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(relativeURL);
-    }
-    if ((relativeURL->_flags & POSIX_AND_URL_PATHS_MATCH) && !(relativeURL->_flags & (RESOURCE_SPECIFIER_MASK | NET_LOCATION_MASK)) && !baseIsObjC && (URL_PATH_TYPE(base) == kCFURLPOSIXPathStyle)) {
-        // There's nothing to relativeURL's string except the path
-        CFStringRef newPath = _resolveFileSystemPaths(relativeURL->_string, base->_string, CFURLHasDirectoryPath(base), kCFURLPOSIXPathStyle, alloc);
-        CFURLRef result = CFURLCreateWithFileSystemPath(alloc, newPath, kCFURLPOSIXPathStyle, CFURLHasDirectoryPath(relativeURL));
-        CFRelease(newPath);
-        return result;
-    }
 
     if (!baseIsObjC) {
-        CFURLPathStyle baseType = URL_PATH_TYPE(base);
-        if (baseType != FULL_URL_REPRESENTATION) {
-            _convertToURLRepresentation((struct __CFURL *)base);
-        } else if (!(base->_flags & IS_PARSED)) {
-            _parseComponentsOfURL(base);
-        }
         baseString = base->_string;
         baseFlags = base->_flags;
-        baseRanges = base->ranges;
+        baseRanges = base->_ranges;
     } else {
         baseString = CFURLGetString(base);
         baseFlags = 0;
@@ -2376,7 +2310,7 @@ CFURLRef CFURLCopyAbsoluteURL(CFURLRef  relativeURL) {
         _parseComponents(alloc, baseString, NULL, &baseFlags, &baseRanges);
     }
     
-    newString = resolveAbsoluteURLString(alloc, relativeURL->_string, relativeURL->_flags, relativeURL->ranges, baseString, baseFlags, baseRanges);
+    newString = resolveAbsoluteURLString(alloc, relativeURL->_string, relativeURL->_flags, relativeURL->_ranges, baseString, baseFlags, baseRanges);
     if (baseIsObjC) {
         CFAllocatorDeallocate(alloc, baseRanges);
     }
@@ -2401,21 +2335,11 @@ CFStringEncoding _CFURLGetEncoding(CFURLRef url) {
 
 Boolean CFURLCanBeDecomposed(CFURLRef  anURL) {
     anURL = _CFURLFromNSURL(anURL);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) return true;
-    if (!(anURL->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(anURL);
-    }
     return ((anURL->_flags & IS_DECOMPOSABLE) != 0);
 }
 
 CFStringRef  CFURLGetString(CFURLRef  url) {
-    CF_OBJC_FUNCDISPATCH0(__kCFURLTypeID, CFStringRef  , url, "relativeString");
-    if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-        if (url->_base && (url->_flags & POSIX_AND_URL_PATHS_MATCH)) {
-            return url->_string;
-        }
-        _convertToURLRepresentation((struct __CFURL *)url);
-    }
+    CF_OBJC_FUNCDISPATCHV(__kCFURLTypeID, CFStringRef, (NSURL *)url, relativeString);
     if (!_haveTestedOriginalString(url)) {
         computeSanitizedString(url);
     }
@@ -2434,9 +2358,6 @@ CFIndex CFURLGetBytes(CFURLRef url, UInt8 *buffer, CFIndex bufferLength) {
         string = CFURLGetString(url);
         enc = kCFStringEncodingUTF8;
     } else {
-        if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-            _convertToURLRepresentation((struct __CFURL *)url);
-        }
         string = url->_string;
         enc = url->_encoding;
     }
@@ -2450,7 +2371,7 @@ CFIndex CFURLGetBytes(CFURLRef url, UInt8 *buffer, CFIndex bufferLength) {
 }
 
 CFURLRef  CFURLGetBaseURL(CFURLRef  anURL) {
-    CF_OBJC_FUNCDISPATCH0(__kCFURLTypeID, CFURLRef, anURL, "baseURL");
+    CF_OBJC_FUNCDISPATCHV(__kCFURLTypeID, CFURLRef, (NSURL *)anURL, baseURL);
     return anURL->_base;
 }
 
@@ -2472,41 +2393,66 @@ static CFStringRef _retainedComponentString(CFURLRef url, UInt32 compFlag, Boole
     CFRange rg;
     CFStringRef comp;
     CFAllocatorRef alloc = CFGetAllocator(url);
-    CFAssert1(URL_PATH_TYPE(url) == FULL_URL_REPRESENTATION, __kCFLogAssertion, "%s(): passed a file system URL", __PRETTY_FUNCTION__);
-    if (removePercentEscapes) fromOriginalString = true;
-    if (!(url->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(url);
+    if (removePercentEscapes) {
+        fromOriginalString = true;
     }
-    rg = _rangeForComponent(url->_flags, url->ranges, compFlag);
-    if (rg.location == kCFNotFound) return NULL;
-       if (compFlag & HAS_SCHEME && url->_flags & HAS_HTTP_SCHEME) {
-               comp = kCFURLHTTPScheme;
-               CFRetain(comp);
-       } else if (compFlag & HAS_SCHEME && url->_flags & HAS_FILE_SCHEME) {
-               comp = kCFURLFileScheme;
-               CFRetain(comp);
-       } else {
-               comp = CFStringCreateWithSubstring(alloc, url->_string, rg);
-       }
-    if (!fromOriginalString) {
-        if (!_haveTestedOriginalString(url)) {
-            computeSanitizedString(url);
+    rg = _rangeForComponent(url->_flags, url->_ranges, compFlag);
+    if (rg.location == kCFNotFound) {
+        comp = NULL;
+    }
+    else {
+        if ( compFlag & HAS_SCHEME ) {
+            switch ( _getSchemeTypeFromFlags(url->_flags) ) {
+                case kHasHttpScheme:
+                    comp = (CFStringRef)CFRetain(kCFURLHTTPScheme);
+                    break;
+                    
+                case kHasHttpsScheme:
+                    comp = (CFStringRef)CFRetain(kCFURLHTTPSScheme);
+                    break;
+                    
+                case kHasFileScheme:
+                    comp = (CFStringRef)CFRetain(kCFURLFileScheme);
+                    break;
+                    
+                case kHasDataScheme:
+                    comp = (CFStringRef)CFRetain(kCFURLDataScheme);
+                    break;
+                    
+                case kHasFtpScheme:
+                    comp = (CFStringRef)CFRetain(kCFURLFTPScheme);
+                    break;
+                    
+                default:
+                    comp = CFStringCreateWithSubstring(alloc, url->_string, rg);
+                    break;
+            }
         }
-        if (!(url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (url->_flags & (compFlag << BIT_SHIFT_FROM_COMPONENT_TO_DIFFERS_FLAG))) {
-            CFStringRef newComp = correctedComponent(comp, compFlag, url->_encoding);
-            CFRelease(comp);
-            comp = newComp;
+        else {
+            comp = CFStringCreateWithSubstring(alloc, url->_string, rg);
         }
-    }
-    if (removePercentEscapes) {
-        CFStringRef tmp;
-        if (url->_flags & IS_OLD_UTF8_STYLE || url->_encoding == kCFStringEncodingUTF8) {
-            tmp = CFURLCreateStringByReplacingPercentEscapes(alloc, comp, CFSTR(""));
-        } else {
-            tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(alloc, comp, CFSTR(""), url->_encoding);
+        
+        if (!fromOriginalString) {
+            if (!_haveTestedOriginalString(url)) {
+                computeSanitizedString(url);
+            }
+            if (!(url->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (_getAdditionalDataFlags(url) & compFlag)) {
+                CFStringRef newComp = correctedComponent(comp, compFlag, url->_encoding);
+                CFRelease(comp);
+                comp = newComp;
+            }
         }
-        CFRelease(comp);
-        comp = tmp;
+        if (removePercentEscapes) {
+            CFStringRef tmp;
+            if (url->_encoding == kCFStringEncodingUTF8) {
+                tmp = CFURLCreateStringByReplacingPercentEscapes(alloc, comp, CFSTR(""));
+            } else {
+                tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(alloc, comp, CFSTR(""), url->_encoding);
+            }
+            CFRelease(comp);
+            comp = tmp;
+        }
+        
     }
     return comp;
 }
@@ -2514,34 +2460,46 @@ static CFStringRef _retainedComponentString(CFURLRef url, UInt32 compFlag, Boole
 CFStringRef  CFURLCopyScheme(CFURLRef  anURL) {
     CFStringRef scheme;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, scheme, anURL, "scheme");
-        if (scheme) CFRetain(scheme);
-        return scheme;
-    } 
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        if (anURL->_base) {
-            return CFURLCopyScheme(anURL->_base);
-        } else {
-            CFRetain(kCFURLFileScheme); // because caller will release it
-            return kCFURLFileScheme;
+        scheme = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, scheme);
+        if ( scheme ) {
+            CFRetain(scheme);
         }
-    } 
-    if (anURL->_flags & IS_PARSED && anURL->_flags & HAS_HTTP_SCHEME) {
-        CFRetain(kCFURLHTTPScheme);
-        return kCFURLHTTPScheme;
     }
-    if (anURL->_flags & IS_PARSED && anURL->_flags & HAS_FILE_SCHEME) {
-        CFRetain(kCFURLFileScheme);
-        return kCFURLFileScheme;
-    }
-    scheme = _retainedComponentString(anURL, HAS_SCHEME, true, false);
-    if (scheme) {
-        return scheme;
-    } else if (anURL->_base) {
-        return CFURLCopyScheme(anURL->_base);
-    } else {
-        return NULL;
+    else {
+        switch ( _getSchemeTypeFromFlags(anURL->_flags) ) {
+            case kHasHttpScheme:
+                scheme = (CFStringRef)CFRetain(kCFURLHTTPScheme);
+                break;
+                
+            case kHasHttpsScheme:
+                scheme = (CFStringRef)CFRetain(kCFURLHTTPSScheme);
+                break;
+                
+            case kHasFileScheme:
+                scheme = (CFStringRef)CFRetain(kCFURLFileScheme);
+                break;
+                
+            case kHasDataScheme:
+                scheme = (CFStringRef)CFRetain(kCFURLDataScheme);
+                break;
+                
+            case kHasFtpScheme:
+                scheme = (CFStringRef)CFRetain(kCFURLFTPScheme);
+                break;
+                
+            default:
+                scheme = _retainedComponentString(anURL, HAS_SCHEME, true, false);
+                if ( !scheme ) {
+                    if (anURL->_base) {
+                        scheme = CFURLCopyScheme(anURL->_base);
+                    } else {
+                        scheme = NULL;
+                    }
+                }
+                break;
+        }
     }
+    return ( scheme );
 }
 
 static CFRange _netLocationRange(UInt32 flags, CFRange *ranges) {
@@ -2568,33 +2526,22 @@ static CFRange _netLocationRange(UInt32 flags, CFRange *ranges) {
 
 CFStringRef CFURLCopyNetLocation(CFURLRef  anURL) {
     anURL = _CFURLFromNSURL(anURL);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        // !!! This won't work if we go to putting the vol ref num in the net location for HFS
-        if (anURL->_base) {
-            return CFURLCopyNetLocation(anURL->_base);
-        } else {
-            CFRetain(kCFURLLocalhost);
-            return kCFURLLocalhost;
-        }
-    }
-    if (!(anURL->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(anURL);
-    }
     if (anURL->_flags & NET_LOCATION_MASK) {
         // We provide the net location
-        CFRange netRg = _netLocationRange(anURL->_flags, anURL->ranges);
+        CFRange netRg = _netLocationRange(anURL->_flags, anURL->_ranges);
         CFStringRef netLoc;
         if (!_haveTestedOriginalString(anURL)) {
             computeSanitizedString(anURL);
         }
-        if (!(anURL->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (anURL->_flags & (USER_DIFFERS | PASSWORD_DIFFERS | HOST_DIFFERS | PORT_DIFFERS))) {
+        if (!(anURL->_flags & ORIGINAL_AND_URL_STRINGS_MATCH) && (_getAdditionalDataFlags(anURL) & (USER_DIFFERS | PASSWORD_DIFFERS | HOST_DIFFERS | PORT_DIFFERS))) {
             // Only thing that can come before the net location is the scheme.  It's impossible for the scheme to contain percent escapes.  Therefore, we can use the location of netRg in _sanatizedString, just not the length. 
             CFRange netLocEnd;
-            netRg.length = CFStringGetLength( _getSanitizedString(anURL)) - netRg.location;
-            if (CFStringFindWithOptions(_getSanitizedString(anURL), CFSTR("/"), netRg, 0, &netLocEnd)) {
+            CFStringRef sanitizedString = _getSanitizedString(anURL);
+            netRg.length = CFStringGetLength(sanitizedString) - netRg.location;
+            if (CFStringFindWithOptions(sanitizedString, CFSTR("/"), netRg, 0, &netLocEnd)) {
                 netRg.length = netLocEnd.location - netRg.location;
             }
-            netLoc = CFStringCreateWithSubstring(CFGetAllocator(anURL), _getSanitizedString(anURL), netRg);
+            netLoc = CFStringCreateWithSubstring(CFGetAllocator(anURL), sanitizedString, netRg);
         } else {
             netLoc = CFStringCreateWithSubstring(CFGetAllocator(anURL), anURL->_string, netRg);
         }
@@ -2609,13 +2556,6 @@ CFStringRef CFURLCopyNetLocation(CFURLRef  anURL) {
 // NOTE - if you want an absolute path, you must first get the absolute URL.  If you want a file system path, use the file system methods above.
 CFStringRef  CFURLCopyPath(CFURLRef  anURL) {
     anURL = _CFURLFromNSURL(anURL);
-    if (URL_PATH_TYPE(anURL) == kCFURLPOSIXPathStyle && (anURL->_flags & POSIX_AND_URL_PATHS_MATCH)) {
-        CFRetain(anURL->_string);
-        return anURL->_string;
-    }
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        _convertToURLRepresentation((struct __CFURL *)anURL);
-    }
     return _retainedComponentString(anURL, HAS_PATH, false, false);
 }
 
@@ -2644,16 +2584,12 @@ CFStringRef CFURLCopyStrictPath(CFURLRef anURL, Boolean *isAbsolute) {
 
 Boolean CFURLHasDirectoryPath(CFURLRef  anURL) {
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) == FULL_URL_REPRESENTATION) {
-        if (!(anURL->_flags & IS_PARSED)) {
-            _parseComponentsOfURL(anURL);
-        }
-        if (!anURL->_base || (anURL->_flags & (HAS_PATH | NET_LOCATION_MASK))) {
-            return ((anURL->_flags & IS_DIRECTORY) != 0);
-        }
+    if (!anURL->_base || (anURL->_flags & (HAS_PATH | NET_LOCATION_MASK))) {
+        return ((anURL->_flags & IS_DIRECTORY) != 0);
+    }
+    else {
         return CFURLHasDirectoryPath(anURL->_base);
     }
-    return ((anURL->_flags & IS_DIRECTORY) != 0);
 }
 
 static UInt32 _firstResourceSpecifierFlag(UInt32 flags) {
@@ -2671,21 +2607,18 @@ static UInt32 _firstResourceSpecifierFlag(UInt32 flags) {
 CFStringRef  CFURLCopyResourceSpecifier(CFURLRef  anURL) {
     anURL = _CFURLFromNSURL(anURL);
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        return NULL;
-    }
-    if (!(anURL->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(anURL);
-    }
     if (!(anURL->_flags & IS_DECOMPOSABLE)) {
-        CFRange schemeRg = _rangeForComponent(anURL->_flags, anURL->ranges, HAS_SCHEME);
+        CFRange schemeRg = _rangeForComponent(anURL->_flags, anURL->_ranges, HAS_SCHEME);
         CFIndex base = schemeRg.location + schemeRg.length + 1;
         if (!_haveTestedOriginalString(anURL)) {
             computeSanitizedString(anURL);
         }
-        if (_getSanitizedString(anURL)) {
+        
+        CFStringRef sanitizedString = _getSanitizedString(anURL);
+        
+        if (sanitizedString) {
             // It is impossible to have a percent escape in the scheme (if there were one, we would have considered the URL a relativeURL with a  colon in the path instead), so this range computation is always safe.
-            return CFStringCreateWithSubstring(CFGetAllocator(anURL), _getSanitizedString(anURL), CFRangeMake(base, CFStringGetLength(_getSanitizedString(anURL))-base));
+            return CFStringCreateWithSubstring(CFGetAllocator(anURL), sanitizedString, CFRangeMake(base, CFStringGetLength(sanitizedString)-base));
         } else {
             return CFStringCreateWithSubstring(CFGetAllocator(anURL), anURL->_string, CFRangeMake(base, CFStringGetLength(anURL->_string)-base));
         }
@@ -2699,10 +2632,14 @@ CFStringRef  CFURLCopyResourceSpecifier(CFURLRef  anURL) {
             if (!_haveTestedOriginalString(anURL)) {
                 computeSanitizedString(anURL);
             }
+            
+            UInt32 additionalDataFlags = _getAdditionalDataFlags(anURL);
+            CFStringRef sanitizedString = _getSanitizedString(anURL);
+            
             if (!(anURL->_flags & ORIGINAL_AND_URL_STRINGS_MATCH)) {
                 // See if any pieces in the resource specifier differ between sanitized string and original string
                 for (flag = firstRsrcSpecFlag; flag != (HAS_FRAGMENT << 1); flag = flag << 1) {
-                    if (anURL->_flags & (flag << BIT_SHIFT_FROM_COMPONENT_TO_DIFFERS_FLAG)) {
+                    if (additionalDataFlags & flag) {
                         canUseOriginalString = false;
                         break;
                     }
@@ -2711,33 +2648,33 @@ CFStringRef  CFURLCopyResourceSpecifier(CFURLRef  anURL) {
             if (!canUseOriginalString) {
                 // If none of the pieces prior to the first resource specifier flag differ, then we can use the offset from the original string as the offset in the sanitized string.
                 for (flag = firstRsrcSpecFlag >> 1; flag != 0; flag = flag >> 1) {
-                    if (anURL->_flags & (flag << BIT_SHIFT_FROM_COMPONENT_TO_DIFFERS_FLAG)) {
+                    if (additionalDataFlags & flag) {
                         canUseSanitizedString = false;
                         break;
                     }
                 }
             }
             if (canUseOriginalString) {
-                CFRange rg = _rangeForComponent(anURL->_flags, anURL->ranges, firstRsrcSpecFlag);
+                CFRange rg = _rangeForComponent(anURL->_flags, anURL->_ranges, firstRsrcSpecFlag);
                 rg.location --; // Include the character that demarcates the component
                 rg.length = CFStringGetLength(anURL->_string) - rg.location;
                 return CFStringCreateWithSubstring(alloc, anURL->_string, rg);
             } else if (canUseSanitizedString) {
-                CFRange rg = _rangeForComponent(anURL->_flags, anURL->ranges, firstRsrcSpecFlag);
+                CFRange rg = _rangeForComponent(anURL->_flags, anURL->_ranges, firstRsrcSpecFlag);
                 rg.location --; // Include the character that demarcates the component
-                rg.length = CFStringGetLength(_getSanitizedString(anURL)) - rg.location;
-                return CFStringCreateWithSubstring(alloc, _getSanitizedString(anURL), rg);
+                rg.length = CFStringGetLength(sanitizedString) - rg.location;
+                return CFStringCreateWithSubstring(alloc, sanitizedString, rg);
             } else {
                 // Must compute the correct string to return; just reparse....
                 UInt32 sanFlags = 0;
                 CFRange *sanRanges = NULL;
                 CFRange rg; 
-                _parseComponents(alloc, _getSanitizedString(anURL), anURL->_base, &sanFlags, &sanRanges);
+                _parseComponents(alloc, sanitizedString, anURL->_base, &sanFlags, &sanRanges);
                 rg = _rangeForComponent(sanFlags, sanRanges, firstRsrcSpecFlag);
                 CFAllocatorDeallocate(alloc, sanRanges);
                 rg.location --; // Include the character that demarcates the component
-                rg.length = CFStringGetLength(_getSanitizedString(anURL)) - rg.location;
-                return CFStringCreateWithSubstring(CFGetAllocator(anURL), _getSanitizedString(anURL), rg);
+                rg.length = CFStringGetLength(sanitizedString) - rg.location;
+                return CFStringCreateWithSubstring(CFGetAllocator(anURL), sanitizedString, rg);
             }
         } else {
             // The resource specifier cannot possibly come from the base.
@@ -2754,19 +2691,11 @@ CFStringRef  CFURLCopyResourceSpecifier(CFURLRef  anURL) {
 CFStringRef  CFURLCopyHostName(CFURLRef  anURL) {
     CFStringRef tmp;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, tmp, anURL, "host");
+        tmp = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, host);
         if (tmp) CFRetain(tmp);
         return tmp;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        if (anURL->_base) {
-            return CFURLCopyHostName(anURL->_base);
-        } else {
-            CFRetain(kCFURLLocalhost);
-            return kCFURLLocalhost;
-        }
-    }
     tmp = _retainedComponentString(anURL, HAS_HOST, true, true);
     if (tmp) {
         if (anURL->_flags & IS_IPV6_ENCODED) {
@@ -2788,19 +2717,12 @@ CFStringRef  CFURLCopyHostName(CFURLRef  anURL) {
 SInt32 CFURLGetPortNumber(CFURLRef  anURL) {
     CFStringRef port;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CFNumberRef cfPort;
-        CF_OBJC_CALL0(CFNumberRef, cfPort, anURL, "port");
+        CFNumberRef cfPort = (CFNumberRef) CF_OBJC_CALLV((NSURL *)anURL, port);
         SInt32 num;
         if (cfPort && CFNumberGetValue(cfPort, kCFNumberSInt32Type, &num)) return num;
         return -1;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        if (anURL->_base) {
-            return CFURLGetPortNumber(anURL->_base);
-        }
-        return -1;
-    }
     port = _retainedComponentString(anURL, HAS_PORT, true, false);
     if (port) {
         SInt32 portNum, idx, length = CFStringGetLength(port);
@@ -2822,17 +2744,11 @@ SInt32 CFURLGetPortNumber(CFURLRef  anURL) {
 CFStringRef  CFURLCopyUserName(CFURLRef  anURL) {
     CFStringRef user;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, user, anURL, "user");
+        user = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, user);
         if (user) CFRetain(user);
         return user;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        if (anURL->_base) {
-            return CFURLCopyUserName(anURL->_base);
-        }
-        return NULL;
-    }
     user = _retainedComponentString(anURL, HAS_USER, true, true);
     if (user) {
         return user;
@@ -2846,17 +2762,11 @@ CFStringRef  CFURLCopyUserName(CFURLRef  anURL) {
 CFStringRef  CFURLCopyPassword(CFURLRef  anURL) {
     CFStringRef passwd;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, passwd, anURL, "password");
+        passwd = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, password);
         if (passwd) CFRetain(passwd);
         return passwd;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        if (anURL->_base) {
-            return CFURLCopyPassword(anURL->_base);
-        }
-        return NULL;
-    }
     passwd = _retainedComponentString(anURL, HAS_PASSWORD, true, true);
     if (passwd) {
         return passwd;
@@ -2872,14 +2782,11 @@ CFStringRef  CFURLCopyPassword(CFURLRef  anURL) {
 static CFStringRef  _unescapedParameterString(CFURLRef  anURL) {
     CFStringRef str;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, str, anURL, "parameterString");
+        str = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, parameterString);
         if (str) CFRetain(str);
         return str;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        return NULL;
-    }
     str = _retainedComponentString(anURL, HAS_PARAMETERS, false, false);
     if (str) return str;
     if (!(anURL->_flags & IS_DECOMPOSABLE)) return NULL;
@@ -2894,7 +2801,7 @@ CFStringRef  CFURLCopyParameterString(CFURLRef  anURL, CFStringRef charactersToL
     CFStringRef  param = _unescapedParameterString(anURL);
     if (param) {
         CFStringRef result;
-        if (anURL->_flags & IS_OLD_UTF8_STYLE || anURL->_encoding == kCFStringEncodingUTF8) {
+        if (anURL->_encoding == kCFStringEncodingUTF8) {
             result = CFURLCreateStringByReplacingPercentEscapes(CFGetAllocator(anURL), param, charactersToLeaveEscaped);
         } else {
             result = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFGetAllocator(anURL), param, charactersToLeaveEscaped, anURL->_encoding);
@@ -2908,14 +2815,11 @@ CFStringRef  CFURLCopyParameterString(CFURLRef  anURL, CFStringRef charactersToL
 static CFStringRef  _unescapedQueryString(CFURLRef  anURL) {
     CFStringRef str;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, str, anURL, "query");
+        str = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, query);
         if (str) CFRetain(str);
         return str;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        return NULL;
-    }
     str = _retainedComponentString(anURL, HAS_QUERY, false, false);
     if (str) return str;
     if (!(anURL->_flags & IS_DECOMPOSABLE)) return NULL;
@@ -2929,7 +2833,7 @@ CFStringRef  CFURLCopyQueryString(CFURLRef  anURL, CFStringRef  charactersToLeav
     CFStringRef  query = _unescapedQueryString(anURL);
     if (query) {
         CFStringRef tmp;
-        if (anURL->_flags & IS_OLD_UTF8_STYLE || anURL->_encoding == kCFStringEncodingUTF8) {
+        if (anURL->_encoding == kCFStringEncodingUTF8) {
             tmp = CFURLCreateStringByReplacingPercentEscapes(CFGetAllocator(anURL), query, charactersToLeaveEscaped);
         } else {
             tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFGetAllocator(anURL), query, charactersToLeaveEscaped, anURL->_encoding);
@@ -2944,14 +2848,11 @@ CFStringRef  CFURLCopyQueryString(CFURLRef  anURL, CFStringRef  charactersToLeav
 static CFStringRef  _unescapedFragment(CFURLRef  anURL) {
     CFStringRef str;
     if (CF_IS_OBJC(__kCFURLTypeID, anURL)) {
-        CF_OBJC_CALL0(CFStringRef, str, anURL, "fragment");
+        str = (CFStringRef) CF_OBJC_CALLV((NSURL *)anURL, fragment);
         if (str) CFRetain(str);
         return str;
     } 
     __CFGenericValidateType(anURL, __kCFURLTypeID);
-    if (URL_PATH_TYPE(anURL) != FULL_URL_REPRESENTATION) {
-        return NULL;
-    }
     str = _retainedComponentString(anURL, HAS_FRAGMENT, false, false);
     return str;
 }
@@ -2960,7 +2861,7 @@ CFStringRef  CFURLCopyFragment(CFURLRef  anURL, CFStringRef  charactersToLeaveEs
     CFStringRef  fragment = _unescapedFragment(anURL);
     if (fragment) {
         CFStringRef tmp;
-        if (anURL->_flags & IS_OLD_UTF8_STYLE || anURL->_encoding == kCFStringEncodingUTF8) {
+        if (anURL->_encoding == kCFStringEncodingUTF8) {
             tmp = CFURLCreateStringByReplacingPercentEscapes(CFGetAllocator(anURL), fragment, charactersToLeaveEscaped);
         } else {
             tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFGetAllocator(anURL), fragment, charactersToLeaveEscaped, anURL->_encoding);
@@ -2985,8 +2886,8 @@ static CFIndex insertionLocationForMask(CFURLRef url, CFOptionFlags mask) {
     } else if (lastComponentBeforeMask == HAS_SCHEME) {
         // Do not have to worry about the non-decomposable case here.  However, we must be prepared for the degenerate
         // case file:/path/immediately/without/host
-        CFRange schemeRg = _rangeForComponent(url->_flags, url->ranges, HAS_SCHEME);
-        CFRange pathRg = _rangeForComponent(url->_flags, url->ranges, HAS_PATH);
+        CFRange schemeRg = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME);
+        CFRange pathRg = _rangeForComponent(url->_flags, url->_ranges, HAS_PATH);
         if (schemeRg.length + 1 == pathRg.location) {
             return schemeRg.length + 1;
         } else {
@@ -2995,7 +2896,7 @@ static CFIndex insertionLocationForMask(CFURLRef url, CFOptionFlags mask) {
     } else {
         // For all other components, the separator precedes the component, so there's no need
         // to add extra chars to get to the next insertion point
-        CFRange rg = _rangeForComponent(url->_flags, url->ranges, lastComponentBeforeMask);
+        CFRange rg = _rangeForComponent(url->_flags, url->_ranges, lastComponentBeforeMask);
         return rg.location + rg.length;
     }
 }
@@ -3006,7 +2907,7 @@ static CFRange _CFURLGetCharRangeForMask(CFURLRef url, CFOptionFlags mask, CFRan
     Boolean haveReachedMask = false;
     CFIndex beforeMask = 0;
     CFIndex afterMask = kCFNotFound;
-    CFRange *currRange = url->ranges;
+    CFRange *currRange = url->_ranges;
     CFRange maskRange = {kCFNotFound, 0};
     for (currentOption = 1; currentOption <= HAS_FRAGMENT; currentOption = currentOption << 1) {
         if (!haveReachedMask && (currentOption & mask) != 0) {
@@ -3092,12 +2993,12 @@ static CFRange _getCharRangeInDecomposableURL(CFURLRef url, CFURLComponentType c
 
 static CFRange _getCharRangeInNonDecomposableURL(CFURLRef url, CFURLComponentType component, CFRange *rangeIncludingSeparators) {
     if (component == kCFURLComponentScheme) {
-        CFRange schemeRg = _rangeForComponent(url->_flags, url->ranges, HAS_SCHEME);
+        CFRange schemeRg = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME);
         rangeIncludingSeparators->location = 0;
         rangeIncludingSeparators->length = schemeRg.length + 1;
         return schemeRg;
     } else if (component == kCFURLComponentResourceSpecifier) {
-        CFRange schemeRg = _rangeForComponent(url->_flags, url->ranges, HAS_SCHEME);
+        CFRange schemeRg = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME);
         CFIndex stringLength = CFStringGetLength(url->_string);
         if (schemeRg.length + 1 == stringLength) {
             rangeIncludingSeparators->location = schemeRg.length + 1;
@@ -3121,12 +3022,6 @@ CFRange CFURLGetByteRangeForComponent(CFURLRef url, CFURLComponentType component
     CFRange byteRange;
     CFAssert2(component > 0 && component < 13, __kCFLogAssertion, "%s(): passed invalid component %d", __PRETTY_FUNCTION__, component);
     url = _CFURLFromNSURL(url);
-    if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-        _convertToURLRepresentation((struct __CFURL *)url);
-    }
-    if (!(url->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(url);
-    }
 
     if (!(url->_flags & IS_DECOMPOSABLE)) {
         // Special-case this because non-decomposable URLs have a slightly strange flags setup
@@ -3181,37 +3076,13 @@ CFRange CFURLGetByteRangeForComponent(CFURLRef url, CFURLComponentType component
 
 /* Component support */
 
-/* We convert to the CFURL immediately at the beginning of decomposition, so all the decomposition routines need not worry about having an ObjC NSURL */
-static CFStringRef schemeSpecificString(CFURLRef url) {
-    Boolean isDir;
-    isDir = ((url->_flags & IS_DIRECTORY) != 0);
-    switch (URL_PATH_TYPE(url)) {
-    case kCFURLPOSIXPathStyle:
-        if (url->_flags & POSIX_AND_URL_PATHS_MATCH) {
-            return (CFStringRef)CFRetain(url->_string);
-        } else {
-            return POSIXPathToURLPath(url->_string, CFGetAllocator(url), isDir);
-        }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-    case kCFURLHFSPathStyle:
-        return HFSPathToURLPath(url->_string, CFGetAllocator(url), isDir);
-#endif
-    case kCFURLWindowsPathStyle:
-        return WindowsPathToURLPath(url->_string, CFGetAllocator(url), isDir);
-    case FULL_URL_REPRESENTATION:
-        return CFURLCopyResourceSpecifier(url);
-    default:
-        return NULL;
-    }
-}
-
 static Boolean decomposeToNonHierarchical(CFURLRef url, CFURLComponentsNonHierarchical *components) {
     if ( CFURLGetBaseURL(url) != NULL)  {
         components->scheme = NULL;
     } else {
         components->scheme = CFURLCopyScheme(url);
     }
-    components->schemeSpecific = schemeSpecificString(url);
+    components->schemeSpecific = CFURLCopyResourceSpecifier(url);
     return true;
 }
 
@@ -3239,7 +3110,6 @@ static CFURLRef composeFromNonHierarchical(CFAllocatorRef alloc, const CFURLComp
 
 static Boolean decomposeToRFC1808(CFURLRef url, CFURLComponentsRFC1808 *components) {
     CFAllocatorRef alloc = CFGetAllocator(url);
-    int pathType;
     static CFStringRef emptyStr = NULL;
     if (!emptyStr) {
         emptyStr = CFSTR("");
@@ -3248,71 +3118,32 @@ static Boolean decomposeToRFC1808(CFURLRef url, CFURLComponentsRFC1808 *componen
     if (!CFURLCanBeDecomposed(url)) {
         return false;
     }
-    if ((pathType = URL_PATH_TYPE(url)) == FULL_URL_REPRESENTATION) {
-        CFStringRef path = CFURLCopyPath(url);
-        if (path) {
-            components->pathComponents = CFStringCreateArrayBySeparatingStrings(alloc, path, CFSTR("/"));
-            CFRelease(path);
-        } else {
-            components->pathComponents = NULL;
-        }
-        components->baseURL = CFURLGetBaseURL(url);
-        if (components->baseURL)  {
-            CFRetain(components->baseURL);
-            components->scheme = NULL;
-        } else {
-            components->scheme = _retainedComponentString(url, HAS_SCHEME, true, false);
-        }
-        components->user = _retainedComponentString(url, HAS_USER, false, false);
-        components->password = _retainedComponentString(url, HAS_PASSWORD, false, false);
-        components->host = _retainedComponentString(url, HAS_HOST, false, false);
-        if (url->_flags & HAS_PORT) {
-            components->port = CFURLGetPortNumber(url);
-        } else {
-            components->port = kCFNotFound;
-        }
-        components->parameterString = _retainedComponentString(url, HAS_PARAMETERS, false, false);
-        components->query = _retainedComponentString(url, HAS_QUERY, false, false);
-        components->fragment = _retainedComponentString(url, HAS_FRAGMENT, false, false);
+    
+    CFStringRef path = CFURLCopyPath(url);
+    if (path) {
+        components->pathComponents = CFStringCreateArrayBySeparatingStrings(alloc, path, CFSTR("/"));
+        CFRelease(path);
+    } else {
+        components->pathComponents = NULL;
+    }
+    components->baseURL = CFURLGetBaseURL(url);
+    if (components->baseURL)  {
+        CFRetain(components->baseURL);
+        components->scheme = NULL;
+    } else {
+        components->scheme = _retainedComponentString(url, HAS_SCHEME, true, false);
+    }
+    components->user = _retainedComponentString(url, HAS_USER, false, false);
+    components->password = _retainedComponentString(url, HAS_PASSWORD, false, false);
+    components->host = _retainedComponentString(url, HAS_HOST, false, false);
+    if (url->_flags & HAS_PORT) {
+        components->port = CFURLGetPortNumber(url);
     } else {
-        switch (pathType) {
-        case kCFURLPOSIXPathStyle: {
-            CFStringRef pathStr;
-            if (url->_flags & POSIX_AND_URL_PATHS_MATCH) {
-                pathStr = url->_string;
-                CFRetain(pathStr);
-            } else {
-                pathStr = POSIXPathToURLPath(url->_string, alloc, url->_flags & IS_DIRECTORY);
-            }
-            components->pathComponents = CFStringCreateArrayBySeparatingStrings(alloc, pathStr, CFSTR("/"));
-            CFRelease(pathStr);
-            break;
-        }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-       case kCFURLHFSPathStyle:
-            components->pathComponents = HFSPathToURLComponents(url->_string, alloc, ((url->_flags & IS_DIRECTORY) != 0));
-            break;
-#endif
-        case kCFURLWindowsPathStyle:
-            components->pathComponents = WindowsPathToURLComponents(url->_string, alloc, ((url->_flags & IS_DIRECTORY) != 0));
-            break;
-        default:
-            components->pathComponents = NULL;
-        }
-        if (!components->pathComponents) {
-            return false;
-        }
-        components->scheme = (CFStringRef)CFRetain(kCFURLFileScheme);
-        components->user = NULL;
-        components->password = NULL;
-        components->host = (CFStringRef)CFRetain(kCFURLLocalhost);
         components->port = kCFNotFound;
-        components->parameterString = NULL;
-        components->query = NULL;
-        components->fragment = NULL;
-        components->baseURL = CFURLGetBaseURL(url);
-        if (components->baseURL) CFRetain(components->baseURL);
     }
+    components->parameterString = _retainedComponentString(url, HAS_PARAMETERS, false, false);
+    components->query = _retainedComponentString(url, HAS_QUERY, false, false);
+    components->fragment = _retainedComponentString(url, HAS_FRAGMENT, false, false);
     return true;
 }
 
@@ -3578,7 +3409,143 @@ static CFStringRef URLPathToPOSIXPath(CFStringRef path, CFAllocatorRef allocator
         }
     return result;
                 }
+
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+static Boolean CanonicalFileURLStringToFileSystemRepresentation(CFStringRef str, CFAllocatorRef alloc, UInt8 *inBuffer, CFIndex inBufferLen)
+{
+    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);
+        if ( strLength != 0 ) {
+            CFIndex maxBufLength = strLength * 3;
+            CFIndex usedBufLen;
+            CFIndex charsConverted;
+            if ( strLength <= PATH_MAX ) {
+                escapedBuf = &stackEscapedBuf[0];
+            }
+            else {
+                // worst case size is every unicode code point could be a 3-byte UTF8 sequence
+                escapedBuf = (UInt8 *)malloc(maxBufLength);
+            }
+            if ( escapedBuf != NULL ) {
+                charsConverted = CFStringGetBytes(str, CFRangeMake(sizeof(fileURLPrefixWithAuthority) - 1, strLength), kCFStringEncodingUTF8, 0, false, escapedBuf, maxBufLength, &usedBufLen);
+                if ( charsConverted ) {
+                    static const UInt8 hexvalues[] = {
+                        /* 00 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 08 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 10 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 18 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 20 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 28 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 30 */  0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
+                        /* 38 */  0x8, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 40 */  0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,
+                        /* 48 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 50 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 58 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 60 */  0x0, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0,
+                        /* 68 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 70 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 78 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        
+                        /* 80 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 88 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 90 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* 98 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* A0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* A8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* B0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* B8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* C0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* C8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* D0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* D8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* E0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* E8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* F0 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                        /* F8 */  0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+                    };
+                    UInt8 *bufStartPtr;
+                    UInt8 *bufEndPtr;
+                    UInt8 *bufPtr;
+                    const UInt8 *bytePtr = escapedBuf;
+                    CFIndex idx;
+                    Boolean trailingSlash = false;
+                    
+                    bufPtr = bufStartPtr = inBuffer;
+                    bufEndPtr = inBuffer + inBufferLen;
+                    result = TRUE;
+                    
+                    for ( idx = 0; (idx < usedBufLen) && result; ++idx ) {
+                        if ( bufPtr == bufEndPtr ) {
+                            // ooops, ran out of inBuffer
+                            *bufStartPtr = '\0';
+                            result = FALSE;
+                        }
+                        else {
+                            switch ( *bytePtr ) {
+                                case '%':
+                                    idx += 2;
+                                    if ( idx < usedBufLen ) {
+                                        // skip over %
+                                        bytePtr++;
+                                        // convert hex digits
+                                        *bufPtr = hexvalues[*bytePtr++] << 4;
+                                        *bufPtr += hexvalues[*bytePtr++];
+                                        trailingSlash = (*bufPtr == '/');
+                                    }
+                                    break;
+                                default:
+                                    // copy everything else
+                                    *bufPtr = *bytePtr++;
+                                    trailingSlash = (*bufPtr == '/');
+                                    break;
+                            }
+                            ++bufPtr;
+                        }
+                    }
+                    if ( result ) {
+                        // remove trailing slash (if any)
+                        if ( (bufPtr > (bufStartPtr + 1)) && trailingSlash ) {
+                            --bufPtr;
+                        }
+                        if ( bufPtr < bufEndPtr ) {
+                            *bufPtr = '\0';
+                        }
+                    }
+                }
+                else {
+                    // CFStringGetBytes failed
+                    result = FALSE;
+                }
                 
+                // free the buffer if we malloc'd it
+                if ( escapedBuf != &stackEscapedBuf[0] ) {
+                    free(escapedBuf);
+                }
+            }
+            else {
+                // could not allocate escapedBuf
+                result = FALSE;
+            }
+        }
+        else {
+            // str was zero characters
+            *inBuffer = '\0';
+            result = TRUE;
+        }
+    }
+    else {
+        // no inBuffer or inBufferLen is zero
+        result = FALSE;
+    }
+    
+    return ( result );
+}
+#endif
+
 #if DEPLOYMENT_TARGET_WINDOWS
 // From CFPlatform.c
 extern CFStringRef CFCreateWindowsDrivePathFromVolumeName(CFStringRef volNameStr);
@@ -3655,18 +3622,15 @@ 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) {
+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);
     
-#if DEBUG_URL_MEMORY_USAGE
-    numFileURLsConverted ++;
-#endif
-
-    switch (URL_PATH_TYPE(url)) {
+    switch (fsType) {
         case kCFURLPOSIXPathStyle:
+            isFileReferencePath = _pathHasFileIDPrefix(url->_string);
             if (url->_flags & POSIX_AND_URL_PATHS_MATCH) {
                 path = (CFStringRef)CFRetain(url->_string);
             } else {
@@ -3680,44 +3644,43 @@ static void _convertToURLRepresentation(struct __CFURL *url) {
     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://") : CFSTR("file://localhost"));
-           CFStringAppend(str, path);
-           url->_flags = (url->_flags & (IS_DIRECTORY)) | (FULL_URL_REPRESENTATION << 16) | IS_DECOMPOSABLE | IS_ABSOLUTE | IS_PARSED | HAS_SCHEME | HAS_FILE_SCHEME | HAS_HOST | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | ( isFileReferencePath ? PATH_HAS_FILE_ID : 0 );
-           CFRelease(url->_string);
-           url->_string = str;
-           url->ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange) * 3, 0);
-           url->ranges[0] = CFRangeMake(0, 4);
-           url->ranges[1] = CFRangeMake(7, isFileReferencePath ? 0 : 9);
-           url->ranges[2] = CFRangeMake(url->ranges[1].location + url->ranges[1].length, CFStringGetLength(path));
-           CFRelease(path);
-       } else {
-           CFRelease(url->_string);
-           url->_flags = (url->_flags & (IS_DIRECTORY)) | (FULL_URL_REPRESENTATION << 16) | IS_DECOMPOSABLE | IS_PARSED | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH;
-           url->_string = path;
-           url->ranges = (CFRange *)CFAllocatorAllocate(alloc, sizeof(CFRange), 0);
-           *(url->ranges) = CFRangeMake(0, CFStringGetLength(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));
+        }
     }
 }
 
-// relativeURL is known to be a file system URL whose base is a matching file system URL
-static CFURLRef _CFURLCopyAbsoluteFileURL(CFURLRef relativeURL) {
-    CFAllocatorRef alloc = CFGetAllocator(relativeURL);
-    CFURLPathStyle fsType = URL_PATH_TYPE(relativeURL);
-    CFURLRef base = relativeURL->_base;
-    CFStringRef newPath = _resolveFileSystemPaths(relativeURL->_string, base->_string, (base->_flags & IS_DIRECTORY) != 0, fsType, alloc);
-    CFURLRef result =  CFURLCreateWithFileSystemPath(alloc, newPath, fsType, (relativeURL->_flags & IS_DIRECTORY) != 0);
-    CFRelease(newPath);
-    return result;
-}
-
 // Caller must release the returned string
 static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef basePath, Boolean baseIsDir, CFURLPathStyle fsType, CFAllocatorRef alloc) {
     CFIndex baseLen = CFStringGetLength(basePath);
     CFIndex relLen = CFStringGetLength(relativePath);
-    UniChar pathDelimiter = PATH_DELIM_FOR_TYPE(fsType);
+    UniChar pathDelimiter = '/';
     UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, sizeof(UniChar)*(relLen + baseLen + 2), 0);
     CFStringGetCharacters(basePath, CFRangeMake(0, baseLen), buf);
     if (baseIsDir) {
@@ -3755,7 +3718,7 @@ CFURLRef CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStringRef fil
     CFIndex len;
     CFURLRef baseURL, result;
 
-    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle || ASSERT_CHECK_PATHSTYLE(fsType), __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
+    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
     
     CFAssert1(filePath != NULL, __kCFLogAssertion, "%s(): NULL filePath argument not permitted", __PRETTY_FUNCTION__);
 
@@ -3793,7 +3756,7 @@ CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef al
     CFIndex len;
 
     CFAssert1(filePath != NULL, __kCFLogAssertion, "%s(): NULL path string not permitted", __PRETTY_FUNCTION__);
-    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle || ASSERT_CHECK_PATHSTYLE(fsType), __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
+    CFAssert2(fsType == kCFURLPOSIXPathStyle || fsType == kCFURLHFSPathStyle || fsType == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): encountered unknown path style %d", __PRETTY_FUNCTION__, fsType);
     
        len = CFStringGetLength(filePath);
 
@@ -3808,8 +3771,8 @@ CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef al
            /* Absolute path under Win32 can begin with "\\"
             * (Sergey Zubarev)
             */
-                       if (!isAbsolute)
-                               isAbsolute = (len > 2 && CFStringGetCharacterAtIndex(filePath, 0) == '\\' && CFStringGetCharacterAtIndex(filePath, 1) == '\\');
+            if (!isAbsolute)
+                isAbsolute = (len > 2 && CFStringGetCharacterAtIndex(filePath, 0) == '\\' && CFStringGetCharacterAtIndex(filePath, 1) == '\\');
              pathDelim = '\\';
             break;
         case kCFURLHFSPathStyle: 
@@ -3925,7 +3888,8 @@ CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef al
            CFStringAppend(newString, CFSTR("./"));
            CFStringAppend(newString, url->_string);
             CFRelease(url->_string);
-            ((struct __CFURL *)url)->_string = newString;
+            ((struct __CFURL *)url)->_string = CFStringCreateCopy(allocator, newString);
+            CFRelease(newString);
         }
     }
     return url;
@@ -3934,23 +3898,29 @@ CF_EXPORT CFURLRef CFURLCreateWithFileSystemPathRelativeToBase(CFAllocatorRef al
 static Boolean _pathHasFileIDPrefix( CFStringRef path )
 {
     // path is not NULL, path has prefix "/.file/" and has at least one character following the prefix.
+#ifdef __CONSTANT_STRINGS__
+    static const 
+#endif
     CFStringRef fileIDPrefix = CFSTR( "/" FILE_ID_PREFIX "/" );
     return path && CFStringHasPrefix( path, fileIDPrefix ) && CFStringGetLength( path ) > CFStringGetLength( fileIDPrefix );
 }
 
-
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 static Boolean _pathHasFileIDOnly( CFStringRef path )
 {
     // Is file ID rooted and contains no additonal path segments
     CFRange slashRange;
     return _pathHasFileIDPrefix( path ) && ( !CFStringFindWithOptions( path, CFSTR("/"), CFRangeMake( sizeof(FILE_ID_PREFIX) + 1, CFStringGetLength( path ) - sizeof(FILE_ID_PREFIX) - 1), 0, &slashRange ) || slashRange.location == CFStringGetLength( path ) - 1 );
 }
-
+#endif
 
 CF_EXPORT CFStringRef CFURLCopyFileSystemPath(CFURLRef anURL, CFURLPathStyle pathStyle) {
-    CFAssert2(pathStyle == kCFURLPOSIXPathStyle || pathStyle == kCFURLHFSPathStyle || pathStyle == kCFURLWindowsPathStyle || ASSERT_CHECK_PATHSTYLE(pathStyle), __kCFLogAssertion, "%s(): Encountered unknown path style %d", __PRETTY_FUNCTION__, pathStyle);
+    CFAssert2(pathStyle == kCFURLPOSIXPathStyle || pathStyle == kCFURLHFSPathStyle || pathStyle == kCFURLWindowsPathStyle, __kCFLogAssertion, "%s(): Encountered unknown path style %d", __PRETTY_FUNCTION__, pathStyle);
     
-    return CFURLCreateStringWithFileSystemPath(CFGetAllocator(anURL), anURL, pathStyle, false);
+    CFStringRef result;
+    
+    result = CFURLCreateStringWithFileSystemPath(CFGetAllocator(anURL), anURL, pathStyle, false);
+    return ( result );
 }
 
 
@@ -3962,13 +3932,7 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
     
     if (!CF_IS_OBJC(__kCFURLTypeID, anURL)) {
         // We can grope the ivars
-        CFURLPathStyle myType = URL_PATH_TYPE(anURL);
-        if (myType == fsType) {
-            relPath = (CFStringRef)CFRetain(anURL->_string);
-        } else if (fsType == kCFURLPOSIXPathStyle && myType == FULL_URL_REPRESENTATION) {
-            if (!(anURL->_flags & IS_PARSED)) {
-                _parseComponentsOfURL(anURL);
-            }
+        if (fsType == kCFURLPOSIXPathStyle) {
             if (anURL->_flags & POSIX_AND_URL_PATHS_MATCH) {
                 relPath = _retainedComponentString(anURL, HAS_PATH, true, true);
             }
@@ -3977,7 +3941,7 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
 
     if (relPath == NULL) {
         CFStringRef urlPath = CFURLCopyPath(anURL);
-        CFStringEncoding enc = (anURL->_flags & IS_OLD_UTF8_STYLE) ? kCFStringEncodingUTF8 : anURL->_encoding;
+        CFStringEncoding enc = anURL->_encoding;
         if (urlPath) {
             switch (fsType) {
                 case kCFURLPOSIXPathStyle:
@@ -4000,32 +3964,52 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR
     // and do a linked-on-or-later check so we don't break third parties.
     // See <rdar://problem/4003028> Converting volume name from POSIX to HFS form fails and
     // <rdar://problem/4018895> CF needs to back out 4003028 for icky details.
-    if ( relPath && CFURLHasDirectoryPath(anURL) && CFStringGetLength(relPath) > 1 && CFStringGetCharacterAtIndex(relPath, CFStringGetLength(relPath)-1) == PATH_DELIM_FOR_TYPE(fsType)) {
+    if ( relPath && CFURLHasDirectoryPath(anURL) && CFStringGetLength(relPath) > 1 && CFStringGetCharacterAtIndex(relPath, CFStringGetLength(relPath)-1) == '/') {
         CFStringRef tmp = CFStringCreateWithSubstring(allocator, relPath, CFRangeMake(0, CFStringGetLength(relPath)-1));
         CFRelease(relPath);
         relPath = tmp;
     }
     
-    // Note that !resolveAgainstBase implies !base
-    if (!basePath || !relPath) {
+    if ( relPath ) {
         if ( basePath ) {
+            // we have both basePath and relPath -- resolve them
+            CFStringRef result = _resolveFileSystemPaths(relPath, basePath, CFURLHasDirectoryPath(base), fsType, allocator);
             CFRelease(basePath);
+            CFRelease(relPath);
+            return result;
         }
-        return relPath;
-    } else {
-        CFStringRef result = _resolveFileSystemPaths(relPath, basePath, CFURLHasDirectoryPath(base), fsType, allocator);
-        CFRelease(basePath);
-        CFRelease(relPath);
-        return result;
+        else {
+            // we only have the relPath -- return it
+            return relPath;
+        }
+    }
+    else if ( basePath ) {
+        // we only have the basePath --- return it
+        return basePath;
+    }
+    else {
+        // we have nothing to return
+        return NULL;
     }
 }
 
 Boolean CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, uint8_t *buffer, CFIndex bufLen) {
-    CFStringRef path;
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || 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 ( !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);
+            }
+        }
+    }
+    // else fall back to slower way.
     path = CFURLCreateStringWithFileSystemPath(alloc, url, kCFURLPOSIXPathStyle, resolveAgainstBase);
     if (path) {
         Boolean convResult = _CFStringGetFileSystemRepresentation(path, buffer, bufLen);
@@ -4044,8 +4028,6 @@ Boolean CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBas
             return true;
         }
     }
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     return false;
 }
@@ -4099,31 +4081,180 @@ static CFStringRef _createPathFromFileSystemRepresentation(CFAllocatorRef alloca
     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));
+    }
+    
+    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);
+        }
+    }
+    else {
+        result = NULL;
+    }
+    
+    if ( addedPercentEncoding ) {
+        *addedPercentEncoding = addedPercent;
+    }
+    
+    return ( result );
+}
+
 CFURLRef CFURLCreateFromFileSystemRepresentation(CFAllocatorRef allocator, const uint8_t *buffer, CFIndex bufLen, Boolean isDirectory) {
-    CFStringRef path = _createPathFromFileSystemRepresentation(allocator, buffer, bufLen, isDirectory);
-    CFURLRef newURL;
-    if (!path) return NULL;
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+    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;
+        }
+    }
 #elif DEPLOYMENT_TARGET_WINDOWS
+    CFStringRef path = _createPathFromFileSystemRepresentation(allocator, buffer, bufLen, isDirectory);
+    if ( path ) {
         newURL = CFURLCreateWithFileSystemPath(allocator, path, kCFURLWindowsPathStyle, isDirectory);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
+        CFRelease(path);
+    }
+    else {
+        newURL = NULL;
+    }
 #endif
-    CFRelease(path);
     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;
+    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);
-#else
-#error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
     CFRelease(path);
     return newURL;
@@ -4136,28 +4267,22 @@ CF_EXPORT CFURLRef CFURLCreateFromFileSystemRepresentationRelativeToBase(CFAlloc
 
 // Assumes url is a CFURL (not an Obj-C NSURL)
 static CFRange _rangeOfLastPathComponent(CFURLRef url) {
-    UInt32 pathType = URL_PATH_TYPE(url);
     CFRange pathRg, componentRg;
     
-    if (pathType ==  FULL_URL_REPRESENTATION) {
-        if (!(url->_flags & IS_PARSED)) _parseComponentsOfURL(url);
-        pathRg = _rangeForComponent(url->_flags, url->ranges, HAS_PATH);
-    } else {
-        pathRg = CFRangeMake(0, CFStringGetLength(url->_string));
-    }
+    pathRg = _rangeForComponent(url->_flags, url->_ranges, HAS_PATH);
 
     if (pathRg.location == kCFNotFound || pathRg.length == 0) {
         // No path
         return pathRg;
     }
-    if (CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) == PATH_DELIM_FOR_TYPE(pathType)) {
+    if (CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) == '/') {
         pathRg.length --;
         if (pathRg.length == 0) {
             pathRg.length ++;
             return pathRg;
         }
     }
-    if (CFStringFindWithOptions(url->_string, PATH_DELIM_AS_STRING_FOR_TYPE(pathType), pathRg, kCFCompareBackwards, &componentRg)) {
+    if (CFStringFindWithOptions(url->_string, CFSTR("/"), pathRg, kCFCompareBackwards, &componentRg)) {
         componentRg.location ++;
         componentRg.length = pathRg.location + pathRg.length - componentRg.location;
     } else {
@@ -4170,7 +4295,7 @@ CFStringRef CFURLCopyLastPathComponent(CFURLRef url) {
     CFStringRef result;
 
     if (CF_IS_OBJC(__kCFURLTypeID, url)) {
-        CFStringRef path = CFURLCopyFileSystemPath(url, kCFURLPOSIXPathStyle);
+        CFStringRef path = CFURLCreateStringWithFileSystemPath(CFGetAllocator(url), url, kCFURLPOSIXPathStyle, false);
         CFIndex length;
         CFRange rg, compRg;
         if (!path) return NULL;
@@ -4197,9 +4322,8 @@ CFStringRef CFURLCopyLastPathComponent(CFURLRef url) {
             CFRelease(path);
         }
     } else {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         Boolean filePathURLCreated = false;
-        
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         if ( _CFURLIsFileReferenceURL(url) ) {
             // use a file path URL or fail
             CFURLRef filePathURL = CFURLCreateFilePathURL(CFGetAllocator(url), url, NULL);
@@ -4216,25 +4340,21 @@ CFStringRef CFURLCopyLastPathComponent(CFURLRef url) {
         CFRange rg = _rangeOfLastPathComponent(url);
         if (rg.location == kCFNotFound || rg.length == 0) {
             // No path
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
             if ( filePathURLCreated ) {
                 CFRelease(url);
             }
-#endif
             return (CFStringRef)CFRetain(CFSTR(""));
         }
-        if (rg.length == 1 && CFStringGetCharacterAtIndex(url->_string, rg.location) == PATH_DELIM_FOR_TYPE(URL_PATH_TYPE(url))) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+        if (rg.length == 1 && CFStringGetCharacterAtIndex(url->_string, rg.location) == '/') {
             if ( filePathURLCreated ) {
                 CFRelease(url);
             }
-#endif
             return (CFStringRef)CFRetain(CFSTR("/"));
         }
         result = CFStringCreateWithSubstring(CFGetAllocator(url), url->_string, rg);
-        if (URL_PATH_TYPE(url) == FULL_URL_REPRESENTATION && !(url->_flags & POSIX_AND_URL_PATHS_MATCH)) {
+        if (!(url->_flags & POSIX_AND_URL_PATHS_MATCH)) {
             CFStringRef tmp;
-            if (url->_flags & IS_OLD_UTF8_STYLE || url->_encoding == kCFStringEncodingUTF8) {
+            if (url->_encoding == kCFStringEncodingUTF8) {
                 tmp = CFURLCreateStringByReplacingPercentEscapes(CFGetAllocator(url), result, CFSTR(""));
             } else {
                 tmp = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFGetAllocator(url), result, CFSTR(""), url->_encoding);
@@ -4242,11 +4362,9 @@ CFStringRef CFURLCopyLastPathComponent(CFURLRef url) {
             CFRelease(result);
             result = tmp;
         }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         if ( filePathURLCreated ) {
             CFRelease(url);
         }
-#endif
     }
     return result;
 }
@@ -4272,15 +4390,13 @@ CFStringRef CFURLCopyPathExtension(CFURLRef url) {
 }
 
 CFURLRef CFURLCreateCopyAppendingPathComponent(CFAllocatorRef allocator, CFURLRef url, CFStringRef pathComponent, Boolean isDirectory) {
-    UInt32 fsType;
     CFURLRef result;
     url = _CFURLFromNSURL(url);
     __CFGenericValidateType(url, __kCFURLTypeID);
     CFAssert1(pathComponent != NULL, __kCFLogAssertion, "%s(): Cannot be called with a NULL component to append", __PRETTY_FUNCTION__);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     Boolean filePathURLCreated = false;
-    
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( _CFURLIsFileReferenceURL(url) ) {
         // use a file path URL if possible (only because this is appending a path component)
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
@@ -4291,61 +4407,31 @@ CFURLRef CFURLCreateCopyAppendingPathComponent(CFAllocatorRef allocator, CFURLRe
     }
 #endif
 
-    fsType = URL_PATH_TYPE(url);
-    if (fsType != FULL_URL_REPRESENTATION && CFStringFindWithOptions(pathComponent, PATH_DELIM_AS_STRING_FOR_TYPE(fsType), CFRangeMake(0, CFStringGetLength(pathComponent)), 0, NULL)) {
-        // Must convert to full representation, and then work with it
-        fsType = FULL_URL_REPRESENTATION;
-        _convertToURLRepresentation((struct __CFURL *)url);
+    CFMutableStringRef newString;
+    CFStringRef newComp;
+    CFRange pathRg;
+    if (!(url->_flags & HAS_PATH)) {
+        result = NULL;
     }
-
-    if (fsType == FULL_URL_REPRESENTATION) {
-        CFMutableStringRef newString;
-        CFStringRef newComp;
-        CFRange pathRg;
-        if (!(url->_flags & IS_PARSED)) _parseComponentsOfURL(url);
-        if (!(url->_flags & HAS_PATH)) {
-            result = NULL;
-        }
-        else {
-            newString = CFStringCreateMutableCopy(allocator, 0, url->_string);
-            newComp = CFURLCreateStringByAddingPercentEscapes(allocator, pathComponent, NULL, CFSTR(";?"),  (url->_flags & IS_OLD_UTF8_STYLE) ? kCFStringEncodingUTF8 : url->_encoding);
-            pathRg = _rangeForComponent(url->_flags, url->ranges, HAS_PATH);
-            if (!pathRg.length || CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) != '/') {
-                CFStringInsert(newString, pathRg.location + pathRg.length, CFSTR("/"));
-                pathRg.length ++;
-            }
-            CFStringInsert(newString, pathRg.location + pathRg.length, newComp);
-            if (isDirectory) {
-                CFStringInsert(newString, pathRg.location + pathRg.length + CFStringGetLength(newComp), CFSTR("/"));
-            }
-            CFRelease(newComp);
-            result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
-            CFRelease(newString);
+    else {
+        newString = CFStringCreateMutableCopy(allocator, 0, url->_string);
+        newComp = CFURLCreateStringByAddingPercentEscapes(allocator, pathComponent, NULL, CFSTR(";?"), url->_encoding);
+        pathRg = _rangeForComponent(url->_flags, url->_ranges, HAS_PATH);
+        if ( (!pathRg.length || CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) != '/') && (CFStringGetCharacterAtIndex(newComp, 0) != '/') ) {
+            CFStringInsert(newString, pathRg.location + pathRg.length, CFSTR("/"));
+            pathRg.length ++;
         }
-    } else {
-        UniChar pathDelim = PATH_DELIM_FOR_TYPE(fsType);
-        CFStringRef newString;
-        if (CFStringGetCharacterAtIndex(url->_string, CFStringGetLength(url->_string) - 1) != pathDelim) {
-            if (isDirectory) {
-                newString = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@%c%@%c"), url->_string, pathDelim, pathComponent, pathDelim);
-            } else {
-                newString = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@%c%@"), url->_string, pathDelim, pathComponent);
-            }
-        } else {
-            if (isDirectory) {
-                newString = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@%@%c"), url->_string, pathComponent, pathDelim);
-            } else {
-                newString = CFStringCreateWithFormat(allocator, NULL, CFSTR("%@%@"), url->_string, pathComponent);
-            }
+        CFStringInsert(newString, pathRg.location + pathRg.length, newComp);
+        if (isDirectory) {
+            CFStringInsert(newString, pathRg.location + pathRg.length + CFStringGetLength(newComp), CFSTR("/"));
         }
-        result = CFURLCreateWithFileSystemPathRelativeToBase(allocator, newString, fsType, isDirectory, url->_base);
+        CFRelease(newComp);
+        result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
         CFRelease(newString);
     }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( filePathURLCreated ) {
         CFRelease(url);
     }
-#endif
     return result;
 }
 
@@ -4354,15 +4440,13 @@ CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFUR
     CFMutableStringRef newString;
     CFRange lastCompRg, pathRg;
     Boolean appendDotDot = false;
-    UInt32 fsType;
 
     url = _CFURLFromNSURL(url);
     CFAssert1(url != NULL, __kCFLogAssertion, "%s(): NULL argument not allowed", __PRETTY_FUNCTION__);
     __CFGenericValidateType(url, __kCFURLTypeID);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     Boolean filePathURLCreated = false;
-
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( _CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
@@ -4376,27 +4460,19 @@ CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFUR
     }
 #endif
     
-    fsType = URL_PATH_TYPE(url);
-    if (fsType == FULL_URL_REPRESENTATION) {
-        if (!(url->_flags & IS_PARSED)) _parseComponentsOfURL(url);
-        if (!(url->_flags & HAS_PATH)) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-            if ( filePathURLCreated ) {
-                CFRelease(url);
-            }
-#endif
-            return NULL;
+    if (!(url->_flags & HAS_PATH)) {
+        if ( filePathURLCreated ) {
+            CFRelease(url);
         }
-        pathRg = _rangeForComponent(url->_flags, url->ranges, HAS_PATH);
-    } else {
-        pathRg = CFRangeMake(0, CFStringGetLength(url->_string));
+        return NULL;
     }
+    pathRg = _rangeForComponent(url->_flags, url->_ranges, HAS_PATH);
     lastCompRg = _rangeOfLastPathComponent(url);
     if (lastCompRg.length == 0) {
         appendDotDot = true;
     } else if (lastCompRg.length == 1) {
         UniChar ch = CFStringGetCharacterAtIndex(url->_string, lastCompRg.location);
-        if (ch == '.' || ch == PATH_DELIM_FOR_TYPE(fsType)) {
+        if (ch == '.' || ch == '/') {
             appendDotDot = true;
         }
     } else if (lastCompRg.length == 2 && CFStringGetCharacterAtIndex(url->_string, lastCompRg.location) == '.' && CFStringGetCharacterAtIndex(url->_string, lastCompRg.location+1) == '.') {
@@ -4406,17 +4482,17 @@ CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFUR
     newString = CFStringCreateMutableCopy(allocator, 0, url->_string);
     if (appendDotDot) {
         CFIndex delta = 0;
-        if (pathRg.length > 0 && CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) != PATH_DELIM_FOR_TYPE(fsType)) {
-            CFStringInsert(newString, pathRg.location + pathRg.length, PATH_DELIM_AS_STRING_FOR_TYPE(fsType));
+        if (pathRg.length > 0 && CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) != '/') {
+            CFStringInsert(newString, pathRg.location + pathRg.length, CFSTR("/"));
             delta ++;
         }
         CFStringInsert(newString, pathRg.location + pathRg.length + delta, CFSTR(".."));
         delta += 2;
-        CFStringInsert(newString, pathRg.location + pathRg.length + delta, PATH_DELIM_AS_STRING_FOR_TYPE(fsType));
+        CFStringInsert(newString, pathRg.location + pathRg.length + delta, CFSTR("/"));
         delta ++;
         // We know we have "/../" at the end of the path; we wish to know if that's immediately preceded by "/." (but that "/." doesn't start the string), in which case we want to delete the "/.".
         if (pathRg.length + delta > 4 && CFStringGetCharacterAtIndex(newString, pathRg.location + pathRg.length + delta - 5) == '.') {
-            if (pathRg.length+delta > 7 && CFStringGetCharacterAtIndex(newString, pathRg.location + pathRg.length + delta - 6) == PATH_DELIM_FOR_TYPE(fsType)) {
+            if (pathRg.length+delta > 7 && CFStringGetCharacterAtIndex(newString, pathRg.location + pathRg.length + delta - 6) == '/') {
                 CFStringDelete(newString, CFRangeMake(pathRg.location + pathRg.length + delta - 6, 2));
             } else if (pathRg.length+delta == 5) {
                 CFStringDelete(newString, CFRangeMake(pathRg.location + pathRg.length + delta - 5, 2));
@@ -4424,21 +4500,15 @@ CFURLRef CFURLCreateCopyDeletingLastPathComponent(CFAllocatorRef allocator, CFUR
         }
     } else if (lastCompRg.location == pathRg.location) {
         CFStringReplace(newString, pathRg, CFSTR("."));
-        CFStringInsert(newString, 1, PATH_DELIM_AS_STRING_FOR_TYPE(fsType));
+        CFStringInsert(newString, 1, CFSTR("/"));
     } else {
         CFStringDelete(newString, CFRangeMake(lastCompRg.location, pathRg.location + pathRg.length - lastCompRg.location));
     }
-    if (fsType == FULL_URL_REPRESENTATION) {
-        result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
-    } else {
-        result = CFURLCreateWithFileSystemPathRelativeToBase(allocator, newString, fsType, true, url->_base);
-    }
+    result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
     CFRelease(newString);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( filePathURLCreated ) {
         CFRelease(url);
     }
-#endif
     return result;
 }
 
@@ -4446,16 +4516,14 @@ CFURLRef CFURLCreateCopyAppendingPathExtension(CFAllocatorRef allocator, CFURLRe
     CFMutableStringRef newString;
     CFURLRef result;
     CFRange rg;
-    CFURLPathStyle fsType;
     
     CFAssert1(url != NULL && extension != NULL, __kCFLogAssertion, "%s(): NULL argument not allowed", __PRETTY_FUNCTION__);
     url = _CFURLFromNSURL(url);
     __CFGenericValidateType(url, __kCFURLTypeID);
     __CFGenericValidateType(extension, CFStringGetTypeID());
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     Boolean filePathURLCreated = false;
-    
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( _CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
@@ -4471,37 +4539,22 @@ CFURLRef CFURLCreateCopyAppendingPathExtension(CFAllocatorRef allocator, CFURLRe
     
     rg = _rangeOfLastPathComponent(url);
     if (rg.location < 0) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
         if ( filePathURLCreated ) {
             CFRelease(url);
         }
-#endif
         return NULL; // No path
     }
-    fsType = URL_PATH_TYPE(url);
-    if (fsType != FULL_URL_REPRESENTATION && CFStringFindWithOptions(extension, PATH_DELIM_AS_STRING_FOR_TYPE(fsType), CFRangeMake(0, CFStringGetLength(extension)), 0, NULL)) {
-        _convertToURLRepresentation((struct __CFURL *)url);
-        fsType = FULL_URL_REPRESENTATION;
-        rg = _rangeOfLastPathComponent(url);
-    }
 
     newString = CFStringCreateMutableCopy(allocator, 0, url->_string);
     CFStringInsert(newString, rg.location + rg.length, CFSTR("."));
-    if (fsType == FULL_URL_REPRESENTATION) {
-        CFStringRef newExt = CFURLCreateStringByAddingPercentEscapes(allocator, extension, NULL, CFSTR(";?/"), (url->_flags & IS_OLD_UTF8_STYLE) ? kCFStringEncodingUTF8 : url->_encoding);
-        CFStringInsert(newString, rg.location + rg.length + 1, newExt);
-        CFRelease(newExt);
-        result =  _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
-    } else {
-        CFStringInsert(newString, rg.location + rg.length + 1, extension);
-        result = CFURLCreateWithFileSystemPathRelativeToBase(allocator, newString, fsType, (url->_flags & IS_DIRECTORY) != 0 ? true : false, url->_base);
-    }
+    CFStringRef newExt = CFURLCreateStringByAddingPercentEscapes(allocator, extension, NULL, CFSTR(";?/"), url->_encoding);
+    CFStringInsert(newString, rg.location + rg.length + 1, newExt);
+    CFRelease(newExt);
+    result =  _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
     CFRelease(newString);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( filePathURLCreated ) {
         CFRelease(url);
     }
-#endif
     return result;
 }
 
@@ -4513,9 +4566,8 @@ CFURLRef CFURLCreateCopyDeletingPathExtension(CFAllocatorRef allocator, CFURLRef
     url = _CFURLFromNSURL(url);
     __CFGenericValidateType(url, __kCFURLTypeID);
     
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     Boolean filePathURLCreated = false;
-
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( _CFURLIsFileReferenceURL(url) ) {
         // use a file path URL or fail
         CFURLRef filePathURL = CFURLCreateFilePathURL(allocator, url, NULL);
@@ -4536,20 +4588,14 @@ CFURLRef CFURLCreateCopyDeletingPathExtension(CFAllocatorRef allocator, CFURLRef
         CFMutableStringRef newString = CFStringCreateMutableCopy(allocator, 0, url->_string);
         dotRg.length = rg.location + rg.length - dotRg.location;
         CFStringDelete(newString, dotRg);
-        if (URL_PATH_TYPE(url) == FULL_URL_REPRESENTATION) {
-            result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
-        } else {
-            result = CFURLCreateWithFileSystemPathRelativeToBase(allocator, newString, URL_PATH_TYPE(url), (url->_flags & IS_DIRECTORY) != 0 ? true : false, url->_base);
-        }
+        result = _CFURLCreateWithArbitraryString(allocator, newString, url->_base);
         CFRelease(newString);
     } else {
         result = (CFURLRef)CFRetain(url);
     }
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if ( filePathURLCreated ) {
         CFRelease(url);
     }
-#endif
     return result;
 }
 
@@ -4613,6 +4659,41 @@ static CFArrayRef HFSPathToURLComponents(CFStringRef path, CFAllocatorRef alloc,
     }
     return newComponents;
 }
+
+typedef CFStringRef (*StringTransformation)(CFAllocatorRef, CFStringRef, CFIndex);
+static CFArrayRef copyStringArrayWithTransformation(CFArrayRef array, StringTransformation transformation) {
+    CFAllocatorRef alloc = CFGetAllocator(array);
+    CFMutableArrayRef mArray = NULL;
+    CFIndex i, c = CFArrayGetCount(array);
+    for (i = 0; i < c; i ++) {
+        CFStringRef origComp = (CFStringRef)CFArrayGetValueAtIndex(array, i);
+        CFStringRef unescapedComp = transformation(alloc, origComp, i);
+        if (!unescapedComp) { 
+            break;
+        }
+        if (unescapedComp != origComp) {
+            if (!mArray) {
+                mArray = CFArrayCreateMutableCopy(alloc, c, array);
+            }
+            CFArraySetValueAtIndex(mArray, i, unescapedComp);
+        }
+        CFRelease(unescapedComp);
+    }
+    if (i != c) {
+        if (mArray) CFRelease(mArray);
+        return NULL;
+    } else if (mArray) {
+        return mArray;
+    } else {
+        CFRetain(array);
+        return array;
+    }
+}
+
+static CFStringRef escapePathComponent(CFAllocatorRef alloc, CFStringRef origComponent, CFIndex componentIndex) {
+    return CFURLCreateStringByAddingPercentEscapes(alloc, origComponent, NULL, CFSTR(";?/"), kCFStringEncodingUTF8);
+}
+
 static CFStringRef HFSPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDir) {
     CFArrayRef components = HFSPathToURLComponents(path, alloc, isDir);
     CFArrayRef newComponents = components ? copyStringArrayWithTransformation(components, escapePathComponent) : NULL;
@@ -4648,16 +4729,16 @@ static void __CFURLCopyPropertyListKeysAndValues(CFURLRef url, CFTypeRef *keys,
         vals[0] = CFNumberCreate(alloc, kCFNumberSInt32Type, &urlType);
         vals[1] = CFURLGetString(url);
     } else {
-        SInt32 urlType = URL_PATH_TYPE(url);
+        SInt32 urlType = FULL_URL_REPRESENTATION;
         vals[0] = CFNumberCreate(alloc, kCFNumberSInt32Type, &urlType);
         if (url->_flags & IS_DIRECTORY) {
-            if (CFStringGetCharacterAtIndex(url->_string, CFStringGetLength(url->_string) - 1) == PATH_DELIM_FOR_TYPE(urlType)) {
+            if (CFStringGetCharacterAtIndex(url->_string, CFStringGetLength(url->_string) - 1) == '/') {
                 vals[1] = CFRetain(url->_string);
             } else {
-                vals[1] = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%c"), url->_string, PATH_DELIM_FOR_TYPE(urlType));
+                vals[1] = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%c"), url->_string, '/');
             }
         } else {
-            if (CFStringGetCharacterAtIndex(url->_string, CFStringGetLength(url->_string) - 1) != PATH_DELIM_FOR_TYPE(urlType)) {
+            if (CFStringGetCharacterAtIndex(url->_string, CFStringGetLength(url->_string) - 1) != '/') {
                 vals[1] = CFRetain(url->_string);
             } else {
                 vals[1] = CFStringCreateWithSubstring(alloc, url->_string, CFRangeMake(0, CFStringGetLength(url->_string) - 1));
@@ -4670,16 +4751,16 @@ static void __CFURLCopyPropertyListKeysAndValues(CFURLRef url, CFTypeRef *keys,
             vals[2] = CFNumberCreate(alloc, kCFNumberSInt32Type, &urlType);
             vals[3] = CFURLGetString(base);
         } else {
-            SInt32 urlType = URL_PATH_TYPE(base);
+            SInt32 urlType = FULL_URL_REPRESENTATION;
             vals[2] = CFNumberCreate(alloc, kCFNumberSInt32Type, &urlType);
             if (base->_flags & IS_DIRECTORY) {
-                if (CFStringGetCharacterAtIndex(base->_string, CFStringGetLength(base->_string) - 1) == PATH_DELIM_FOR_TYPE(urlType)) {
+                if (CFStringGetCharacterAtIndex(base->_string, CFStringGetLength(base->_string) - 1) == '/') {
                     vals[3] = CFRetain(base->_string);
                 } else {
-                    vals[3] = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%c"), base->_string, PATH_DELIM_FOR_TYPE(urlType));
+                    vals[3] = CFStringCreateWithFormat(alloc, NULL, CFSTR("%@%c"), base->_string, '/');
                 }
             } else {
-                if (CFStringGetCharacterAtIndex(base->_string, CFStringGetLength(base->_string) - 1) != PATH_DELIM_FOR_TYPE(urlType)) {
+                if (CFStringGetCharacterAtIndex(base->_string, CFStringGetLength(base->_string) - 1) != '/') {
                     vals[3] = CFRetain(base->_string);
                 } else {
                     vals[3] = CFStringCreateWithSubstring(alloc, base->_string, CFRangeMake(0, CFStringGetLength(base->_string) - 1));
@@ -4737,13 +4818,13 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp
         if (baseType == FULL_URL_REPRESENTATION) {
             baseURL = _CFURLCreateWithArbitraryString(alloc, baseString, NULL);
         } else {
-            baseURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, baseString, (CFURLPathStyle)baseType, CFStringGetCharacterAtIndex(baseString, CFStringGetLength(baseString)-1) == PATH_DELIM_FOR_TYPE(baseType), NULL);
+            baseURL = CFURLCreateWithFileSystemPathRelativeToBase(alloc, baseString, (CFURLPathStyle)baseType, CFStringGetCharacterAtIndex(baseString, CFStringGetLength(baseString)-1) == '/', NULL);
         }
     }
     if (urlType == FULL_URL_REPRESENTATION) {
         url = _CFURLCreateWithArbitraryString(alloc, string, baseURL);
     } else {
-        url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, string, (CFURLPathStyle)urlType, CFStringGetCharacterAtIndex(string, CFStringGetLength(string)-1) == PATH_DELIM_FOR_TYPE(urlType), baseURL);
+        url = CFURLCreateWithFileSystemPathRelativeToBase(alloc, string, (CFURLPathStyle)urlType, CFStringGetCharacterAtIndex(string, CFStringGetLength(string)-1) == '/', baseURL);
     }
     if (baseURL) CFRelease(baseURL);
     return url;
@@ -4753,39 +4834,76 @@ CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFProp
 Boolean _CFURLIsFileReferenceURL(CFURLRef url)
 {
     // returns TRUE if url is is a file URL whose path starts with a file ID reference
-    if ( url->_base ) {
-       return _CFURLIsFileReferenceURL( url->_base );
+    Boolean result = false;
+    CFURLRef baseURL = CFURLGetBaseURL(url);
+    if ( baseURL ) {
+       result = _CFURLIsFileReferenceURL(baseURL);
     }
-    if (URL_PATH_TYPE(url) == kCFURLFileReferencePathStyle) {
-        return true;
-    } else if (URL_PATH_TYPE(url) == FULL_URL_REPRESENTATION ) {
-       if (!(url->_flags & IS_PARSED)) {
-           _parseComponentsOfURL(url);
-       }
-       return ((url->_flags & HAS_FILE_SCHEME) && (url->_flags & PATH_HAS_FILE_ID));
+    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));
+        }
     }
-    // Otherwise, the path type is some other non-ID path type
-    return false;
+    return ( result );
 }
 
-Boolean _CFURLIsFileURL(CFURLRef url)
+static Boolean _CFURLHasFileURLScheme(CFURLRef url, Boolean *hasScheme)
 {
-    if ( url->_base ) {
-       return _CFURLIsFileURL( url->_base );
+    Boolean result;
+    CFURLRef baseURL = CFURLGetBaseURL(url);
+    
+    if ( baseURL ) {
+       result = _CFURLHasFileURLScheme(baseURL, hasScheme);
     }
-    if (URL_PATH_TYPE(url) != FULL_URL_REPRESENTATION) {
-        return true;
-    } else if (!(url->_flags & IS_PARSED)) {
-        _parseComponentsOfURL(url);
+    else {
+        if ( CF_IS_OBJC(__kCFURLTypeID, url) ) {
+            CFStringRef scheme = CFURLCopyScheme(url);
+            if ( scheme ) {
+                if ( scheme == kCFURLFileScheme ) {
+                    result = true;
+                }
+                else {
+                    result = CFStringCompare(scheme, kCFURLFileScheme, kCFCompareCaseInsensitive) == kCFCompareEqualTo;
+                }
+                if ( hasScheme ) {
+                    *hasScheme = true;
+                }
+                CFRelease(scheme);
+            }
+            else {
+                if ( hasScheme ) {
+                    *hasScheme = false;
+                }
+                result = false;
+            }
+        }
+        else {
+            if ( hasScheme ) {
+                *hasScheme = (url->_flags & HAS_SCHEME) != 0;
+            }
+            result = (_getSchemeTypeFromFlags(url->_flags) == kHasFileScheme);
+        }
     }
-    return (url->_flags & HAS_FILE_SCHEME) != 0;
+    return ( result );
 }
 
+Boolean _CFURLIsFileURL(CFURLRef url)
+{
+    Boolean result = _CFURLHasFileURLScheme(url, NULL);
+    return ( result );
+}
 
 CFURLRef CFURLCreateFilePathURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *error)
 {
     CFURLRef result = NULL;
-    if (!_CFURLIsFileURL(url)) {
+    Boolean hasScheme;
+    if (!_CFURLHasFileURLScheme(url, &hasScheme)) {
+        if ( !hasScheme ) {
+            CFLog(kCFLogLevelWarning, CFSTR("CFURLCreateFilePathURL failed because it was passed this URL which has no scheme: %@"), url);
+        }
         if ( error ) {
             *error = CFErrorCreate( kCFAllocatorDefault, kCFErrorDomainCocoa, kCFURLReadUnsupportedSchemeError, NULL );
         }
@@ -4799,12 +4917,12 @@ CFURLRef CFURLCreateFilePathURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *
         
        if ( CFURLGetBaseURL( url )) {
            CFURLRef absURL = CFURLCopyAbsoluteURL( url );
-           fsPath = CFURLCopyFileSystemPath( absURL, kCFURLPOSIXPathStyle );
+           fsPath = CFURLCreateStringWithFileSystemPath(CFGetAllocator(absURL), absURL, kCFURLPOSIXPathStyle, false);
            netLoc = CFURLCopyNetLocation( absURL );
            rSpec = CFURLCopyResourceSpecifier( absURL );
            CFRelease( absURL );
        } else {
-           fsPath = CFURLCopyFileSystemPath( url, kCFURLPOSIXPathStyle );
+           fsPath = CFURLCreateStringWithFileSystemPath(CFGetAllocator(url), url, kCFURLPOSIXPathStyle, false);
            netLoc = CFURLCopyNetLocation( url );
            rSpec = CFURLCopyResourceSpecifier( url );
        }
@@ -4817,7 +4935,7 @@ CFURLRef CFURLCreateFilePathURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *
            CFRelease( fsPath );            
        } else {
            if ( error ) { 
-               // Would be better here to get an underlying error back from CFURLCopyFileSystemPath
+               // Would be better here to get an underlying error back from CFURLCreateStringWithFileSystemPath
                *error = CFErrorCreate( kCFAllocatorDefault, kCFErrorDomainCocoa, kCFURLNoSuchResourceError, NULL );
            }
            result = NULL;
@@ -4834,6 +4952,6 @@ CFURLRef CFURLCreateFilePathURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *
 
 #endif
 
-CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *error) {
-    return NULL;
-}
+
+CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef alloc, CFURLRef url, CFErrorRef *error) { return NULL; }
+
diff --git a/CFURL.h b/CFURL.h
index 28052c8356b8df631556f8af8bb915a10f4250c6..8eeb52523677ab6486819c24e83f8d56fe38b006 100644 (file)
--- a/CFURL.h
+++ b/CFURL.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFURL.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFURL__)
 #include <CoreFoundation/CFData.h>
 #include <CoreFoundation/CFError.h>
 #include <CoreFoundation/CFString.h>
-#include <CoreFoundation/CFNumber.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
-enum {
+typedef CF_ENUM(CFIndex, CFURLPathStyle) {
     kCFURLPOSIXPathStyle = 0,
-    kCFURLHFSPathStyle,
+    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. */
     kCFURLWindowsPathStyle
 };
-typedef CFIndex CFURLPathStyle;
     
 typedef const struct __CFURL * CFURLRef;
 
@@ -297,7 +296,7 @@ CFURLRef CFURLCreateCopyDeletingPathExtension(CFAllocatorRef allocator, CFURLRef
 CF_EXPORT
 CFIndex CFURLGetBytes(CFURLRef url, UInt8 *buffer, CFIndex bufferLength);
 
-enum {
+typedef CF_ENUM(CFIndex, CFURLComponentType) {
        kCFURLComponentScheme = 1,
        kCFURLComponentNetLocation = 2,
        kCFURLComponentPath = 3,
@@ -312,7 +311,6 @@ enum {
        kCFURLComponentQuery = 11,
        kCFURLComponentFragment = 12
 };
-typedef CFIndex CFURLComponentType;
  
 /* 
 Gets the  range of the requested component in the bytes of url, as
@@ -412,130 +410,264 @@ CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CF
 
 
 #if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION
+CF_IMPLICIT_BRIDGING_DISABLED
 
-/* Returns a file reference URL, a path-idependent form of file URL. */
-/* Converts a file path URL if necessary. For non-file URLs, returns NULL. */
-/* Also returns NULL when the conversion fails because the target resource doesn't exist. */
-/* Optional output error: The error is set to a valid CFErrorRef when the function */
-/* result is NULL. A valid output error must be released by the caller. */
+/*
+    CFURLCreateFileReferenceURL
+    
+    Returns a new file reference URL that refers to the same resource as a specified URL.
+
+    Parameters
+        allocator
+            The memory allocator for creating the new URL.
+        url
+            The file URL specifying the resource.
+        error
+            On output when the result is NULL, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        The new file reference URL, or NULL if an error occurs.
+
+    Discussion
+        File reference URLs use a URL path syntax that identifies a file system object by reference, not by path. This form of file URL remains valid when the file system path of the URL’s underlying resource changes. An error will occur if the url parameter is not a file URL. File reference URLs cannot be created to file system objects which do not exist or are not reachable. In some areas of the file system hierarchy, file reference URLs cannot be generated to the leaf node of the URL path. A file reference URL's path should never be persistently stored because is not valid across system restarts, and across remounts of volumes -- if you want to create a persistent reference to a file system object, use a bookmark (see CFURLCreateBookmarkData). If this function returns NULL, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Returns a file path URL, converting a file reference URL if necessary. */
-/* For non-file URLs, returns NULL. Also returns NULL when the conversion fails */
-/* because the target resource doesn't exist. */
-/* Optional output error: The error is set to a valid CFErrorRef when the function */
-/* result is NULL. A valid output error must be released by the caller. */
+/*
+    CFURLCreateFilePathURL
+    
+    Returns a new file path URL that refers to the same resource as a specified URL.
+
+    Parameters
+        allocator
+            The memory allocator for creating the new URL.
+        url
+            The file URL specifying the resource.
+        error
+            On output when the result is NULL, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        The new file path URL, or NULL if an error occurs.
+
+    Discussion
+        File path URLs use a file system style path. An error will occur if the url parameter is not a file URL. A file reference URL's resource must exist and be reachable to be converted to a file path URL. If this function returns NULL, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 CFURLRef CFURLCreateFilePathURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
+CF_IMPLICIT_BRIDGING_ENABLED
 #endif
 
 
 
 #if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION
+CF_IMPLICIT_BRIDGING_DISABLED
 
-/* The following APIs provide efficient access to resource properties. Properties 
-are identified by keys, and values are represented as Core Foundation objects. The 
-type of each value is fixed for each property, e.g. the modification date is a CFDateRef, 
-the file size is a CFNumberRef.
+/* Resource access
 
-Values are fetched on-demand, synchronously, from the resource's backing store. They
-are cached and reused when fetched again through the same URL instance, until the 
-client clears the value. The client has complete control over the cache lifetime.
+    The behavior of resource value caching is slightly different between the NSURL and CFURL API.
 
-Some resource property values can be changed, given sufficient access permission to the resource. 
-When a resource property value is set, the change is written to backing store synchronously.
-*/
+    When the NSURL methods which get, set, or use cached resource values are used from the main thread, resource values cached by the URL (except those added as temporary properties) are invalidated the next time the main thread's run loop runs.
 
-/* Assigns the requested resource property value to the typeRefValuePtr output */
-/* argument. Returns true if the output value was set. Note that NULL is a valid output value. */
-/* The value is fetched synchronously from the resource backing store only if a value is not */
-/* already cached. The type of the output value type varies by property (see property key */
-/* definitions). Returns false if an error occurs. Optional output error: the error is set to */
-/* a valid CFErrorRef when the function returns false. A valid output error must be */
-/* released by the caller. */
+    The CFURL functions do not automatically clear any resource values cached by the URL. The client has complete control over the cache lifetime. If you are using CFURL API, you must use CFURLClearResourcePropertyCacheForKey or CFURLClearResourcePropertyCache to clear cached resource values.
+ */
+
+
+/*
+    CFURLCopyResourcePropertyForKey
+    
+    Returns the resource value identified by a given resource key.
+
+    Parameters
+        url
+            The URL specifying the resource.
+        key
+            The resource key that identifies the resource property.
+        propertyValueTypeRefPtr
+            On output when the result is true, the resource value or NULL.
+        error
+            On output when the result is false, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        true if propertyValueTypeRefPtr is successfully populated; false if an error occurs.
+
+    Discussion
+        CFURLCopyResourcePropertyForKey first checks if the URL object already caches the resource value. If so, it returns the cached resource value to the caller. If not, then CFURLCopyResourcePropertyForKey synchronously obtains the resource value from the backing store, adds the resource value to the URL object's cache, and returns the resource value to the caller. The type of the resource value varies by resource property (see resource key definitions). If this function returns true and propertyValueTypeRefPtr is populated with NULL, it means the resource property is not available for the specified resource and no errors occurred when determining the resource property was not available. If this function returns false, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 Boolean CFURLCopyResourcePropertyForKey(CFURLRef url, CFStringRef key, void *propertyValueTypeRefPtr, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Returns any number of resource property values as a dictionary of keyed values. */
-/* The requested values are specified as an array of keys to appear in */
-/* the result dictionary. Values are fetched synchronously from the resource backing store unless */
-/* already cached. The type of each value type varies (see key definitions, below). */
-/* Returns an empty dictionary if no values are found. Returns NULL when an error occurs. */
-/* Optional output error: the error is set to a valid CFErrorRef when the */
-/* function returns NULL. A valid output error must be released by the caller. */
+/*
+    CFURLCopyResourcePropertiesForKeys
+    
+    Returns the resource values identified by specified array of resource keys.
+
+    Parameters
+        url
+            The URL specifying the resource.
+        keys
+            An array of resource keys that identify the resource properties.
+        error
+            On output when the result is NULL, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        A dictionary of resource values indexed by resource key; NULL if an error occurs.
+
+    Discussion
+        CFURLCopyResourcePropertiesForKeys first checks if the URL object already caches the resource values. If so, it returns the cached resource values to the caller. If not, then CFURLCopyResourcePropertyForKey synchronously obtains the resource values from the backing store, adds the resource values to the URL object's cache, and returns the resource values to the caller. The type of the resource values vary by property (see resource key definitions). If the result dictionary does not contain a resource value for one or more of the requested resource keys, it means those resource properties are not available for the specified resource and no errors occurred when determining those resource properties were not available. If this function returns NULL, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 CFDictionaryRef CFURLCopyResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Changes a resource property value. Synchronously writes the value to the resource backing */
-/* store. The input value type must be a valid CFTypeRef, of the type required for the specified */
-/* key (see key definitions). Returns true upon success, false when an error occurs. */
-/* Optional output error: the error is set to a valid CFErrorRef when the function */
-/* returns false. A valid output error must be released by the caller. */
-/* Note that some values are read-only. Attempting to set a read-only property */
-/* results in an error. */
+/*
+    CFURLSetResourcePropertyForKey
+    
+    Sets the resource value identified by a given resource key.
+
+    Parameters
+        url
+            The URL specifying the resource.
+        key
+            The resource key that identifies the resource property.
+        propertyValue
+            The resource value.
+        error
+            On output when the result is false, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        true if the attempt to set the resource value completed with no errors; otherwise, false.
+
+    Discussion
+        CFURLSetResourcePropertyForKey writes the new resource value out to the backing store. Attempts to set a read-only resource property or to set a resource property not supported by the resource are ignored and are not considered errors. If this function returns false, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 Boolean CFURLSetResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Changes any number of resource property values, specified as a dictionary of keyed values. */
-/* Synchronously writes values to the resource backing store. The input dictionary's value types must conform */
-/* to the type required for its key (see key definitions). Returns true when all values are set successfully, */
-/* and false if an error occurs. Optional output error: the error is set to a valid CFErrorRef when the function returns */
-/* false. A valid output error must be released by the caller. When an error occurs after some properties have been */
-/* successfully changed, the userInfo dictionary in the error contains an array of keys that */
-/* were not set with the dictionary key kCFURLKeysOfUnsetValuesKey. */
-/* Note that some values are read-only. Attempting to set a read-only value results in an error. */
+/*
+    CFURLSetResourcePropertiesForKeys
+    
+    Sets any number of resource values of a URL's resource.
+
+    Parameters
+        url
+            The URL specifying the resource.
+        keyedPropertyValues
+            A dictionary of resource values indexed by resource keys.
+        error
+            On output when the result is false, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        true if the attempt to set the resource values completed with no errors; otherwise, false.
+
+    Discussion
+        CFURLSetResourcePropertiesForKeys writes the new resource values out to the backing store. Attempts to set read-only resource properties or to set resource properties not supported by the resource are ignored and are not considered errors. If an error occurs after some resource properties have been successfully changed, the userInfo dictionary in the returned error contains an array of resource keys that were not set with the key kCFURLKeysOfUnsetValuesKey. The order in which the resource values are set is not defined. If you need to guarantee the order resource values are set, you should make multiple requests to CFURLSetResourcePropertiesForKeys or CFURLSetResourcePropertyForKey to guarantee the order. If this function returns false, the optional error is populated. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 Boolean CFURLSetResourcePropertiesForKeys(CFURLRef url, CFDictionaryRef keyedPropertyValues, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
 
 CF_EXPORT
 const CFStringRef kCFURLKeysOfUnsetValuesKey CF_AVAILABLE(10_7, 5_0);
-    /* If CFURLSetResourcePropertiesForKeys returns an error, this is key in the error's userInfo dictionary to the array of keys of unset values. */
+    /* Key for the resource properties that have not been set after the CFURLSetResourcePropertiesForKeys function returns an error, returned as an array of of CFString objects. */
 
 
-/* Discards a cached property value for a specific key */
+/*
+    CFURLClearResourcePropertyCacheForKey
+    
+    Discards a cached resource value of a URL.
+
+    Parameters
+        url
+            The URL specifying the resource.
+        key
+            The resource key that identifies the resource property.
+
+    Discussion
+        Discarding a cached resource value may discard other cached resource values, because some resource values are cached as a set of values and because some resource values depend on other resource values (temporary properties have no dependencies). This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 void CFURLClearResourcePropertyCacheForKey(CFURLRef url, CFStringRef key) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Discards all cached property values */
+/*
+    CFURLClearResourcePropertyCache
+    
+    Discards all cached resource values of a URL.
+
+    Parameters
+        url
+            The URL specifying the resource.
+
+    Discussion
+        All temporary properties are also cleared from the URL object's cache. This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 void CFURLClearResourcePropertyCache(CFURLRef url) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Sets a temporary property value. Temporary properties exist only in memory and are never */
-/* written to resource backing store. Once set, a temporary property value can be fetched */
-/* with CFURLCopyResourcePropertyForKey and CFURLCopyResourcePropertiesForKeys. Temporary property */
-/* values are for client use. Values must be valid Core Foundation types, and will be retained. */
-/* To remove a temporary property value, use CFURLClearResourcePropertyCacheForKey. */
+/*
+    CFURLSetTemporaryResourcePropertyForKey
+    
+    Sets a temporary resource value on the URL object.
+
+    Parameters
+        url
+            The URL object.
+        key
+            The resource key that identifies the temporary resource property.
+        propertyValue
+            The resource value.
+
+    Discussion
+        Temporary properties are for client use. Temporary properties exist only in memory and are never written to the resource's backing store. Once set, a temporary value can be copied from the URL object with CFURLCopyResourcePropertyForKey and CFURLCopyResourcePropertiesForKeys. To remove a temporary value from the URL object, use CFURLClearResourcePropertyCacheForKey. Temporary values must be valid Core Foundation types, and will be retained by CFURLSetTemporaryResourcePropertyForKey. Care should be taken to ensure the key that identifies a temporary resource property is unique and does not conflict with system defined keys (using reverse domain name notation in your temporary resource property keys is recommended). This function is currently applicable only to URLs for file system resources.
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 void CFURLSetTemporaryResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue) CF_AVAILABLE(10_6, 4_0);
 
 
-/* Synchronously checks if the resource's backing store is reachable and the resource exists, */
-/* returning true if so. The optional output error can be used to determine the type of reachability */
-/* failure (e.g., file not found, network error, etc.). The error is set to a valid CFErrorRef if */
-/* and only if the function returns false. A valid output error must be released by */
-/* the caller. Checking for resource existence and reachability is appropriate when making decisions */
-/* that do not require other immediate operations on the resource. An example would be */
-/* periodic maintenance of UI state that depends on the existence of a particular document. */
-/* When performing an operation such as opening a file, it is more efficient to */
-/* simply try the operation and handle failures than to check first for reachability. */
+/*
+    CFURLResourceIsReachable
+    
+    Returns whether the URL's resource exists and is reachable.
+
+    Parameters
+        url
+            The URL object.
+        error
+            On output when the result is false, the error that occurred. This parameter is optional; if you do not wish the error returned, pass NULL here. The caller is responsible for releasing a valid output error.
+
+    Return Value
+        true if the resource is reachable; otherwise, false.
+
+    Discussion
+        CFURLResourceIsReachable synchronously checks if the resource's backing store is reachable. Checking reachability is appropriate when making decisions that do not require other immediate operations on the resource, e.g. periodic maintenance of UI state that depends on the existence of a specific document. When performing operations such as opening a file or copying resource properties, it is more efficient to simply try the operation and handle failures. This function is currently applicable only to URLs for file system resources. If this function returns false, the optional error is populated. For other URL types, false is returned. 
+        Symbol is present in iOS 4, but performs no operation.
+ */
 CF_EXPORT
 Boolean CFURLResourceIsReachable(CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0);
 
+CF_IMPLICIT_BRIDGING_ENABLED
+
 
 /* Properties of File System Resources */
 
 CF_EXPORT 
 const CFStringRef kCFURLNameKey CF_AVAILABLE(10_6, 4_0);
-    /* The resource name provided by the file system (value type CFString) */
+    /* The resource name provided by the file system (Read-write, value type CFString) */
 
 CF_EXPORT
 const CFStringRef kCFURLLocalizedNameKey CF_AVAILABLE(10_6, 4_0);
@@ -559,27 +691,27 @@ const CFStringRef kCFURLIsVolumeKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLIsPackageKey CF_AVAILABLE(10_6, 4_0);
-    /* True for packaged directories (value type CFBoolean) */
+    /* True for packaged directories (Read-only 10_6 and 10_7, read-write 10_8, value type CFBoolean). Note: You can only set or clear this property on directories; if you try to set this property on non-directory objects, the property is ignored. If the directory is a package for some other reason (extension type, etc), setting this property to false will have no effect. */
 
 CF_EXPORT
 const CFStringRef kCFURLIsSystemImmutableKey CF_AVAILABLE(10_6, 4_0);
-    /* True for system-immutable resources (value type CFBoolean) */
+    /* True for system-immutable resources (Read-write, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLIsUserImmutableKey CF_AVAILABLE(10_6, 4_0);
-    /* True for user-immutable resources (value type CFBoolean) */
+    /* True for user-immutable resources (Read-write, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLIsHiddenKey CF_AVAILABLE(10_6, 4_0);
-    /* True for resources normally hidden from users (value type CFBoolean) */
+    /* True for resources normally not displayed to users (Read-write, value type CFBoolean). Note: If the resource is a hidden because its name starts with a period, setting this property to false will not change the property. */
 
 CF_EXPORT
 const CFStringRef kCFURLHasHiddenExtensionKey CF_AVAILABLE(10_6, 4_0);
-    /* True for resources whose filename extension is hidden (value type CFBoolean) */
+    /* True for resources whose filename extension is removed from the localized name property (Read-write, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLCreationDateKey CF_AVAILABLE(10_6, 4_0);
-    /* The date the resource was created (value type CFDate) */
+    /* The date the resource was created (Read-write, value type CFDate) */
 
 CF_EXPORT
 const CFStringRef kCFURLContentAccessDateKey CF_AVAILABLE(10_6, 4_0);
@@ -587,19 +719,19 @@ const CFStringRef kCFURLContentAccessDateKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLContentModificationDateKey CF_AVAILABLE(10_6, 4_0);
-    /* The time the resource content was last modified (value type CFDate) */
+    /* The time the resource content was last modified (Read-write, value type CFDate) */
 
 CF_EXPORT
 const CFStringRef kCFURLAttributeModificationDateKey CF_AVAILABLE(10_6, 4_0);
-    /* The time the resource's attributes were last modified (value type CFDate) */
+    /* The time the resource's attributes were last modified (Read-write, value type CFDate) */
 
 CF_EXPORT
 const CFStringRef kCFURLLinkCountKey CF_AVAILABLE(10_6, 4_0);
-    /* Number of hard links to the resource (Read-only, CFNumber) */
+    /* Number of hard links to the resource (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLParentDirectoryURLKey CF_AVAILABLE(10_6, 4_0);
-    /* URL of the parent directory, if any (Read-only, value type CFURL) */
+    /* The resource's parent directory, if any (Read-only, value type CFURL) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeURLKey CF_AVAILABLE(10_6, 4_0);
@@ -607,19 +739,19 @@ const CFStringRef kCFURLVolumeURLKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLTypeIdentifierKey CF_AVAILABLE(10_6, 4_0);
-    /* Uniform type identifier for the resource (Read-only, value type CFString) */
+    /* Uniform type identifier (UTI) for the resource (Read-only, value type CFString) */
 
 CF_EXPORT
 const CFStringRef kCFURLLocalizedTypeDescriptionKey CF_AVAILABLE(10_6, 4_0);
-    /* User-visible type or "kind" descriptiopn (Read-only, value type CFString) */
+    /* User-visible type or "kind" description (Read-only, value type CFString) */
 
 CF_EXPORT
 const CFStringRef kCFURLLabelNumberKey CF_AVAILABLE(10_6, 4_0);
-    /* The label number assigned to the resource (value type CFNumber) */
+    /* The label number assigned to the resource (Read-write, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLLabelColorKey CF_AVAILABLE(10_6, 4_0);
-    /* The color of the assigned label (Read-only, value type CGColorRef, must link with Application Services) */
+    /* The color of the assigned label (Currently not implemented, value type CGColorRef, must link with Application Services) */
 
 CF_EXPORT
 const CFStringRef kCFURLLocalizedLabelKey CF_AVAILABLE(10_6, 4_0);
@@ -631,7 +763,7 @@ const CFStringRef kCFURLEffectiveIconKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLCustomIconKey CF_AVAILABLE(10_6, 4_0);
-    /* The custom icon assigned to the resource, if any (value type CGImageRef, must link with Application Services) */
+    /* The custom icon assigned to the resource, if any (Currently not implemented, value type CGImageRef, must link with Application Services) */
 
 CF_EXPORT
 const CFStringRef kCFURLFileResourceIdentifierKey CF_AVAILABLE(10_7, 5_0);
@@ -659,7 +791,19 @@ const CFStringRef kCFURLIsExecutableKey CF_AVAILABLE(10_7, 5_0);
 
 CF_EXPORT
 const CFStringRef kCFURLFileSecurityKey CF_AVAILABLE(10_7, 5_0);
-    /* The file system object's security information encapsulated in a CFFileSecurity object. (Value type CFFileSecurity) */
+    /* The file system object's security information encapsulated in a CFFileSecurity object. (Read-write, value type CFFileSecurity) */
+
+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 kCFURLPathKey CF_AVAILABLE(10_8, 6_0);
+    /* the URL's path as a file system path (Read-only, value type CFString) */
+
+CF_EXPORT
+const CFStringRef kCFURLIsMountTriggerKey CF_AVAILABLE(10_7, 4_0);
+    /* true if this URL is a file system trigger directory. Traversing or opening a file system trigger will cause an attempt to mount a file system on the trigger directory. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLFileResourceTypeKey CF_AVAILABLE(10_7, 5_0);
@@ -687,32 +831,28 @@ const CFStringRef kCFURLFileResourceTypeUnknown CF_AVAILABLE(10_7, 5_0);
 
 CF_EXPORT
 const CFStringRef kCFURLFileSizeKey CF_AVAILABLE(10_6, 4_0);
-    /* Total file size, in bytes (Read-only, value type CFNumber) */
+    /* Total file size in bytes (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLFileAllocatedSizeKey CF_AVAILABLE(10_6, 4_0);
-    /* Total size of blocks allocated (Read-only, value type CFNumber) */
+    /* Total size allocated on disk for the file in bytes (number of blocks times block size) (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLTotalFileSizeKey CF_AVAILABLE(10_7, 5_0);
-    /* Total displayable size of the file, in bytes (this may include space used by metadata), or NULL if not available. (Read-only, value type CFNumber) */
+    /* Total displayable size of the file in bytes (this may include space used by metadata), or NULL if not available. (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLTotalFileAllocatedSizeKey CF_AVAILABLE(10_7, 5_0);
-    /* Total allocated size of the file, in bytes (this may include space used by metadata), or NULL if not available. This can be less than the value returned by kCFURLTotalFileSizeKey if the resource is compressed. (Read-only, value type CFNumber) */
+    /* Total allocated size of the file in bytes (this may include space used by metadata), or NULL if not available. This can be less than the value returned by kCFURLTotalFileSizeKey if the resource is compressed. (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLIsAliasFileKey CF_AVAILABLE(10_6, 4_0);
-    /*  true if the url is a Finder alias file, false otherwise ( Read-only, value type CFBooleanRef) */
-
-CF_EXPORT
-const CFStringRef kCFURLIsMountTriggerKey CF_AVAILABLE(10_7, 4_0);
-    /* true if this URL is a file system trigger directory. Traversing or opening a file system trigger will cause an attempt to mount a file system on the trigger directory. (Read-only, value type CFBoolean) */
+    /*  true if the resource is a Finder alias file or a symlink, false otherwise ( Read-only, value type CFBooleanRef) */
 
 
 /* Volume Properties */
 
-/* For convenience, volume properties may be requested from any resource on a volume. */
+/* As a convenience, volume properties can be requested from any file system URL. The value returned will reflect the property value for the volume on which the resource is located. */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeLocalizedFormatDescriptionKey CF_AVAILABLE(10_6, 4_0);
@@ -724,7 +864,7 @@ const CFStringRef kCFURLVolumeTotalCapacityKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeAvailableCapacityKey CF_AVAILABLE(10_6, 4_0);
-    /* Total free space, in bytes (Read-only, value type CFNumber) */
+    /* Total free space in bytes (Read-only, value type CFNumber) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeResourceCountKey CF_AVAILABLE(10_6, 4_0);
@@ -732,39 +872,39 @@ const CFStringRef kCFURLVolumeResourceCountKey CF_AVAILABLE(10_6, 4_0);
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsPersistentIDsKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format supports persistent object identifiers and can look up file system objects by their IDs (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsSymbolicLinksKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format supports symbolic links (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsHardLinksKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format supports hard links (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsJournalingKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format supports a journal used to speed recovery in case of unplanned restart (such as a power outage or crash). This does not necessarily mean the volume is actively using a journal. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeIsJournalingKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume is currently using a journal for speedy recovery after an unplanned restart. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsSparseFilesKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format supports sparse files, that is, files which can have 'holes' that have never been written to, and thus do not consume space on disk. A sparse file may have an allocated size on disk that is less than its logical length. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsZeroRunsKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* For security reasons, parts of a file (runs) that have never been written to must appear to contain zeroes. true if the volume keeps track of allocated but unwritten runs of a file so that it can substitute zeroes without actually writing zeroes to the media. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsCaseSensitiveNamesKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format treats upper and lower case characters in file and directory names as different. Otherwise an upper case character is equivalent to a lower case character, and you can't have two names that differ solely in the case of the characters. (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsCasePreservedNamesKey CF_AVAILABLE(10_6, 4_0);
-    /* Read-only, value type CFBoolean */
+    /* true if the volume format preserves the case of file and directory names.  Otherwise the volume may change the case of some characters (typically making them all upper or all lower case). (Read-only, value type CFBoolean) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeSupportsRootDirectoryDatesKey CF_AVAILABLE(10_7, 5_0);
@@ -832,7 +972,7 @@ const CFStringRef kCFURLVolumeUUIDStringKey CF_AVAILABLE(10_7, 5_0);
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeNameKey CF_AVAILABLE(10_7, 5_0);
-    /* The name of the volume (settable if kCFURLVolumeSupportsRenamingKey is true, value type CFString) */
+    /* The name of the volume (Read-write, settable if kCFURLVolumeSupportsRenamingKey is true and permissions allow, value type CFString) */
 
 CF_EXPORT
 const CFStringRef kCFURLVolumeLocalizedNameKey CF_AVAILABLE(10_7, 5_0);
@@ -865,41 +1005,36 @@ 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_AVAILABLE(10_7, 5_0);
-    /* [0-100] percent of data downloaded. (Read-only, value type double CFNumber) */
+const CFStringRef kCFURLUbiquitousItemPercentDownloadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0);
+    /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead */
 
 CF_EXPORT
-const CFStringRef kCFURLUbiquitousItemPercentUploadedKey CF_AVAILABLE(10_7, 5_0);
-    /* [0-100] percent of data downloaded. (Read-only, value type double CFNumber) */
+const CFStringRef kCFURLUbiquitousItemPercentUploadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0);
+    /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead */
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkCreationOptions) {
     kCFURLBookmarkCreationPreferFileIDResolutionMask = ( 1UL << 8 ),  // At resolution time, this alias will prefer resolving by the embedded fileID to the path
     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
+    kCFURLBookmarkCreationSecurityScopeAllowOnlyReadAccess CF_ENUM_AVAILABLE(10_7,NA) = ( 1UL << 12 ), // Mac OS X 10.7.3 and later, if used with kCFURLBookmarkCreationWithSecurityScope, at resolution time only read access to the resource will be granted
 };
 
-#if MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED
-enum {
-    kCFURLBookmarkCreationWithSecurityScope = ( 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
-    kCFURLBookmarkCreationSecurityScopeAllowOnlyReadAccess = ( 1UL << 12 ), // Mac OS X 10.7.3 and later, if used with kCFURLBookmarkCreationWithSecurityScope, at resolution time only read access to the resource will be granted
-};
-#endif
-typedef CFOptionFlags CFURLBookmarkCreationOptions;
-
 enum  {
     kCFBookmarkResolutionWithoutUIMask = ( 1UL << 8 ),         // don't perform any UI during bookmark resolution
     kCFBookmarkResolutionWithoutMountingMask = ( 1UL << 9 ),   // don't mount a volume during bookmark resolution
 };
 
-#if MAC_OS_X_VERSION_10_7 <= MAC_OS_X_VERSION_MAX_ALLOWED
 enum {
-    kCFURLBookmarkResolutionWithSecurityScope = ( 1UL << 10 ), // Mac OS X 10.7.3 and later, extract the security scope included at creation time to provide the ability to access the resource.
+    kCFURLBookmarkResolutionWithSecurityScope CF_ENUM_AVAILABLE(10_7,NA) = ( 1UL << 10 ), // Mac OS X 10.7.3 and later, extract the security scope included at creation time to provide the ability to access the resource.
 };
-#endif
+
 typedef CFOptionFlags CFURLBookmarkResolutionOptions;
 
 typedef CFOptionFlags CFURLBookmarkFileCreationOptions;
 
+CF_IMPLICIT_BRIDGING_DISABLED
+
 /*     @function CFURLCreateBookmarkData
        @discussion     Create a CFDataRef containing an externalizable representation from a CFURLRef, modified with the given options, including ( at the minimum ) any
                properties in the propertiesToInclude array which are retrievable from the given url.
@@ -997,6 +1132,8 @@ Boolean CFURLWriteBookmarkDataToFile( CFDataRef bookmarkRef, CFURLRef fileURL, C
 CF_EXPORT
 CFDataRef CFURLCreateBookmarkDataFromAliasRecord ( CFAllocatorRef allocatorRef, CFDataRef aliasRecordDataRef ) CF_AVAILABLE_MAC(10_6);
 
+CF_IMPLICIT_BRIDGING_ENABLED
+
 /*!     @function      CFURLStartAccessingSecurityScopedResource
         @discussion    Given a CFURLRef created by resolving a bookmark data created with security scope, make the resource referenced by the
                         url accessible to the process.  When access to this resource is no longer needed the client should call
@@ -1006,17 +1143,20 @@ CFDataRef CFURLCreateBookmarkDataFromAliasRecord ( CFAllocatorRef allocatorRef,
         @result        returns TRUE if access was granted and FALSE if the url does not reference a security scoped resource, or if some error occurred
                         which didn't allow access to be granted
  */
+CF_EXPORT
 Boolean CFURLStartAccessingSecurityScopedResource(CFURLRef url) CF_AVAILABLE(10_7, NA); // Available in MacOS X 10.7.3 and later
 
 /*!     @function      CFURLStopAccessingSecurityScopedResource
         @discussion    Revokes the access granted to the url by a prior successful call to CFURLStartAccessingSecurityScopedResource().
         @param url     the CFURLRef for the resource to stop accessing.
  */
+CF_EXPORT
 void CFURLStopAccessingSecurityScopedResource(CFURLRef url) CF_AVAILABLE(10_7, NA);
 
 #endif /* TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE */
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFURL__ */
 
index e7d3eeeb7a66b06169c50a358304afca7fc83044..d0b0a4d9064d7d3cbe419c0594a979dd89054731 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFURLAccess.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Chris Linn
 */
 
@@ -39,7 +39,7 @@ CFData read/write routines
 #include <CoreFoundation/CFNumber.h>
 #include <string.h>
 #include <ctype.h>
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #include <stdlib.h>
 #include <unistd.h>
 #include <dirent.h>
@@ -48,17 +48,15 @@ CFData read/write routines
 #include <pwd.h>
 #include <fcntl.h>
 #elif DEPLOYMENT_TARGET_WINDOWS
-//#include <winsock2.h>
 #include <io.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <fcntl.h>
-#include <errno.h>
 #include <ctype.h>
 #else
 #error Unknown or unspecified DEPLOYMENT_TARGET
 #endif
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <dlfcn.h>
 #endif
 
@@ -250,7 +248,7 @@ static Boolean _CFFileURLWritePropertiesToResource(CFURLRef url, CFDictionaryRef
                 CFNumberRef modeNum = (CFNumberRef)value;
                 CFNumberGetValue(modeNum, kCFNumberSInt32Type, &mode);
             } else {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 #define MODE_TYPE mode_t
 #elif DEPLOYMENT_TARGET_WINDOWS
 #define MODE_TYPE uint16_t
@@ -288,7 +286,7 @@ static Boolean _CFFileURLCreateDataAndPropertiesFromResource(CFAllocatorRef allo
             alloc = (CFAllocatorRef)CFRetain(__CFGetDefaultAllocator());
             releaseAlloc = true;
         }
-        if (!_CFReadBytesFromFile(alloc, url, &bytes, &length, 0)) {
+        if (!_CFReadBytesFromFile(alloc, url, &bytes, &length, 0, 0)) {
             if (errorCode) *errorCode = kCFURLUnknownError;
             *fetchedData = NULL;
             success = false;
@@ -772,22 +770,13 @@ Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef data, CFDi
         if (data) {
             if (CFURLHasDirectoryPath(url)) {
                 // Create a directory
-#if DEPLOYMENT_TARGET_WINDOWS
-               wchar_t cPath[CFMaxPathSize];
-                if (!_CFURLGetWideFileSystemRepresentation(url, true, cPath, CFMaxPathSize))
-#else
                 char cPath[CFMaxPathSize];
                 if (!CFURLGetFileSystemRepresentation(url, true, (unsigned char *)cPath, CFMaxPathSize))
-#endif
                 {
                     if (errorCode) *errorCode = kCFURLImproperArgumentsError;
                     success = false;
                 } else {
-#if DEPLOYMENT_TARGET_WINDOWS
-                    success = _CFCreateDirectoryWide(cPath);
-#else
                     success = _CFCreateDirectory(cPath);
-#endif
                     if (!success && errorCode) *errorCode = kCFURLUnknownError;
                 }
             } else {
index 7558b44283ae979baa968f8ac5ae7eb6f359fbc1..af279eac8dddd002e1144b387b7b0696135175f0 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFURLAccess.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFURLACCESS__)
@@ -88,18 +88,17 @@ CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CF
 
 
 /* Common error codes (returned only by the older APIs that predate CFError) */
-enum {
-    kCFURLUnknownError = -10,
-    kCFURLUnknownSchemeError = -11,
-    kCFURLResourceNotFoundError = -12,
-    kCFURLResourceAccessViolationError = -13,
-    kCFURLRemoteHostUnavailableError = -14,
-    kCFURLImproperArgumentsError = -15,
-    kCFURLUnknownPropertyKeyError = -16,
-    kCFURLPropertyKeyUnavailableError = -17,
-    kCFURLTimeoutError = -18
+typedef CF_ENUM(CFIndex, CFURLError) {
+    kCFURLUnknownError = -10L,
+    kCFURLUnknownSchemeError = -11L,
+    kCFURLResourceNotFoundError = -12L,
+    kCFURLResourceAccessViolationError = -13L,
+    kCFURLRemoteHostUnavailableError = -14L,
+    kCFURLImproperArgumentsError = -15L,
+    kCFURLUnknownPropertyKeyError = -16L,
+    kCFURLPropertyKeyUnavailableError = -17L,
+    kCFURLTimeoutError = -18L
 };
-typedef CFIndex CFURLError;
 
 /* Older property keys */
 
index 7c1a5e18c6eb9791d97487caccbcd2f9c9d5435d..9066c9775cd3ed37db7354ce1ed6aa6501f73f31 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFURLPriv.h
-       Copyright (c) 2008-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2008-2012, Apple Inc. All rights reserved.
  */
 
 #if !defined(__COREFOUNDATION_CFURLPRIV__)
@@ -46,7 +46,6 @@ CF_EXTERN_C_BEGIN
 
 #if TARGET_OS_MAC
 
-#if MAC_OS_X_VERSION_10_5 <= MAC_OS_X_VERSION_MAX_ALLOWED
 enum {
     // Resource I/O related errors, with kCFErrorURLKey containing URL
     kCFURLNoSuchResourceError = 4,                        // Attempt to do a file system operation on a non-existent file
@@ -67,13 +66,7 @@ enum {
     kCFURLWriteUnsupportedSchemeError = 518,              // Write error (unsupported URL scheme)
     kCFURLWriteOutOfSpaceError = 640,                      // Write error (out of storage space)
     kCFURLWriteVolumeReadOnlyError = 642,                 // Write error (readonly volume)
-};
-#endif
-
-
-enum {
-    kCFURLFileReferencePathStyle = 14,
-};
+} CF_ENUM_AVAILABLE(10_5, 2_0);
 
 
 /*
@@ -101,9 +94,6 @@ CF_EXPORT const CFStringRef _kCFURLFileIDKey CF_AVAILABLE(10_6, 4_0);
 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) */
 
-/* OBSOLETE */CF_EXPORT const CFStringRef _kCFURLFilePathKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0);
-    /* _kCFURLFilePathKey was never implemented. Use _kCFURLPathKey instead. */
-
 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) */
 
@@ -188,6 +178,9 @@ CF_EXPORT const CFStringRef _kCFURLApplicationHighResolutionModeIsMagnifiedKey C
 CF_EXPORT const CFStringRef _kCFURLCanSetApplicationHighResolutionModeIsMagnifiedKey CF_AVAILABLE(10_7, NA);
     /* True if the app can run in either magnified or native resolution modes (Read only, CFBoolean) */
 
+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) */
+
 /* Additional volume properties */
 
 CF_EXPORT const CFStringRef _kCFURLVolumeRefNumKey CF_AVAILABLE(10_6, 4_0);
@@ -322,7 +315,7 @@ Boolean _CFURLGetResourcePropertyFlags(CFURLRef url, CFURLResourcePropertyFlags
 /*
     File resource properties which can be obtained with _CFURLCopyFilePropertyValuesAndFlags().
  */
-enum {
+typedef CF_OPTIONS(unsigned long long, CFURLFilePropertyBitmap) {
     kCFURLName                             = 0x0000000000000001,
     kCFURLLinkCount                        = 0x0000000000000002,
     kCFURLVolumeIdentifier                 = 0x0000000000000004,
@@ -337,7 +330,6 @@ enum {
     kCFURLFinderInfo                       = 0x0000000000000800,
     kCFURLFileSecurity                     = 0x0000000000001000,
 };
-typedef unsigned long long CFURLFilePropertyBitmap;
 
 /*
     The structure where _CFURLCopyFilePropertyValuesAndFlags() returns file resource properties.
@@ -373,7 +365,7 @@ Boolean _CFURLCopyResourcePropertyValuesAndFlags( CFURLRef url, CFURLFilePropert
 /*
     Volume property flags
  */
-enum {
+typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) {
        kCFURLVolumeIsLocal                             =                0x1LL, // Local device (vs. network device)
        kCFURLVolumeIsAutomount                         =                0x2LL, // Mounted by the automounter
        kCFURLVolumeDontBrowse                          =                0x4LL, // Hidden from user browsing
@@ -424,7 +416,6 @@ enum {
        kCFURLVolumeHas64BitObjectIDs                   = 0x1000000000000000LL,
        kCFURLVolumePropertyFlagsAll                    = 0xffffffffffffffffLL
 };
-typedef unsigned long long CFURLVolumePropertyFlags;
 
 
 /*
@@ -482,15 +473,6 @@ Boolean _CFURLSetResourcePropertyForKeyAndUpdateFileCache(CFURLRef url, CFString
 CF_EXPORT
 CFArrayRef _CFURLCreateDisplayPathComponentsArray(CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_7, 4_0);
 
-#if 0
-/* Not implemented */
-CF_EXPORT
-CFURLRef _CFURLCreateFileIDURLFromFSRef(CFAllocatorRef allocator, const struct FSRef *fsRef);
-#endif
-
-CF_EXPORT
-CFURLRef _CFURLCreateAbsoluteURLWithDirectoryURLAndName(CFAllocatorRef allocator, CFURLRef directoryURL, CFStringRef name) CF_AVAILABLE(10_6, 4_0);
-
 /* Returns true for URLs that locate file system resources. */
 CF_EXPORT
 Boolean _CFURLIsFileURL(CFURLRef url) CF_AVAILABLE(10_6, 4_0);
@@ -567,10 +549,10 @@ enum {
 };
 
 enum {
-    kCFBookmarkResolutionPerformRelativeResolutionFirstMask = ( 1 << 10 ), // perform relative resolution before absolute resolution.  If this bit is set, for this to be useful a relative URL must also have been passed in and the bookmark when created must have been created relative to another url.
+    kCFBookmarkResolutionPerformRelativeResolutionFirstMask CF_ENUM_AVAILABLE(10_8,6_0) = ( 1 << 11 ), // perform relative resolution before absolute resolution.  If this bit is set, for this to be useful a relative URL must also have been passed in and the bookmark when created must have been created relative to another url.
 };
 
-enum {
+typedef CF_ENUM(CFIndex, CFURLBookmarkMatchResult) {
     kCFURLBookmarkComparisonUnableToCompare = 0x00000000,   /* the two bookmarks could not be compared for some reason */
     kCFURLBookmarkComparisonNoMatch         = 0x00001000,   /* Bookmarks do not refer to the same item */
     kCFURLBookmarkComparisonUnlikelyToMatch = 0x00002000,   /* it is unlikely that the two items refer to the same filesystem item */
@@ -578,7 +560,6 @@ enum {
     kCFURLBookmarkComparisonMatch           = 0x00008000,   /* the two items refer to the same item, but other information in the bookmarks may not match */
     kCFURLBookmarkComparisonExactMatch      = 0x0000f000    /* the two bookmarks are identical */
 };
-typedef CFIndex CFURLBookmarkMatchResult;
 
 /*  Keys specific to bookmarks at this time */
 CF_EXPORT const CFStringRef _kCFURLPropertyKeyFullPathString;      //  the full filesystem path of the item the bookmark was create against
index 3e880be64fb96896763a97d05a5284c3672c567a..e820e8c0d1cf500bdc7c9842f80e2a4622f0925c 100644 (file)
--- a/CFUUID.c
+++ b/CFUUID.c
  */
 
 /*     CFUUID.c
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
        Responsibility: David Smith
 */
 
 #include <CoreFoundation/CFUUID.h>
 #include "CFInternal.h"
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
-#include <uuid/uuid.h>
-#endif
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
 #include <dispatch/dispatch.h>
@@ -266,6 +263,8 @@ static CFUUIDRef __CFUUIDCreateWithBytesPrimitive(CFAllocatorRef allocator, CFUU
 
 #if DEPLOYMENT_TARGET_WINDOWS
 #include <Rpc.h>
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#include <uuid/uuid.h>
 #endif
 
 CFUUIDRef CFUUIDCreate(CFAllocatorRef alloc) {
index 28bd1e397f6f8ff3dfa31e1e92e49c1aa8a79403..04b5e1da8c23569dc10181018fd1970f9bb03c7c 100644 (file)
--- a/CFUUID.h
+++ b/CFUUID.h
@@ -22,7 +22,7 @@
  */
 
 /*     CFUUID.h
-       Copyright (c) 1999-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUUID__)
@@ -31,6 +31,7 @@
 #include <CoreFoundation/CFBase.h>
 #include <CoreFoundation/CFString.h>
 
+CF_IMPLICIT_BRIDGING_ENABLED
 CF_EXTERN_C_BEGIN
 
 typedef const struct __CFUUID * CFUUIDRef;
@@ -89,6 +90,7 @@ CF_EXPORT
 CFUUIDRef CFUUIDCreateFromUUIDBytes(CFAllocatorRef alloc, CFUUIDBytes bytes);
 
 CF_EXTERN_C_END
+CF_IMPLICIT_BRIDGING_DISABLED
 
 #endif /* ! __COREFOUNDATION_CFUUID__ */
 
index 357344c102aaac986aa0cc9bc0c2a3a3c5333128..ec635046623dd8eed690614b0825d1611f813961 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniChar.c
-       Copyright (c) 2001-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2001-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
@@ -32,7 +32,7 @@
 #include "CFStringEncodingConverterExt.h"
 #include "CFUnicodeDecomposition.h"
 #include "CFUniCharPriv.h"
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -51,7 +51,7 @@ extern void _CFGetFrameworkPath(wchar_t *path, int maxLength);
 
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 #define __kCFCharacterSetDir "/System/Library/CoreServices"
-#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #define __kCFCharacterSetDir "/usr/local/share/CoreFoundation"
 #elif DEPLOYMENT_TARGET_WINDOWS
 #define __kCFCharacterSetDir "\\Windows\\CoreFoundation"
@@ -99,7 +99,7 @@ static const void *__CFGetSectDataPtr(const char *segname, const char *sectname,
 
 // Memory map the file
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 CF_INLINE void __CFUniCharCharacterSetPath(char *cpath) {
 #elif DEPLOYMENT_TARGET_WINDOWS
 CF_INLINE void __CFUniCharCharacterSetPath(wchar_t *wpath) {
@@ -163,7 +163,7 @@ void __AddBitmapStateForName(const wchar_t *bitmapName) {
 }
 #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
 static bool __CFUniCharLoadBytesFromFile(const char *fileName, const void **bytes, int64_t *fileSize) {
 #elif DEPLOYMENT_TARGET_WINDOWS
 static bool __CFUniCharLoadBytesFromFile(const wchar_t *fileName, const void **bytes, int64_t *fileSize) {
@@ -229,7 +229,7 @@ static bool __CFUniCharLoadBytesFromFile(const wchar_t *fileName, const void **b
 
 #endif // USE_MACHO_SEGMENT
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 static bool __CFUniCharLoadFile(const char *bitmapName, const void **bytes, int64_t *fileSize) {
 #elif DEPLOYMENT_TARGET_WINDOWS
 static bool __CFUniCharLoadFile(const wchar_t *bitmapName, const void **bytes, int64_t *fileSize) {
@@ -243,7 +243,7 @@ static bool __CFUniCharLoadFile(const wchar_t *bitmapName, const void **bytes, i
 
     return *bytes ? true : false;
 #else
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
     char cpath[MAXPATHLEN];
     __CFUniCharCharacterSetPath(cpath);
     strlcat(cpath, bitmapName, MAXPATHLEN);
@@ -319,7 +319,7 @@ static __CFUniCharBitmapData *__CFUniCharBitmapDataArray = NULL;
 
 static CFSpinLock_t __CFUniCharBitmapLock = CFSpinLockInit;
 
-#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 !defined(CF_UNICHAR_BITMAP_FILE)
 #if USE_MACHO_SEGMENT
 #define CF_UNICHAR_BITMAP_FILE "__csbitmaps"
@@ -624,7 +624,7 @@ static const void **__CFUniCharMappingTables = NULL;
 
 static CFSpinLock_t __CFUniCharMappingTableLock = CFSpinLockInit;
 
-#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 __CF_BIG_ENDIAN__
 #if USE_MACHO_SEGMENT
 #define MAPPING_TABLE_FILE "__data"
@@ -767,11 +767,13 @@ static bool __CFUniCharLoadCaseMappingTable(void) {
 #define LITHUANIAN_LANG_CODE   (0x6C74) // lt
 #define AZERI_LANG_CODE                (0x617A) // az
 #define DUTCH_LANG_CODE                (0x6E6C) // nl
+#define GREEK_LANG_CODE                (0x656C) // el
 #else
 #define TURKISH_LANG_CODE      (0x7274) // tr
 #define LITHUANIAN_LANG_CODE   (0x746C) // lt
 #define AZERI_LANG_CODE                (0x7A61) // az
 #define DUTCH_LANG_CODE                (0x6C6E) // nl
+#define GREEK_LANG_CODE                (0x6C65) // el
 #endif
 
 CFIndex CFUniCharMapCaseTo(UTF32Char theChar, UTF16Char *convertedChar, CFIndex maxLength, uint32_t ctype, uint32_t flags, const uint8_t *langCode) {
@@ -789,6 +791,54 @@ caseFoldRetry:
     }
 
     if (langCode) {
+        if (flags & kCFUniCharCaseMapGreekTonos) { // localized Greek uppercasing
+            if (theChar == 0x0301) { // GREEK TONOS
+                return 0;
+            } else if (theChar == 0x0344) {// COMBINING GREEK DIALYTIKA TONOS
+                *convertedChar = 0x0308; // COMBINING GREEK DIALYTIKA
+                return 1;
+            } else if (CFUniCharIsMemberOf(theChar, kCFUniCharDecomposableCharacterSet)) {
+                UTF32Char buffer[MAX_DECOMPOSED_LENGTH];
+                CFIndex length = CFUniCharDecomposeCharacter(theChar, buffer, MAX_DECOMPOSED_LENGTH);
+
+                if (length > 1) {
+                    UTF32Char *characters = buffer + 1;
+                    UTF32Char *tail = buffer + length;
+
+                    while (characters < tail) {
+                        if (*characters == 0x0301) break;
+                        ++characters;
+                    }
+
+                    if (characters < tail) { // found a tonos
+                        CFIndex convertedLength = CFUniCharMapCaseTo(*buffer, convertedChar, maxLength, ctype, 0, langCode);
+
+                        if (convertedLength == 0) {
+                            *convertedChar = (UTF16Char)*buffer;
+                            convertedLength = 1;
+                        }
+
+                        characters = buffer + 1;
+
+                        while (characters < tail) {
+                            if (*characters != 0x0301) { // not tonos
+                                if (*characters < 0x10000) { // BMP
+                                    convertedChar[convertedLength] = (UTF16Char)*characters;
+                                    ++convertedLength;
+                                } else {
+                                    UTF32Char character = *characters - 0x10000;
+                                    convertedChar[convertedLength++] = (UTF16Char)((character >> 10) + 0xD800UL);
+                                    convertedChar[convertedLength++] = (UTF16Char)((character & 0x3FF) + 0xDC00UL);
+                                }
+                            }
+                            ++characters;
+                        }
+
+                        return convertedLength;
+                    }
+                }
+            }
+        }
         switch (*(uint16_t *)langCode) {
             case LITHUANIAN_LANG_CODE:
                 if (theChar == 0x0307 && (flags & kCFUniCharCaseMapAfter_i)) {
@@ -1082,6 +1132,15 @@ __private_extern__ uint32_t CFUniCharGetConditionalCaseMappingFlags(UTF32Char th
                }
            }
        }
+
+        if (kCFUniCharCaseMapGreekTonos & lastFlags) { // still searching for tonos
+            if (CFUniCharIsMemberOf(theChar, kCFUniCharNonBaseCharacterSet)) {
+                return kCFUniCharCaseMapGreekTonos;
+            }
+        }
+        if (((theChar >= 0x0370) && (theChar < 0x0400)) || ((theChar >= 0x1F00) && (theChar < 0x2000))) { // Greek/Coptic & Greek extended ranges
+            if (((type == kCFUniCharToUppercase) || (type == kCFUniCharToTitlecase))&& (CFUniCharIsMemberOf(theChar, kCFUniCharLetterCharacterSet))) return kCFUniCharCaseMapGreekTonos;
+        }
     }
     return 0;
 }
@@ -1092,7 +1151,7 @@ static int __CFUniCharUnicodePropertyTableCount = 0;
 
 static CFSpinLock_t __CFUniCharPropTableLock = CFSpinLockInit;
 
-#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 USE_MACHO_SEGMENT
 #define PROP_DB_FILE "__properties"
 #else
index 9669a65895278ff05b67ee6e04dd4809f81a1503..b886945064b237d530ef6139df2cf2057fe6307a 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniChar.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUNICHAR__)
@@ -125,7 +125,8 @@ enum {
     kCFUniCharCaseMapFinalSigma = (1UL << 0),
     kCFUniCharCaseMapAfter_i = (1UL << 1),
     kCFUniCharCaseMapMoreAbove = (1UL << 2),
-    kCFUniCharCaseMapDutchDigraph = (1UL << 3)
+    kCFUniCharCaseMapDutchDigraph = (1UL << 3),
+    kCFUniCharCaseMapGreekTonos = (1UL << 4)
 };
 
 CF_EXPORT CFIndex CFUniCharMapCaseTo(UTF32Char theChar, UTF16Char *convertedChar, CFIndex maxLength, uint32_t ctype, uint32_t flags, const uint8_t *langCode);
index 2e95c1945c1bbaf2da82210bc1aa6d90b86064ee..de85604efbacc74e56505b9f4836457324b79a1f 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUniCharPriv.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUNICHARPRIV__)
index 37cf5a347939bed3ace307b539fd83fbf90f913a..31ac3deddebae990a90a8141219ca77b6f2433a0 100644 (file)
Binary files a/CFUniCharPropertyDatabase.data and b/CFUniCharPropertyDatabase.data differ
index 444a1e8d56cc02d2021114ca87967258bc19c30f..4b4b6d19221f681db93f38b47e9bc297f584f243 100644 (file)
Binary files a/CFUnicodeData-B.mapping and b/CFUnicodeData-B.mapping differ
index 2be5551ca93cad613f8e8d74795d0ac2152b6ae1..03d92b863b6912ec3e9e97795b942b40f1eae84c 100644 (file)
Binary files a/CFUnicodeData-L.mapping and b/CFUnicodeData-L.mapping differ
index 92436ea4c19f8b1c1372f744ca08cf4386b40b6f..4026b4fd5b95aa6cc5fd3f3af8e342eac07a7301 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*    CFUnicodeDecomposition.c
-    Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+    Copyright (c) 1999-2012, Apple Inc. All rights reserved.
     Responsibility: Aki Inoue
 */
 
index b8f2391944d06e36139d0244505581141b44f5f1..35e82b4ef0b374bd9ccba5be03c7c9313a9a1414 100644 (file)
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by aki on Wed Oct 03 2001.
- *  Copyright (c) 2001-2011, Apple Inc. All rights reserved.
+ *  Copyright (c) 2001-2012, Apple Inc. All rights reserved.
  *
  */
 
index 117c60d3d2553ca421f8e597a02e21b25da3f8c6..915bf866695eea97daab8784b483bf19fef948ac 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUnicodePrecomposition.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: Aki Inoue
 */
 
index 0e5ab78ec7f6d23c24a8078ad232388c25adcb66..97ce58810bc2028cc6b97577c3d0940fb514981c 100644 (file)
@@ -26,7 +26,7 @@
  *  CoreFoundation
  *
  *  Created by aki on Wed Oct 03 2001.
- *  Copyright (c) 2001-2011, Apple Inc. All rights reserved.
+ *  Copyright (c) 2001-2012, Apple Inc. All rights reserved.
  *
  */
 
index 46b4f5132b1680a36d9e267e167f45de32213874..bc848feb96c08912fd13cce19fd244c808e253cf 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUserNotification.c
-       Copyright (c) 2000-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc.  All rights reserved.
        Original Author: Doug Davidson
        Responsibility: Kevin Perry
 */
@@ -232,7 +232,7 @@ static SInt32 _CFUserNotificationSendRequest(CFAllocatorRef allocator, CFStringR
                 if (__CFOASafe) __CFSetLastAllocationEventName(msg, "CFUserNotification (temp)");
                 if (msg) {
                     memset(msg, 0, size);
-                    msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
+                    msg->header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, (replyPort == MACH_PORT_NULL) ? 0 : MACH_MSG_TYPE_MAKE_SEND_ONCE);
                     msg->header.msgh_size = size;
                     msg->header.msgh_remote_port = serverPort;
                     msg->header.msgh_local_port = replyPort;
@@ -379,14 +379,20 @@ CFDictionaryRef CFUserNotificationGetResponseDictionary(CFUserNotificationRef us
 SInt32 CFUserNotificationUpdate(CFUserNotificationRef userNotification, CFTimeInterval timeout, CFOptionFlags flags, CFDictionaryRef dictionary) {
     CHECK_FOR_FORK();
     SInt32 retval = ERR_SUCCESS;
-    if (userNotification && MACH_PORT_NULL != userNotification->_replyPort) retval = _CFUserNotificationSendRequest(CFGetAllocator(userNotification), userNotification->_sessionID, userNotification->_replyPort, userNotification->_token, timeout, flags|kCFUserNotificationUpdateFlag, dictionary);
+    if (userNotification && MACH_PORT_NULL != userNotification->_replyPort) {
+        // Avoid including a new send-once right with update/cancel messages by passing MACH_PORT_NULL, since the server doesn't need to use them.
+        retval = _CFUserNotificationSendRequest(CFGetAllocator(userNotification), userNotification->_sessionID, MACH_PORT_NULL, userNotification->_token, timeout, flags|kCFUserNotificationUpdateFlag, dictionary);
+    }
     return retval;
 }
 
 SInt32 CFUserNotificationCancel(CFUserNotificationRef userNotification) {
     CHECK_FOR_FORK();
     SInt32 retval = ERR_SUCCESS;
-    if (userNotification && MACH_PORT_NULL != userNotification->_replyPort) retval = _CFUserNotificationSendRequest(CFGetAllocator(userNotification), userNotification->_sessionID, userNotification->_replyPort, userNotification->_token, 0, kCFUserNotificationCancelFlag, NULL);
+    if (userNotification && MACH_PORT_NULL != userNotification->_replyPort) {
+        // Avoid including a new send-once right with update/cancel messages by passing MACH_PORT_NULL, since the server doesn't need to use them.
+        retval = _CFUserNotificationSendRequest(CFGetAllocator(userNotification), userNotification->_sessionID, MACH_PORT_NULL, userNotification->_token, 0, kCFUserNotificationCancelFlag, NULL);
+    }
     return retval;
 }
 
index 76f8732f3ef38d2e0bb39ca4250e476ce1d53d62..a3e4406d2082103bb8e77eebe15a22f2ed984b1d 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUserNotification.h
-       Copyright (c) 2000-2011, Apple Inc.  All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc.  All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFUSERNOTIFICATION__)
index ffd23b54dd3d15af61664f59b68233e30fa4d089..b14becc450f03f7f632066f0b00f49d315dbc371 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFUtilities.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: Tony Parker
 */
 
@@ -51,7 +51,7 @@
 #define ASL_LEVEL_DEBUG 7
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <unistd.h>
 #include <sys/uio.h>
 #include <mach/mach.h>
@@ -143,7 +143,7 @@ CFHashCode CFHashBytes(uint8_t *bytes, CFIndex length) {
 #undef ELF_STEP
 
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 __private_extern__ uintptr_t __CFFindPointer(uintptr_t ptr, uintptr_t start) {
     vm_map_t task = mach_task_self();
     mach_vm_address_t address = start;
@@ -196,7 +196,7 @@ static unsigned __stdcall __CFWinThreadFunc(void *arg) {
 #endif
 
 __private_extern__ void *__CFStartSimpleThread(void *func, void *arg) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
+#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;
     pthread_attr_init(&attr);
@@ -248,18 +248,19 @@ static CFStringRef _CFCopyLocalizedVersionKey(CFBundleRef *bundlePtr, CFStringRe
 
 static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) {
     CFPropertyListRef plist = NULL;
+    
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     CFDataRef data;
     CFURLRef url;
-
+    
     url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, false);
     if (url && CFURLCreateDataAndPropertiesFromResource(kCFAllocatorSystemDefault, url, &data, NULL, NULL, NULL)) {
        plist = CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListMutableContainers, NULL);
        CFRelease(data);
     }
     if (url) CFRelease(url);
-    
+
     if (plist) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
        CFBundleRef locBundle = NULL;
        CFStringRef fullVersion, vers, versExtra, build;
        CFStringRef versionString = _CFCopyLocalizedVersionKey(&locBundle, _kCFSystemVersionProductVersionStringKey);
@@ -286,8 +287,29 @@ static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) {
        CFRelease(buildString);
        CFRelease(fullVersionString);
         CFRelease(fullVersion);
-#endif
     }    
+#elif DEPLOYMENT_TARGET_WINDOWS
+    OSVERSIONINFOEX osvi;
+    ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+    BOOL result = GetVersionEx((OSVERSIONINFO *)&osvi);
+    if (!result) return NULL;
+
+    plist = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 10, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    
+    // e.g. 10.7
+    CFStringRef versionString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%ld.%ld(%ld,%ld)"), osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.wServicePackMajor, osvi.wServicePackMinor);
+    
+    // e.g. 11A508
+    CFStringRef buildString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%ld"), osvi.dwBuildNumber);
+        
+    CFDictionarySetValue((CFMutableDictionaryRef)plist, _kCFSystemVersionProductVersionKey, versionString);
+    CFDictionarySetValue((CFMutableDictionaryRef)plist, _kCFSystemVersionBuildVersionKey, buildString);    
+    CFDictionarySetValue((CFMutableDictionaryRef)plist, _kCFSystemVersionProductNameKey, CFSTR("Windows")); // hard coded for now
+    
+    CFRelease(versionString);
+    CFRelease(buildString);
+#endif
     return (CFDictionaryRef)plist;
 }
 
@@ -363,9 +385,7 @@ __private_extern__ void *__CFLookupCoreServicesInternalFunction(const char *name
     }
     return dyfunc;
 }
-#endif
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
 __private_extern__ void *__CFLookupCFNetworkFunction(const char *name) {
     static void *image = NULL;
     if (NULL == image) {
@@ -374,11 +394,7 @@ __private_extern__ void *__CFLookupCFNetworkFunction(const char *name) {
            path = __CFgetenv("CFNETWORK_LIBRARY_PATH");
        }
        if (!path) {
-#if DEPLOYMENT_TARGET_MACOSX
-           path = "/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork";
-#else
            path = "/System/Library/Frameworks/CFNetwork.framework/CFNetwork";
-#endif
        }
        image = dlopen(path, RTLD_LAZY | RTLD_LOCAL);
     }
@@ -411,7 +427,7 @@ __private_extern__ CFIndex __CFActiveProcessorCount() {
     v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
     v = (v + (v >> 4)) & 0xf0f0f0f0f0f0f0fULL;
     pcnt = (v * 0x0101010101010101ULL) >> ((sizeof(v) - 1) * 8);
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     int32_t mib[] = {CTL_HW, HW_AVAILCPU};
     size_t len = sizeof(pcnt);
     int32_t result = sysctl(mib, sizeof(mib) / sizeof(int32_t), &pcnt, &len, NULL, 0);
@@ -425,6 +441,21 @@ __private_extern__ CFIndex __CFActiveProcessorCount() {
     return pcnt;
 }
 
+__private_extern__ 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;
+    if (0 == pthread_getugid_np(&uid, &gid)) {
+        if (euid) *euid = uid;
+        if (egid) *egid = gid;
+    } else
+#endif
+    {
+        if (euid) *euid = geteuid();
+        if (egid) *egid = getegid();
+    }
+}
+
 const char *_CFPrintForDebugger(const void *obj) {
        static char *result = NULL;
        CFStringRef str;
@@ -504,7 +535,7 @@ static void _CFShowToFile(FILE *file, Boolean flush, const void *obj) {
          }
      }
      if (!lastNL) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
          fprintf_l(file, NULL, "\n");
 #else
          fprintf(file, NULL, "\n");
@@ -525,7 +556,10 @@ void CFShow(const void *obj) {
 typedef void (*CFLogFunc)(int32_t lev, const char *message, size_t length, char withBanner);
 
 static Boolean also_do_stderr() {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_EMBEDDED_MINI
+    // just log to stderr, other logging facilities are out
+    return true;
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
     if (!issetugid() && __CFgetenv("CFLOG_FORCE_STDERR")) {
        return true;
     }
@@ -551,9 +585,10 @@ 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_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)
+#if DEPLOYMENT_TARGET_WINDOWS
     int bannerLen = 0;
 #endif
+#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) {
        CFAbsoluteTime at = CFAbsoluteTimeGetCurrent();
@@ -587,7 +622,9 @@ static void __CFLogCString(int32_t lev, const char *message, size_t length, char
     }
     after_banner:;
 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
-    asprintf(&uid, "%d", geteuid());
+    uid_t euid;
+    __CFGetUGIDs(&euid, NULL);
+    asprintf(&uid, "%d", euid);
     aslclient asl = asl_open(NULL, __CFBundleMainID[0] ? __CFBundleMainID : "com.apple.console", ASL_OPT_NO_DELAY);
     aslmsg msg = asl_new(ASL_TYPE_MSG);
     asl_set(msg, "CFLog Local Time", time); // not to be documented, not public API
@@ -600,9 +637,10 @@ static void __CFLogCString(int32_t lev, const char *message, size_t length, char
     asl_free(msg);
     asl_close(asl);
 #endif
+#endif // DEPLOYMENT_TARGET
 
     if (also_do_stderr()) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
        struct iovec v[3];
        v[0].iov_base = banner;
        v[0].iov_len = banner ? strlen(banner) : 0;
@@ -657,7 +695,7 @@ static void __CFLogCString(int32_t lev, const char *message, size_t length, char
 }
 
 CF_EXPORT void _CFLogvEx(CFLogFunc logit, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, int32_t lev, CFStringRef format, va_list args) {
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     uintptr_t val = (uintptr_t)_CFGetTSD(__CFTSDKeyIsInCFLog);
     if (3 < val) return; // allow up to 4 nested invocations
     _CFSetTSD(__CFTSDKeyIsInCFLog, (void *)(val + 1), NULL);
@@ -675,7 +713,7 @@ CF_EXPORT void _CFLogvEx(CFLogFunc logit, CFStringRef (*copyDescFunc)(void *, co
     }
     if (buf) free(buf);
     if (str) CFRelease(str);
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     _CFSetTSD(__CFTSDKeyIsInCFLog, (void *)val, NULL);
 #endif
 }
@@ -780,14 +818,7 @@ void _CFSuddenTerminationEnable(void) {
     __CFSpinLock(&__CFProcessKillingLock);
     __CFProcessKillingDisablingCount--;
     if (__CFProcessKillingDisablingCount==0 && !__CFProcessKillingWasTurnedOn) {
-       int64_t transactionsAreToBeEnabled = 1;
-       int64_t transactionsWereAlreadyEnabled = 0;
-       vproc_err_t verr = vproc_swap_integer(NULL, VPROC_GSK_TRANSACTIONS_ENABLED, &transactionsAreToBeEnabled, &transactionsWereAlreadyEnabled);
-       if (!verr) {
-           if (!transactionsWereAlreadyEnabled) {
-               // We set __CFProcessKillingWasTurnedOn below regardless of success because there's no point in retrying.
-           } // else this process was launched by launchd with transactions already enabled because EnableTransactions was set to true in the launchd .plist file.
-       } // else this process was not launched by launchd and the fix for 6416724 is not in the build yet.
+       _vproc_transactions_enable();
        __CFProcessKillingWasTurnedOn = true;
     } else {
        // Mail seems to have sudden termination disabling/enabling imbalance bugs that make _vproc_transaction_end() kill the app but we don't want that to prevent our submission of the fix 6382488.
@@ -902,7 +933,7 @@ size_t _CFSuddenTerminationDisablingCount(void) {
 #endif
 
 #if 0
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 
 typedef void (^ThrottleTypeA)(void);           // allows calls per nanoseconds
 typedef void (^ThrottleTypeB)(uint64_t amt);   // allows amount per nanoseconds
@@ -956,3 +987,144 @@ __private_extern__ ThrottleTypeB __CFCreateThrottleTypeB(uint64_t amount, uint64
 #endif
 #endif
 
+#pragma mark File Reading
+    
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#if DEPLOYMENT_TARGET_WINDOWS
+#include <io.h>
+#include <direct.h>
+#define close _close
+#define write _write
+#define read _read
+#define open _NS_open
+#define stat _NS_stat
+#define fstat _fstat
+#define statinfo _stat
+    
+#define mach_task_self() 0
+
+#else
+#define statinfo stat
+#endif
+    
+static CFErrorRef _CFErrorWithFilePathCodeDomain(CFStringRef domain, CFIndex code, CFStringRef path) {
+    CFStringRef key = CFSTR("NSFilePath");
+    CFDictionaryRef userInfo = CFDictionaryCreate(kCFAllocatorSystemDefault, (const void **)&key, (const void **)&path, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+    CFErrorRef result = CFErrorCreate(kCFAllocatorSystemDefault, domain, code, userInfo);
+    CFRelease(userInfo);
+    return result;
+}
+
+// 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) {
+    void *bytes = NULL;
+    unsigned long length;
+    char cpath[CFMaxPathSize];
+    if (!CFStringGetFileSystemRepresentation(path, cpath, CFMaxPathSize)) {
+        // TODO: real error codes
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainCocoa, -1, path);
+       return false;
+    }
+
+    struct statinfo statBuf;
+    int32_t fd = -1;
+
+    fd = open(cpath, O_RDONLY|CF_OPENFLGS, 0666);
+    if (fd < 0) {
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, errno, path);
+        return false;
+    }
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI    
+    if (uncached) (void)fcntl(fd, F_NOCACHE, 1);  // Non-zero arg turns off caching; we ignore error as uncached is just a hint
+#endif
+    if (fstat(fd, &statBuf) < 0) {
+        int32_t savederrno = errno;
+        close(fd);
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, savederrno, path);
+        return false;
+    }
+    if ((statBuf.st_mode & S_IFMT) != S_IFREG) {
+        close(fd);
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, EACCES, path);
+        return false;
+    }
+    if (statBuf.st_size < 0LL) {       // too small
+        close(fd);
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, ENOMEM, path);
+        return false;
+    }
+#if __LP64__
+#else
+    if (statBuf.st_size > (1LL << 31)) {       // refuse to do more than 2GB
+        close(fd);
+        if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, EFBIG, path);
+        return false;
+    }
+#endif
+
+    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
+    } else if (map) {
+        if((void *)-1 == (bytes = mmap(0, (size_t)statBuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0))) {
+           int32_t savederrno = errno;
+           close(fd);
+            if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, savederrno, path);
+           return false;
+       }
+       length = (unsigned long)statBuf.st_size;
+    } else {
+        bytes = malloc(statBuf.st_size);
+        if (bytes == NULL) {
+            close(fd);
+            if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, ENOMEM, path);
+            return false;
+        }
+       size_t numBytesRemaining = (size_t)statBuf.st_size;
+       void *readLocation = bytes;
+       while (numBytesRemaining > 0) {
+           size_t numBytesRequested = (numBytesRemaining < (1LL << 31)) ? numBytesRemaining : ((1LL << 31) - 1);       // This loop is basically a workaround for 4870206 
+           ssize_t numBytesRead = read(fd, readLocation, numBytesRequested);
+           if (numBytesRead <= 0) {
+               if (numBytesRead < 0) {
+                   int32_t savederrno = errno;
+                    free(bytes);
+                   close(fd);
+                    if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, savederrno, path);
+                   bytes = NULL;
+                   return false;
+               } else {
+                   // This is a bizarre case; 0 bytes read. Might indicate end-of-file?
+                   break;
+               }
+           } else {
+               readLocation += numBytesRead;
+               numBytesRemaining -= numBytesRead;
+           }
+       }
+       length = (unsigned long)statBuf.st_size - numBytesRemaining;
+    }
+#else
+    } else {
+        bytes = malloc(statBuf.st_size);
+        DWORD numBytesRead;
+        if (!ReadFile((HANDLE)_get_osfhandle(fd), bytes, statBuf.st_size, &numBytesRead, NULL)) {
+            DWORD lastError = GetLastError();
+            if (errorPtr) *errorPtr = _CFErrorWithFilePathCodeDomain(kCFErrorDomainPOSIX, lastError, path);
+           free(bytes);
+           close(fd);
+           errno = lastError;
+           bytes = NULL;
+           return false;
+        }
+       length = numBytesRead;
+    }
+#endif
+    close(fd);
+    *outBytes = bytes;
+    *outLength = length;
+    return true;
+}
index 224ae9f9d5667dd7964d5c05f20cabbece027e0b..4a33d1407511f8a94ef9721ebeabf6be3ec56f65 100644 (file)
@@ -25,5 +25,5 @@
     Copyright 2009-2011, Apple Inc. All rights reserved.
     Responsibility: CFLite Team
 */
-const unsigned char kCFCoreFoundationVersionString[] = "@(#)PROGRAM:CoreFoundation  PROJECT:CoreFoundation-635.21  SYSTEM:Darwin  DEVELOPER:unknown  BUILT:" __DATE__ " " __TIME__ "\n";
-double kCFCoreFoundationVersionNumber = (double)635.21;
+const unsigned char kCFCoreFoundationVersionString[] = "@(#)PROGRAM:CoreFoundation  PROJECT:CoreFoundation-744  SYSTEM:Darwin  DEVELOPER:unknown  BUILT:" __DATE__ " " __TIME__ "\n";
+double kCFCoreFoundationVersionNumber = (double)744;
index 7d0fe138c048f277bc3023260e2d1f7d25ccef61..af1bb39c094687f7a9e5dbf457c84587d3b29d94 100644 (file)
@@ -23,7 +23,7 @@
 
 /*     
     CFWindowsUtilities.c
-    Copyright (c) 2008-2011, Apple Inc. All rights reserved.
+    Copyright (c) 2008-2012, Apple Inc. All rights reserved.
     Responsibility: Tony Parker
 */
 
index 13d2bb43c1c11ffdf9470ede4590fda68e5ef8a5..b3d735264c88f754ffffdb6c95d08a9b964edcd9 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLInputStream.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index 7d786d687e5f87158d3a2b1fc51c6d4aaecad91e..0eadcee4712ae210e9911c2ec7f1439a025e6f75 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLInputStream.h
-       Copyright (c) 2000-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2000-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_CFXMLINPUTSTREAM__)
index 44e53eda44242310f835ec043f8ea59a3e58a025..10700d5b25219561d53b50fdd40a0266af3218a2 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLNode.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index da2f3385c1351a1e9e397bcc9b4380f6169906fb..8be66f48b45e1a9fc3af16f4fab6a20d342f880a 100644 (file)
  */
 
 /*     CFXMLNode.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
-/*  CFXMLParser (and thus CFXMLNode) are deprecated. Clients should be aware of the fact that CFXMLParser has 
-    some serious deficiencies in terms of both performance and standards compliance and should migrate their 
-    XML parsing to NSXMLParser, NSXMLDocument, or other XML parsing technologies.
- */
+/*  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. */
 
 #if !defined(__COREFOUNDATION_CFXMLNODE__)
 #define __COREFOUNDATION_CFXMLNODE__ 1
@@ -69,7 +66,7 @@ typedef CFTreeRef CFXMLTreeRef;
     */
 
 /* Type codes for the different possible XML nodes; this list may grow.*/
-enum {
+typedef CF_ENUM(CFIndex, CFXMLNodeTypeCode) {
     kCFXMLNodeTypeDocument = 1,
     kCFXMLNodeTypeElement = 2,
     kCFXMLNodeTypeAttribute = 3,
@@ -86,7 +83,6 @@ enum {
     kCFXMLNodeTypeElementTypeDeclaration = 14,
     kCFXMLNodeTypeAttributeListDeclaration = 15
 };
-typedef CFIndex CFXMLNodeTypeCode;
 
 typedef struct {
     CFDictionaryRef attributes;
@@ -134,14 +130,13 @@ typedef struct {
     CFXMLAttributeDeclarationInfo *attributes;
 } CFXMLAttributeListDeclarationInfo;
 
-enum {
+typedef CF_ENUM(CFIndex, CFXMLEntityTypeCode) {
     kCFXMLEntityTypeParameter,       /* Implies parsed, internal */
     kCFXMLEntityTypeParsedInternal,
     kCFXMLEntityTypeParsedExternal,
     kCFXMLEntityTypeUnparsed,
     kCFXMLEntityTypeCharacter
 };
-typedef CFIndex CFXMLEntityTypeCode;
 
 typedef struct {
     CFXMLEntityTypeCode entityType;
@@ -175,37 +170,37 @@ typedef struct {
 */
 
 CF_EXPORT
-CFTypeID CFXMLNodeGetTypeID(void);
+CFTypeID CFXMLNodeGetTypeID(void) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Creates a new node based on xmlType, dataString, and additionalInfoPtr.  version (together with xmlType) determines the expected structure of additionalInfoPtr */
 CF_EXPORT
-CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalInfoPtr, CFIndex version);
+CFXMLNodeRef CFXMLNodeCreate(CFAllocatorRef alloc, CFXMLNodeTypeCode xmlType, CFStringRef dataString, const void *additionalInfoPtr, CFIndex version) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Creates a copy of origNode (which may not be NULL). */
 CF_EXPORT
-CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode);
+CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node);
+CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-CFStringRef CFXMLNodeGetString(CFXMLNodeRef node);
+CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node);
+const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node);
+CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* CFXMLTreeRef */
 
 /* Creates a childless, parentless tree from node */
 CF_EXPORT
-CFXMLTreeRef CFXMLTreeCreateWithNode(CFAllocatorRef allocator, CFXMLNodeRef node);
+CFXMLTreeRef CFXMLTreeCreateWithNode(CFAllocatorRef allocator, CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Extracts and returns the node stored in xmlTree */
 CF_EXPORT
-CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlTree);
+CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlTree) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXTERN_C_END
 
index 974dc728369d0646b4bb1ddbe22d38c844ac7edc..16dda0460ab94c26dc44dc8cdaea50c7407d8ba6 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLParser.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
@@ -32,6 +32,9 @@
 #include "CFUniChar.h" 
 #include "CFInternal.h"
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 struct __CFXMLParser {
     CFRuntimeBase _cfBase;
 
@@ -2058,4 +2061,4 @@ CFStringRef CFXMLCreateStringByUnescapingEntities(CFAllocatorRef allocator, CFSt
     return newString;
 }
 
-
+#pragma GCC diagnostic pop
index 9a09b5c0af9036a176eb2ae3d227d45c38bc7440..aa5b54d4fd6ab3d20901aef123b86530240d45c5 100644 (file)
  */
 
 /*     CFXMLParser.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
-/*  CFXMLParser is deprecated. Clients should be aware of the fact that CFXMLParser has some serious 
-    deficiencies in terms of both performance and standards compliance and should migrate their XML 
-    parsing to NSXMLParser, NSXMLDocument, or other XML parsing technologies.
- */
+/*  CFXMLParser is deprecated as of Mac OS X 10.8. The suggested replacements are the Foundation classes NSXMLParser and NSXMLDocument, or the libxml2 library. */
 
 #if !defined(__COREFOUNDATION_CFXMLPARSER__)
 #define __COREFOUNDATION_CFXMLPARSER__ 1
@@ -75,7 +72,7 @@ kCFXMLParserAddImpliedAttributes -
    Currently not supported.
 */
 
-enum {
+typedef CF_OPTIONS(CFOptionFlags, CFXMLParserOptions) {
     kCFXMLParserValidateDocument = (1UL << 0),
     kCFXMLParserSkipMetaData = (1UL << 1),
     kCFXMLParserReplacePhysicalEntities = (1UL << 2),
@@ -85,10 +82,9 @@ enum {
     kCFXMLParserAllOptions = 0x00FFFFFF,
     kCFXMLParserNoOptions = 0
 };
-typedef CFOptionFlags CFXMLParserOptions;
 
 /* This list is expected to grow */
-enum {
+typedef CF_OPTIONS(CFIndex, CFXMLParserStatusCode) {
     kCFXMLStatusParseNotBegun = -2,
     kCFXMLStatusParseInProgress = -1,
     kCFXMLStatusParseSuccessful = 0,
@@ -108,7 +104,6 @@ enum {
     kCFXMLErrorMalformedParsedCharacterData,
     kCFXMLErrorNoData
 };
-typedef CFIndex CFXMLParserStatusCode;
 
 
 /*  These functions are called as a parse progresses.
@@ -178,7 +173,7 @@ typedef struct {
 } CFXMLParserContext;
 
 CF_EXPORT
-CFTypeID CFXMLParserGetTypeID(void);
+CFTypeID CFXMLParserGetTypeID(void) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Creates a parser which will parse the given data with the given options.  xmlData may not be NULL. 
    dataSource should be the URL from which the data came, and may be NULL; it is used to resolve any
@@ -188,48 +183,48 @@ CFTypeID CFXMLParserGetTypeID(void);
    callBacks->endXMLStructure must all be non-NULL.  context determines what if any info pointer is
    passed to the callbacks as the parse progresses; context may be NULL.  */
 CF_EXPORT
-CFXMLParserRef CFXMLParserCreate(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context);
+CFXMLParserRef CFXMLParserCreate(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Arguments as above, except that the data to be parsed is loaded directly 
    from dataSource.  dataSource may not be NULL.  */
 CF_EXPORT
-CFXMLParserRef CFXMLParserCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context);
+CFXMLParserRef CFXMLParserCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFXMLParserCallBacks *callBacks, CFXMLParserContext *context) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context);
+void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks);
+void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser);
+CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Returns the character index of the current parse location */
 CF_EXPORT
-CFIndex CFXMLParserGetLocation(CFXMLParserRef parser);
+CFIndex CFXMLParserGetLocation(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Returns the line number of the current parse location */
 CF_EXPORT
-CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser);
+CFIndex CFXMLParserGetLineNumber(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Returns the top-most object returned by the createXMLStructure callback */
 CF_EXPORT
-void *CFXMLParserGetDocument(CFXMLParserRef parser);
+void *CFXMLParserGetDocument(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Get the status code or a user-readable description of the last error that occurred in a parse.
    If no error has occurred, a null description string is returned.  See the enum above for
    possible status returns */
 CF_EXPORT
-CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser);
+CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 CF_EXPORT
-CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser);
+CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Cause any in-progress parse to abort with the given error code and description.  errorCode
    must be positive, and errorDescription may not be NULL.  Cannot be called asynchronously
    (i.e. must be called from within a parser callback) */
 CF_EXPORT
-void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription);
+void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CFStringRef errorDescription) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Starts a parse of the data the parser was created with; returns success or failure.
    Upon success, use CFXMLParserGetDocument() to get the product of the parse.  Upon
@@ -237,7 +232,7 @@ void CFXMLParserAbort(CFXMLParserRef parser, CFXMLParserStatusCode errorCode, CF
    information about the error.  It is an error to call CFXMLParserParse() while a
    parse is already underway. */
 CF_EXPORT
-Boolean CFXMLParserParse(CFXMLParserRef parser);
+Boolean CFXMLParserParse(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* These functions provide a higher-level interface.  The XML data is parsed to a
    special CFTree (an CFXMLTree) with known contexts and callbacks.  See CFXMLNode.h
@@ -246,17 +241,17 @@ Boolean CFXMLParserParse(CFXMLParserRef parser);
 /* Parse to an CFXMLTreeRef.  parseOptions are as above. versionOfNodes determines
    what version CFXMLNodes are used to populate the tree.  */
 CF_EXPORT
-CFXMLTreeRef CFXMLTreeCreateFromData(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes);
+CFXMLTreeRef CFXMLTreeCreateFromData(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* As above, with the additional by-reference pass of a CFDictionaryRef containing
    various error information (see below). The caller is responsible for releasing the
    returned dictionary. If the error dictionary is not desired, pass NULL. */
 CF_EXPORT
-CFXMLTreeRef CFXMLTreeCreateFromDataWithError(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFDictionaryRef *errorDict);
+CFXMLTreeRef CFXMLTreeCreateFromDataWithError(CFAllocatorRef allocator, CFDataRef xmlData, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes, CFDictionaryRef *errorDict) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Loads the data to be parsed directly from dataSource.  Arguments as above. */
 CF_EXPORT
-CFXMLTreeRef CFXMLTreeCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes);
+CFXMLTreeRef CFXMLTreeCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef dataSource, CFOptionFlags parseOptions, CFIndex versionOfNodes) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Generate the XMLData (ready to be written to whatever permanent storage is to be
    used) from an CFXMLTree.  Will NOT regenerate entity references (except those
@@ -264,7 +259,7 @@ CFXMLTreeRef CFXMLTreeCreateWithDataFromURL(CFAllocatorRef allocator, CFURLRef d
    clients that wish this should walk the tree and re-insert any entity references
    that should appear in the final output file. */
 CF_EXPORT
-CFDataRef CFXMLTreeCreateXMLData(CFAllocatorRef allocator, CFXMLTreeRef xmlTree);
+CFDataRef CFXMLTreeCreateXMLData(CFAllocatorRef allocator, CFXMLTreeRef xmlTree) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0);
 
 /* Escaping and unescaping XML entities in CFStrings. The standard XML entities
    are always replaced.  */
index 5886267275286c7cf5e7928339d11dcf481f245f..03a9b0dd051d4a2f072c86da8313ed7154550fc7 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CFXMLPreferencesDomain.c
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
index 326b0ad48dde431a37acf19d7f3e4ce99cd6393d..0c704a340723a9a1d0f4412c7df24feb5709d28e 100644 (file)
  */
 
 /*     CFXMLTree.c
-       Copyright (c) 1999-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1999-2012, Apple Inc. All rights reserved.
        Responsibility: David Smith
 */
 
 #include "CFInternal.h"
 #include <CoreFoundation/CFXMLParser.h>
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
 /*************/
 /* CFXMLTree */
 /*************/
@@ -256,4 +259,4 @@ static void _CFAppendXMLEpilog(CFMutableStringRef str, CFXMLTreeRef tree) {
     }
 }
 
-
+#pragma GCC diagnostic pop
index c3e9bda444a0c7175e3794f0bf7fbe8428269e3f..100e4e512094f45650f1398fc59b2248744e81e8 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CoreFoundation.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !defined(__COREFOUNDATION_COREFOUNDATION__)
@@ -84,6 +84,7 @@
 #include <CoreFoundation/CFURL.h>
 #include <CoreFoundation/CFURLAccess.h>
 #include <CoreFoundation/CFUUID.h>
+#include <CoreFoundation/CFUtilities.h>
 
 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32
 #include <CoreFoundation/CFBundle.h>
index 2b40e93cc459f62871503a30c132c84cfaed59c7..f353a9a13b89b1c7baefff87b5e2643a77f429d9 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     CoreFoundation_Prefix.h
-       Copyright (c) 2005-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2005-2012, Apple Inc. All rights reserved.
 */
 
 
@@ -53,11 +53,10 @@ typedef char * Class;
 #define nil NULL
 #endif
 
-#if DEPLOYMENT_TARGET_MACOSX && defined(__ppc__)
-#define SUPPORT_CFM 1
-#endif
+#define CRSetCrashLogMessage(A) do {} while (0)
+#define CRSetCrashLogMessage2(A) do {} while (0)
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #import <libkern/OSAtomic.h>
 #import <pthread.h>
 #endif
@@ -120,6 +119,7 @@ typedef int         boolean_t;
 #define strtod_l(a,b,locale) strtod(a,b)
 #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) strtoll(a,b,c)
 #define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c)
 
 #define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__)
@@ -209,6 +209,7 @@ CF_EXPORT int _NS_access(const char *name, int amode);
 #endif
 
 // The order of these includes is important
+#define FD_SETSIZE 1024
 #include <winsock2.h>
 #include <windows.h>
 #include <pthread.h>
@@ -261,11 +262,22 @@ CF_INLINE size_t malloc_size(void *memblock) {
     return _msize(memblock);
 }
 
-#define mach_absolute_time() ((uint64_t)(CFAbsoluteTimeGetCurrent() * 1000000000.0))
+CF_INLINE uint64_t mach_absolute_time() {
+    LARGE_INTEGER count;
+    QueryPerformanceCounter(&count);
+    // mach_absolute_time is unsigned, but this function returns a signed value.
+    return (uint64_t)count.QuadPart;
+}
+
+CF_INLINE long long llabs(long long v) {
+    if (v < 0) return -v;
+    return v;
+}
 
 #define strtod_l(a,b,locale) strtod(a,b)
 #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_l(a, b, c, d) _strnicmp(a, b, c)
 #define snprintf _snprintf
 
@@ -451,36 +463,6 @@ CF_INLINE void objc_collect(unsigned long options) { }
     
 #endif
 
-// Need to use the _O_BINARY flag on Windows to get the correct behavior
-#if DEPLOYMENT_TARGET_WINDOWS
-    #define CF_OPENFLGS        (_O_BINARY|_O_NOINHERIT)
-#else
-    #define CF_OPENFLGS        (0)
-#endif
-
-#if DEPLOYMENT_TARGET_WINDOWS
-
-// These are replacements for pthread calls on Windows
-CF_EXPORT int _NS_pthread_main_np();
-CF_EXPORT int _NS_pthread_setspecific(pthread_key_t key, const void *val);
-CF_EXPORT void* _NS_pthread_getspecific(pthread_key_t key);
-CF_EXPORT int _NS_pthread_key_init_np(int key, void (*destructor)(void *));
-CF_EXPORT void _NS_pthread_setname_np(const char *name);
-    
-// map use of pthread_set/getspecific to internal API
-#define pthread_setspecific _NS_pthread_setspecific
-#define pthread_getspecific _NS_pthread_getspecific
-#define pthread_key_init_np _NS_pthread_key_init_np
-#define pthread_main_np _NS_pthread_main_np
-#define pthread_setname_np _NS_pthread_setname_np
-#endif
-
-#if DEPLOYMENT_TARGET_WINDOWS
-// replacement for DISPATCH_QUEUE_OVERCOMMIT until we get a bug fix in dispatch on Windows
-// <rdar://problem/7923891> dispatch on Windows: Need queue_private.h
-#define DISPATCH_QUEUE_OVERCOMMIT 2
-#endif
-    
 #if DEPLOYMENT_TARGET_WINDOWS && defined(__cplusplus)
 } // extern "C"
 #endif
index 0e9449311a3745e43e46a44ea4e81a41c83a20b3..2a304eac518b3003dede9a6ddb0d675e9e2ea147 100644 (file)
@@ -22,7 +22,7 @@
  */
 
 /*     ForFoundationOnly.h
-       Copyright (c) 1998-2011, Apple Inc. All rights reserved.
+       Copyright (c) 1998-2012, Apple Inc. All rights reserved.
 */
 
 #if !CF_BUILDING_CF && !NSBUILDINGFOUNDATION
@@ -53,7 +53,7 @@ CF_EXTERN_C_BEGIN
 
 #if DEPLOYMENT_TARGET_LINUX
 #include <malloc.h>
-#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
 #include <malloc/malloc.h>
 #endif
 
@@ -61,7 +61,7 @@ CF_EXTERN_C_END
 
 // ---- CFBundle material ----------------------------------------
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
 #include <CoreFoundation/CFBundlePriv.h>
 
 CF_EXTERN_C_BEGIN
@@ -78,6 +78,8 @@ 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);
@@ -386,7 +388,6 @@ CF_EXPORT bool __CFBinaryPlistGetTopLevelInfo(const uint8_t *databytes, uint64_t
 CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects);
 CF_EXPORT bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFTypeRef key, uint64_t *koffset, uint64_t *voffset, Boolean unused, CFMutableDictionaryRef objects);
 CF_EXPORT bool __CFBinaryPlistCreateObject(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFPropertyListRef *plist);
-CF_EXPORT bool __CFBinaryPlistCreateObject2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFPropertyListRef *plist);
 CF_EXPORT CFIndex __CFBinaryPlistWriteToStream(CFPropertyListRef plist, CFTypeRef stream);
 CF_EXPORT CFIndex __CFBinaryPlistWriteToStreamWithEstimate(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate); // will be removed soon
 CF_EXPORT CFIndex __CFBinaryPlistWriteToStreamWithOptions(CFPropertyListRef plist, CFTypeRef stream, uint64_t estimate, CFOptionFlags options); // will be removed soon
@@ -505,7 +506,7 @@ CF_EXPORT void *__CFURLReservedPtr(CFURLRef  url);
 CF_EXPORT void __CFURLSetReservedPtr(CFURLRef  url, void *ptr);
 CF_EXPORT CFStringEncoding _CFURLGetEncoding(CFURLRef url);
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS
 CF_EXPORT Boolean _CFRunLoopFinished(CFRunLoopRef rl, CFStringRef mode);
 #endif
 
@@ -536,7 +537,7 @@ enum {
 CF_EXPORT CFRange _CFDataFindBytes(CFDataRef data, CFDataRef dataToFind, CFRange searchRange, CFDataSearchFlags compareOptions);
 
 
-#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
+#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
     #if !defined(__CFReadTSR)
     #include <mach/mach_time.h>
     #define __CFReadTSR() mach_absolute_time()
index 65a3bc9ea6826fcb5912208325174b9611fa714f..944c11fbd93d60b1f6ab8204b342115f7b21a2d0 100644 (file)
@@ -15,7 +15,7 @@
        <key>CFBundlePackageType</key>
        <string>FMWK</string>
        <key>CFBundleShortVersionString</key>
-       <string>6.7.2</string>
+       <string>6.8</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
index db97d3335619363969d36d829f2a5285b3dbdd5e..7093efad54dee46297b596d894e7a13e4a3b5db1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 
 include MakefileVersion
 
-MIN_MACOSX_VERSION=10.7
-MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_7
+MIN_MACOSX_VERSION=10.8
+MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_8
 
 OBJECTS = $(patsubst %.c,%.o,$(wildcard *.c))
 OBJECTS += CFBasicHash.o
@@ -11,7 +11,7 @@ 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
 
-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
+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
 
 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)
@@ -26,7 +26,7 @@ STYLE_LFLAGS=
 ARCHFLAGS=-arch i386 -arch x86_64
 INSTALLNAME=/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation_$(STYLE)
 
-CC = /usr/bin/llvm-gcc
+CC = /usr/bin/clang
 
 CFLAGS=-c -x c -pipe -std=gnu99 -Wmost -Wno-trigraphs -mmacosx-version-min=$(MIN_MACOSX_VERSION) -fconstant-cfstrings -fexceptions -DCF_BUILDING_CF=1 -DDEPLOYMENT_TARGET_MACOSX=1 -DMAC_OS_X_VERSION_MAX_ALLOWED=$(MAX_MACOSX_VERSION) -DU_SHOW_DRAFT_API=1 -DU_SHOW_CPLUSPLUS_API=0 -I$(OBJBASE) -DVERSION=$(VERSION) -include CoreFoundation_Prefix.h
 
index 43bc87c99f760460750607fee151090f2739a080..19e6ee73a82d6425c1a14a7cfa920ccbb6411de2 100644 (file)
@@ -4,7 +4,7 @@ include MakefileVersion
 MIN_MACOSX_VERSION=10.7
 MAX_MACOSX_VERSION=MAC_OS_X_VERSION_10_7
 
-OBJECTS = CFCharacterSet.o CFPreferences.o CFApplicationPreferences.o CFXMLPreferencesDomain.o CFStringEncodingConverter.o CFUniChar.o CFArray.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 = 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))
index 3b0484288ffa6321e7a811c1f09c2cfaed8ff51a..642bf7027921447ab611fcf6d00c451f8f4a2004 100644 (file)
@@ -1 +1 @@
-VERSION=635.21
+VERSION=744
index f02a1871d2e9afbe8cd07855193e91944231d965..b256dae79da6246886e7e6783bf2eaaaf6762138 100644 (file)
@@ -1,5 +1,5 @@
 /*     TargetConditionals.h
-       Copyright (c) 2010-2011, Apple Inc. All rights reserved.
+       Copyright (c) 2010-2012, Apple Inc. All rights reserved.
        For CF on Linux ONLY
 */