diff --git a/CoreFoundation/AppServices.subproj/CFNotificationCenter.h b/CoreFoundation/AppServices.subproj/CFNotificationCenter.h index b87b54623a..27852b0981 100644 --- a/CoreFoundation/AppServices.subproj/CFNotificationCenter.h +++ b/CoreFoundation/AppServices.subproj/CFNotificationCenter.h @@ -1,7 +1,7 @@ /* CFNotificationCenter.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/AppServices.subproj/CFUserNotification.c b/CoreFoundation/AppServices.subproj/CFUserNotification.c index e6dca66e77..d7fef4615e 100644 --- a/CoreFoundation/AppServices.subproj/CFUserNotification.c +++ b/CoreFoundation/AppServices.subproj/CFUserNotification.c @@ -1,7 +1,7 @@ /* CFUserNotification.c - Copyright (c) 2000-2017, Apple Inc. All rights reserved. + Copyright (c) 2000-2016, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/AppServices.subproj/CFUserNotification.h b/CoreFoundation/AppServices.subproj/CFUserNotification.h index 9d01d7b333..c6b9db659c 100644 --- a/CoreFoundation/AppServices.subproj/CFUserNotification.h +++ b/CoreFoundation/AppServices.subproj/CFUserNotification.h @@ -1,7 +1,7 @@ /* CFUserNotification.h - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -170,7 +170,7 @@ CF_EXPORT const CFStringRef kCFUserNotificationTextFieldValuesKey; CF_EXPORT -const CFStringRef kCFUserNotificationPopUpSelectionKey API_AVAILABLE(macos(10.3)) API_UNAVAILABLE(ios, watchos, tvos); +const CFStringRef kCFUserNotificationPopUpSelectionKey CF_AVAILABLE(10_3, NA); #if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) CF_EXPORT diff --git a/CoreFoundation/Base.subproj/CFAvailability.h b/CoreFoundation/Base.subproj/CFAvailability.h index fcb977d479..f8ed142818 100644 --- a/CoreFoundation/Base.subproj/CFAvailability.h +++ b/CoreFoundation/Base.subproj/CFAvailability.h @@ -1,7 +1,7 @@ /* CFAvailability.h - Copyright (c) 2013-2017, Apple Inc. and the Swift project authors + Copyright (c) 2013-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,23 +10,23 @@ #if !defined(__COREFOUNDATION_CFAVAILABILITY__) #define __COREFOUNDATION_CFAVAILABILITY__ 1 -#if __has_include() +#if DEPLOYMENT_RUNTIME_SWIFT #include -#elif __has_include() -#include #else -#error Missing header TargetConditionals.h +#include #endif -#if __has_include() && __has_include() && __has_include() +#if DEPLOYMENT_RUNTIME_SWIFT +#define API_AVAILABLE(...) +#define API_DEPRECATED(...) +#else +#if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_WIN32) #include #include + // Even if unused, these must remain here for compatibility, because projects rely on them being included. #include -#else -#define API_AVAILABLE(...) -#define API_DEPRECATED(...) -#define API_UNAVAILABLE(...) +#endif #endif #ifndef __has_feature @@ -112,22 +112,14 @@ #endif // Enums and Options -#if __has_attribute(enum_extensibility) -#define __CF_ENUM_ATTRIBUTES __attribute__((enum_extensibility(open))) -#define __CF_OPTIONS_ATTRIBUTES __attribute__((flag_enum,enum_extensibility(open))) -#else -#define __CF_ENUM_ATTRIBUTES -#define __CF_OPTIONS_ATTRIBUTES -#endif - #define __CF_ENUM_GET_MACRO(_1, _2, NAME, ...) NAME #if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) -#define __CF_NAMED_ENUM(_type, _name) enum __CF_ENUM_ATTRIBUTES _name : _type _name; enum _name : _type -#define __CF_ANON_ENUM(_type) enum __CF_ENUM_ATTRIBUTES : _type +#define __CF_NAMED_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#define __CF_ANON_ENUM(_type) enum : _type #if (__cplusplus) -#define CF_OPTIONS(_type, _name) _type _name; enum __CF_OPTIONS_ATTRIBUTES : _type +#define CF_OPTIONS(_type, _name) _type _name; enum : _type #else -#define CF_OPTIONS(_type, _name) enum __CF_OPTIONS_ATTRIBUTES _name : _type _name; enum _name : _type +#define CF_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type #endif #else #define __CF_NAMED_ENUM(_type, _name) _type _name; enum @@ -164,40 +156,11 @@ CF_ENUM(CFIndex) { #if DEPLOYMENT_RUNTIME_SWIFT #define CF_STRING_ENUM #define CF_EXTENSIBLE_STRING_ENUM - -#define CF_TYPED_ENUM -#define CF_TYPED_EXTENSIBLE_ENUM #else #define CF_STRING_ENUM _CF_TYPED_ENUM #define CF_EXTENSIBLE_STRING_ENUM _CF_TYPED_EXTENSIBLE_ENUM - -#define CF_TYPED_ENUM _CF_TYPED_ENUM -#define CF_TYPED_EXTENSIBLE_ENUM _CF_TYPED_EXTENSIBLE_ENUM -#endif - -#define __CF_ERROR_ENUM_GET_MACRO(_1, _2, NAME, ...) NAME -#if ((__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum))) && __has_attribute(ns_error_domain) -#define __CF_NAMED_ERROR_ENUM(_domain, _name) enum __attribute__((ns_error_domain(_domain))) _name : CFIndex _name; enum _name : CFIndex -#define __CF_ANON_ERROR_ENUM(_domain) enum __attribute__((ns_error_domain(_domain))) : CFIndex -#else -#define __CF_NAMED_ERROR_ENUM(_domain, _name) __CF_NAMED_ENUM(CFIndex, _name) -#define __CF_ANON_ERROR_ENUM(_domain) __CF_ANON_ENUM(CFIndex) #endif -/* CF_ERROR_ENUM supports the use of one or two arguments. The first argument is always the domain specifier for the enum. The second argument is an optional name of the typedef for the macro. When specifying a name for of the typedef, you must precede the macro with 'typedef' like so: - - typedef CF_ERROR_ENUM(kCFSomeErrorDomain, SomeErrorCodes) { - ... - }; - - If you do not specify a typedef name, do not use 'typedef', like so: - - CF_ERROR_ENUM(kCFSomeErrorDomain) { - ... - }; - */ -#define CF_ERROR_ENUM(...) __CF_ERROR_ENUM_GET_MACRO(__VA_ARGS__, __CF_NAMED_ERROR_ENUM, __CF_ANON_ERROR_ENUM)(__VA_ARGS__) - // Extension availability macros #define CF_EXTENSION_UNAVAILABLE(_msg) __OS_EXTENSION_UNAVAILABLE(_msg) #define CF_EXTENSION_UNAVAILABLE_MAC(_msg) __OSX_EXTENSION_UNAVAILABLE(_msg) diff --git a/CoreFoundation/Base.subproj/CFBase.c b/CoreFoundation/Base.subproj/CFBase.c index 0cdb25ed7a..956449c43d 100644 --- a/CoreFoundation/Base.subproj/CFBase.c +++ b/CoreFoundation/Base.subproj/CFBase.c @@ -1,7 +1,7 @@ /* CFBase.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -533,7 +533,12 @@ static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorC if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator"); } memset(memory, 0, sizeof(CFRuntimeBase)); - __CFRuntimeSetRC(memory, 1); +#if __LP64__ + memory->_base._rc = 1; +#else + memory->_base._cfinfo[CF_RC_BITS] = 1; +#endif + memory->_base._cfinfo[CF_INFO_BITS] = 0; _CFAllocatorSetInstanceTypeIDAndIsa(memory); #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI memory->size = __CFAllocatorCustomSize; @@ -753,41 +758,6 @@ void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context // -------- -------- -------- -------- -------- -------- -------- -------- - -static void __CFReallocationFailed(void *ptr, CFStringRef reason, void (^reallocationFailureHandler)(void *original, _Bool *outRecovered)) { - _Bool recovered = false; - if (reallocationFailureHandler) { - reallocationFailureHandler(ptr, &recovered); - } - - if (!recovered) { - CRSetCrashLogMessage("Failed to grow buffer"); - HALT; - } -} - - -void *__CFSafelyReallocate(void *destination, size_t newCapacity, void (^reallocationFailureHandler)(void *original, _Bool *outRecovered)) { - void *const reallocated = realloc(destination, newCapacity); - if (__builtin_expect(reallocated == NULL, false)) { - __CFReallocationFailed(destination, CFSTR("realloc"), reallocationFailureHandler); - } - return reallocated; -} - - -void *__CFSafelyReallocateWithAllocator(CFAllocatorRef allocator, void *destination, size_t newCapacity, CFOptionFlags options, void (^reallocationFailureHandler)(void *original, _Bool *outRecovered)) { - void *reallocated = CFAllocatorReallocate(allocator, destination, newCapacity, options); - // NOTE: important difference in behavior between realloc vs CFAllocateReallocate NULL+0 -> NULL for allocators! - if (__builtin_expect(reallocated == NULL, false) && !(destination == NULL && newCapacity == 0)) { - __CFReallocationFailed(destination, CFSTR("realloc"), reallocationFailureHandler); - } - return reallocated; -} - - - - CFRange __CFRangeMake(CFIndex loc, CFIndex len) { CFRange range; range.location = loc; diff --git a/CoreFoundation/Base.subproj/CFBase.h b/CoreFoundation/Base.subproj/CFBase.h index 0dc06b1e76..6cd690a08e 100644 --- a/CoreFoundation/Base.subproj/CFBase.h +++ b/CoreFoundation/Base.subproj/CFBase.h @@ -1,7 +1,7 @@ /* CFBase.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -66,10 +66,6 @@ #if defined(__GNUC__) || TARGET_OS_WIN32 #include #include -#endif - -#if __BLOCKS__ && ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) -#include #endif #if ((TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) && !DEPLOYMENT_RUNTIME_SWIFT @@ -139,9 +135,11 @@ #endif #endif #else - -#define CF_EXPORT extern - + #if defined(__cplusplus) + #define CF_EXPORT extern "C" + #else + #define CF_EXPORT extern + #endif #endif CF_EXTERN_C_BEGIN @@ -656,7 +654,7 @@ void CFRelease(CFTypeRef cf); #if DEPLOYMENT_RUNTIME_SWIFT #else CF_EXPORT -CFTypeRef CFAutorelease(CFTypeRef CF_RELEASES_ARGUMENT arg) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +CFTypeRef CFAutorelease(CFTypeRef CF_RELEASES_ARGUMENT arg) CF_AVAILABLE(10_9, 7_0); CF_EXPORT CFIndex CFGetRetainCount(CFTypeRef cf); diff --git a/CoreFoundation/Base.subproj/CFByteOrder.h b/CoreFoundation/Base.subproj/CFByteOrder.h index 79fb412a55..90cada3c59 100644 --- a/CoreFoundation/Base.subproj/CFByteOrder.h +++ b/CoreFoundation/Base.subproj/CFByteOrder.h @@ -1,7 +1,7 @@ /* CFByteOrder.h - Copyright (c) 1995-2017, Apple Inc. and the Swift project authors + Copyright (c) 1995-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFFileUtilities.c b/CoreFoundation/Base.subproj/CFFileUtilities.c index df6bdc6a1a..e1ac7eab8a 100644 --- a/CoreFoundation/Base.subproj/CFFileUtilities.c +++ b/CoreFoundation/Base.subproj/CFFileUtilities.c @@ -1,7 +1,7 @@ /* CFFileUtilities.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -594,10 +594,6 @@ CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, B return _CFGetPathProperties(alloc, path, exists, posixMode, size, modTime, ownerID, dirContents); } -CF_PRIVATE bool _CFURLExists(CFURLRef url) { - Boolean exists; - return url && (0 == _CFGetFileProperties(kCFAllocatorSystemDefault, url, &exists, NULL, NULL, NULL, NULL, NULL)) && exists; -} #if DEPLOYMENT_TARGET_WINDOWS #define WINDOWS_PATH_SEMANTICS @@ -1096,22 +1092,15 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla for (CFIndex i = 0; i < CFArrayGetCount(stuffToPrefix); i++) { CFStringRef onePrefix = CFArrayGetValueAtIndex(stuffToPrefix, i); // Note: CFStringGetBytes does not null-terminate - we will do that below - CFIndex usedBufLen = 0; - startAt += CFStringGetBytes(onePrefix, CFRangeMake(0, CFStringGetLength(onePrefix)), CFStringFileSystemEncoding(), 0, false, (UInt8 *)fullPathToFile + startAt, sizeof(fullPathToFile) - startAt, &usedBufLen); - if (startAt > 0) { // Add a / if the string did not have one - // In some cases, startAt and usedBufLen differ (e.g. the num of bytes returned is less than the number written to the buffer). - if (startAt < usedBufLen) { - if (fullPathToFile[usedBufLen - 1] != (char)_CFGetSlash()) { - fullPathToFile[usedBufLen] = (char)_CFGetSlash(); - startAt += (usedBufLen - startAt) + 1; - } - } else { - if (fullPathToFile[startAt - 1] != (char)_CFGetSlash()) { - fullPathToFile[startAt++] = (char)_CFGetSlash(); - } + startAt += CFStringGetBytes(onePrefix, CFRangeMake(0, CFStringGetLength(onePrefix)), CFStringFileSystemEncoding(), 0, false, (UInt8 *)fullPathToFile + startAt, sizeof(fullPathToFile) - startAt, NULL); + if (startAt > 0) { + // Add a / if the string did not have one + if (fullPathToFile[startAt - 1] != (char)_CFGetSlash()) { + fullPathToFile[startAt++] = (char)_CFGetSlash(); } } } + fullPathToFile[startAt] = 0; } @@ -1178,7 +1167,6 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla #endif } - #if DEPLOYMENT_RUNTIME_SWIFT // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html @@ -1357,4 +1345,3 @@ CF_PRIVATE CFArrayRef _CFCreateCFArrayByTokenizingString(const char *values, cha } #endif - diff --git a/CoreFoundation/Base.subproj/CFInternal.h b/CoreFoundation/Base.subproj/CFInternal.h index 937515cac2..786d704b23 100644 --- a/CoreFoundation/Base.subproj/CFInternal.h +++ b/CoreFoundation/Base.subproj/CFInternal.h @@ -1,7 +1,7 @@ /* CFInternal.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -92,8 +92,6 @@ CF_EXTERN_C_BEGIN #include #include #include -#include -#include #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD #if TARGET_OS_CYGWIN #else @@ -173,15 +171,25 @@ CF_PRIVATE CFIndex __CFActiveProcessorCount(void); #define __builtin_unreachable() do { } while (0) #endif -#define HALT __builtin_trap() -#define HALT_MSG(str) do { CRSetCrashLogMessage(str); HALT; } while (0) +#if defined(__GNUC__) + #if defined(__i386__) || defined(__x86_64__) + #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); __builtin_unreachable(); } while (0) + #else + #define HALT do {__builtin_trap(); kill(getpid(), 9); __builtin_unreachable(); } while (0) + #endif +#elif defined(_MSC_VER) + #define HALT do { DebugBreak(); abort(); __builtin_unreachable(); } while (0) +#else + #error Compiler not supported +#endif + #if defined(DEBUG) - #define CFAssert(cond, prio, desc) do { if (!(cond)) { CFLog(prio, CFSTR(desc)); HALT; } } while (0) - #define CFAssert1(cond, prio, desc, a1) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1); HALT; } } while (0) - #define CFAssert2(cond, prio, desc, a1, a2) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2); HALT; } } while (0) - #define CFAssert3(cond, prio, desc, a1, a2, a3) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3); HALT; } } while (0) - #define CFAssert4(cond, prio, desc, a1, a2, a3, a4) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3, a4); HALT; } } while (0) + #define CFAssert(cond, prio, desc) do { if (!(cond)) { CFLog(prio, CFSTR(desc)); /* HALT; */ } } while (0) + #define CFAssert1(cond, prio, desc, a1) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1); /* HALT; */ } } while (0) + #define CFAssert2(cond, prio, desc, a1, a2) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2); /* HALT; */ } } while (0) + #define CFAssert3(cond, prio, desc, a1, a2, a3) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3); /* HALT; */ } } while (0) + #define CFAssert4(cond, prio, desc, a1, a2, a3, a4) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3, a4); /* HALT; */ } } while (0) #else #define CFAssert(cond, prio, desc) do {} while (0) #define CFAssert1(cond, prio, desc, a1) do {} while (0) @@ -202,6 +210,9 @@ extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *fu #define __CFGenericValidateType(cf, type) ((void)0) #endif +#define CF_INFO_BITS (!!(__CF_BIG_ENDIAN__) * 3) +#define CF_RC_BITS (!!(__CF_LITTLE_ENDIAN__) * 3) + /* Bit manipulation macros */ /* Bits are numbered from 31 on left to 0 on right */ /* May or may not work if you use them on bitfields in types other than UInt32, bitfields the full width of a UInt32, or anything else for which they were not designed. */ @@ -209,62 +220,7 @@ extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *fu #define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1)) #define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2)) #define __CFBitfieldSetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfieldMask(N1, N2)) | (((X) << (N2)) & __CFBitfieldMask(N1, N2))) - -#define __CFBitfield64Mask(N1, N2) ((((uint64_t)~0ULL) << (63ULL - (N1) + (N2))) >> (63ULL - N1)) -#define __CFBitfield64GetValue(V, N1, N2) (((V) & __CFBitfield64Mask(N1, N2)) >> (N2)) -#define __CFBitfield64SetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfield64Mask(N1, N2)) | ((((uint64_t)X) << (N2)) & __CFBitfield64Mask(N1, N2))) - -#if __LP64__ -typedef uint64_t __CFInfoType; -#define __CFInfoMask(N1, N2) __CFBitfield64Mask(N1, N2) -#else -typedef uint32_t __CFInfoType; -#define __CFInfoMask(N1, N2) __CFBitfieldMask(N1, N2) -#endif - -/// Get a value from a CFTypeRef info bitfield. -/// -/// Bits are numbered from 6 on left to 0 on right. n1 and n2 specify an inclusive range n1..n2 with n1 >= n2. -/// For example: -/// n1 == 6, n2 == 4 will result in using the mask 0x0070. The value must fit inside 3 bits (6 - 4 + 1). -/// n1 == 0, n2 == 0 will result in using the mask 0x0001. The value must be 1 bit (0 - 0 + 1). -static inline uint8_t __CFRuntimeGetValue(CFTypeRef cf, uint8_t n1, uint8_t n2) { - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - return (info & __CFInfoMask(n1, n2)) >> n2; -} - -/// Get a flag from a CFTypeRef info bitfield. -/// -/// Bits are numbered from 7 on left to 0 on right. -static inline Boolean __CFRuntimeGetFlag(CFTypeRef cf, uint8_t n) { - return __CFRuntimeGetValue(cf, n, n) == 1; -} - -/// Set a value in a CFTypeRef info bitfield. -/// -/// Bits are numbered from 6 on left to 0 on right. n1 and n2 specify an inclusive range n1..n2 with n1 >= n2. -/// For example: -/// n1 == 6, n2 == 4 will result in using the mask 0x0070. The value must fit inside 3 bits (6 - 4 + 1). -/// n1 == 0, n2 == 0 will result in using the mask 0x0001. The value must be 1 bit (0 - 0 + 1). -static inline void __CFRuntimeSetValue(CFTypeRef cf, uint8_t n1, uint8_t n2, uint8_t x) { - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - __CFInfoType newInfo; - __CFInfoType mask = __CFInfoMask(n1, n2); - do { - // maybe don't need to do the negation part because the right side promises that we are not going to touch the rest of the word - newInfo = (info & ~mask) | ((x << n2) & mask); - } while (!atomic_compare_exchange_weak(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); -} - -/// Set a flag in a CFTypeRef info bitfield. -/// -/// Bits are numbered from 7 on left to 0 on right. -static inline void __CFRuntimeSetFlag(CFTypeRef cf, uint8_t n, Boolean flag) { - __CFRuntimeSetValue(cf, n, n, flag ? 1 : 0); -} - -CF_PRIVATE Boolean __CFRuntimeIsConstant(CFTypeRef cf); -CF_PRIVATE void __CFRuntimeSetRC(CFTypeRef cf, uint32_t rc); +#define __CFBitfieldMaxValue(N1, N2) __CFBitfieldGetValue(0xFFFFFFFFUL, (N1), (N2)) #define __CFBitIsSet(V, N) (((V) & (1UL << (N))) != 0) #define __CFBitSet(V, N) ((V) |= (1UL << (N))) @@ -287,7 +243,6 @@ enum { __CFTSDKeyWeakReferenceHandler = 14, __CFTSDKeyIsInPreferences = 15, __CFTSDKeyIsHoldingGlobalPreferencesLock = 16, // this can be removed if we run out of TSD keys, it's just for assertions - __CFTSDKeyPendingPreferencesKVONotifications = 17, // autorelease pool stuff must be higher than run loop constants __CFTSDKeyAutoreleaseData2 = 61, __CFTSDKeyAutoreleaseData1 = 62, @@ -337,6 +292,10 @@ CF_INLINE CFAllocatorRef __CFGetDefaultAllocator(void) { #define __kCFAllocatorNoPointers 0x10 #define __kCFAllocatorDoNotRecordEvent 0x100 +CF_INLINE void __CFAssignWithWriteBarrier(void **location, void *value) { + *location = value; +} + CF_EXPORT CFAllocatorRef _CFTemporaryMemoryAllocator(void); extern uint64_t __CFTimeIntervalToTSR(CFTimeInterval ti); @@ -375,23 +334,7 @@ CF_PRIVATE Boolean __CFProcessIsRestricted(void); #define STACK_BUFFER_DECL(T, N, C) T N[C] #endif -#define SAFE_STACK_BUFFER_DEFINE(Type, Name) Type *Name = NULL; BOOL __ ## Name ## WasMallocd = NO; - -#if DEPLOYMENT_TARGET_WINDOWS -#define SAFE_STACK_BUFFER_DECL(Type, Name, Count, Max) Type *Name; BOOL __ ## Name ## WasMallocd = NO; if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? _alloca((Count) * sizeof(Type)) : NULL -#define SAFE_STACK_BUFFER_USE(Type, Name, Count, Max) if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? _alloca((Count) * sizeof(Type)) : NULL -#else -// Declare and allocate a stack buffer. Max is the max size (in bytes) before falling over to malloc. -#define SAFE_STACK_BUFFER_DECL(Type, Name, Count, Max) Type *Name; BOOL __ ## Name ## WasMallocd = NO; if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? alloca((Count) * sizeof(Type)) : NULL - -// Allocate a pre-named stack buffer. Max is the max size (in bytes) before falling over to malloc. -#define SAFE_STACK_BUFFER_USE(Type, Name, Count, Max) if (sizeof(Type) * Count > Max) { Name = (Type *)malloc((Count) * sizeof(Type)); __ ## Name ## WasMallocd = YES; } else Name = (Count > 0) ? alloca((Count) * sizeof(Type)) : NULL -#endif // DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED - -// Be sure to call this before your SAFE_STACK_BUFFER exits scope. -#define SAFE_STACK_BUFFER_CLEANUP(Name) if (__ ## Name ## WasMallocd) free(Name) -CF_EXPORT void * __CFConstantStringClassReferencePtr; #if DEPLOYMENT_RUNTIME_SWIFT @@ -401,8 +344,15 @@ CF_EXPORT void * __CFConstantStringClassReferencePtr; #define __CFConstantStringClassReference _T010Foundation19_NSCFConstantStringCN #endif +CF_EXPORT void * __CFConstantStringClassReferencePtr; CF_EXPORT void *__CFConstantStringClassReference[]; +#if __CF_BIG_ENDIAN__ +#define CF_CONST_STRING_INFO {0x00, 0x00, 0x07, 0xc8} +#elif __CF_LITTLE_ENDIAN__ +#define CF_CONST_STRING_INFO {0xc8, 0x07, 0x00, 0x00} +#endif + #if DEPLOYMENT_TARGET_LINUX #define CONST_STRING_SECTION __attribute__((section(".cfstr.data"))) #else @@ -410,11 +360,11 @@ CF_EXPORT void *__CFConstantStringClassReference[]; #endif #define CONST_STRING_DECL(S, V) \ -const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1}; \ +const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, CF_CONST_STRING_INFO}, (uint8_t *)(V), sizeof(V) - 1}; \ const CFStringRef S = (CFStringRef)&__##S; #define PE_CONST_STRING_DECL(S, V) \ -const static struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1}; \ +const static struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, CF_CONST_STRING_INFO}, (uint8_t *)(V), sizeof(V) - 1}; \ CF_PRIVATE const CFStringRef S = (CFStringRef)&__##S; @@ -428,7 +378,11 @@ CF_PRIVATE const CFStringRef S = (CFStringRef)&__##S; struct CF_CONST_STRING { CFRuntimeBase _base; uint8_t *_ptr; - uint32_t _length; +#if defined(__LP64__) && defined(__BIG_ENDIAN__) + uint64_t _length; +#else + uint32_t _length; +#endif }; CF_EXPORT int __CFConstantStringClassReference[]; @@ -436,10 +390,10 @@ 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 */ #define CONST_STRING_DECL(S, V) \ -static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, 0x000007c8U}, (uint8_t *)V, sizeof(V) - 1}; \ +static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, CF_CONST_STRING_INFO}, (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, 0x000007c8U}, (uint8_t *)V, sizeof(V) - 1}; \ +static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, CF_CONST_STRING_INFO}, (uint8_t *)V, sizeof(V) - 1}; \ CF_PRIVATE const CFStringRef S = (CFStringRef) & __ ## S ## __; #endif // __CONSTANT_CFSTRINGS__ @@ -559,39 +513,6 @@ typedef CFLock_t OSSpinLock; #endif -#if __has_include() -#include -#else -#define OS_UNFAIR_LOCK_INIT PTHREAD_MUTEX_INITIALIZER -typedef pthread_mutex_t os_unfair_lock; -typedef pthread_mutex_t * os_unfair_lock_t; -static void os_unfair_lock_lock(os_unfair_lock_t lock) { pthread_mutex_lock(lock); } -static void os_unfair_lock_unlock(os_unfair_lock_t lock) { pthread_mutex_unlock(lock); } -#endif - -#if __has_include() -#include -#else - -static _Bool __os_warn_unused(_Bool x) __attribute__((__warn_unused_result__)); -static _Bool __os_warn_unused(_Bool x) { return x; } - -#if __has_builtin(__builtin_add_overflow) && \ - __has_builtin(__builtin_sub_overflow) && \ - __has_builtin(__builtin_mul_overflow) - -#define os_add_overflow(a, b, res) __os_warn_unused(__builtin_add_overflow((a), (b), (res))) -#define os_sub_overflow(a, b, res) __os_warn_unused(__builtin_sub_overflow((a), (b), (res))) -#define os_mul_overflow(a, b, res) __os_warn_unused(__builtin_mul_overflow((a), (b), (res))) - -#else - -#error Missing compiler support for overflow checking - -#endif - -#endif - #if !__HAS_DISPATCH__ typedef volatile long dispatch_once_t; @@ -601,8 +522,8 @@ CF_PRIVATE void _CF_dispatch_once(dispatch_once_t *, void (^)(void)); #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -extern _Atomic(uint8_t) __CF120293; -extern _Atomic(uint8_t) __CF120290; +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); #define CHECK_FOR_FORK() do { __CF120290 = true; if (__CF120293) __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(); } while (0) #define CHECK_FOR_FORK_RET(...) do { CHECK_FOR_FORK(); if (__CF120293) return __VA_ARGS__; } while (0) @@ -663,7 +584,6 @@ CF_PRIVATE SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, B /* alloc may be NULL */ /* any of exists, posixMode, size, modTime, and dirContents can be NULL. Usually it is not a good idea to pass NULL for exists, since interpretting the other values sometimes requires that you know whether the file existed or not. Except for dirContents, it is pretty cheap to compute any of these things as loing as one of them must be computed. */ -CF_PRIVATE bool _CFURLExists(CFURLRef url); /* ==================== Simple path manipulation ==================== */ @@ -825,7 +745,7 @@ CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) { // !!! Use with CF typ return kCFAllocatorSystemDefault; } #endif - if (__builtin_expect(__CFRuntimeGetFlag(cf, 7), true)) { + if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7), 1)) { return kCFAllocatorSystemDefault; } // To preserve 16 byte alignment when using custom allocators, we always place the CFAllocatorRef 16 bytes before the CFType @@ -840,10 +760,6 @@ struct __objcFastEnumerationStateEquivalent { unsigned long extra[5]; }; -CF_PRIVATE CFSetRef __CFBinaryPlistCopyTopLevelKeys(CFAllocatorRef allocator, const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer); -CF_PRIVATE bool __CFBinaryPlistIsDictionary(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer); -CF_PRIVATE bool __CFBinaryPlistIsArray(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer); - #if 0 #pragma mark - #pragma mark Windows Compatability @@ -889,17 +805,13 @@ CF_PRIVATE const wchar_t *_CFDLLPath(void); /* Buffer size for file pathname */ #if DEPLOYMENT_TARGET_WINDOWS -/// Use this constant for the size (in characters) of a buffer in which to hold a path. This size adds space for at least a couple of null terminators at the end of a buffer into which you copy up to kCFMaxPathLength characters. #define CFMaxPathSize ((CFIndex)262) -/// Use this constant for the maximum length (in characters) of a path you want to copy into a buffer. This should be the maximum number of characters before the null terminator(s). #define CFMaxPathLength ((CFIndex)260) #define PATH_SEP '\\' #define PATH_SEP_STR CFSTR("\\") #define PATH_MAX MAX_PATH #else -/// Use this constant for the size (in characters) of a buffer in which to hold a path. This size adds space for at least a couple of null terminators at the end of a buffer into which you copy up to kCFMaxPathLength characters. #define CFMaxPathSize ((CFIndex)1026) -/// Use this constant for the maximum length (in characters) of a path you want to copy into a buffer. This should be the maximum number of characters before the null terminator(s). #define CFMaxPathLength ((CFIndex)1024) #define PATH_SEP '/' #define PATH_SEP_STR CFSTR("/") @@ -976,31 +888,13 @@ CF_INLINE dispatch_queue_t __CFDispatchQueueGetGenericBackground(void) { CF_PRIVATE CFStringRef _CFStringCopyBundleUnloadingProtectedString(CFStringRef str); -CF_PRIVATE uint8_t *_CFDataGetBytePtrNonObjC(CFDataRef data); - // Use this for functions that are intended to be breakpoint hooks. If you do not, the compiler may optimize them away. // Based on: BREAKPOINT_FUNCTION in objc-os.h // Example: // CF_BREAKPOINT_FUNCTION( void stop_on_error(void) ); */ #define CF_BREAKPOINT_FUNCTION(prototype) \ extern __attribute__((noinline, used, visibility("hidden"))) \ - prototype { __asm(""); } - -#define __CF_QUEUE_NAME(a) "com.apple." a - -#pragma mark - -#pragma mark CF Instruments SPI - -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED -extern void __CFRecordAllocationEvent(int eventnum, void *ptr, int64_t size, uint64_t data, const char *classname); -#else -#define __CFRecordAllocationEvent(a, b, c, d, e) ((void)0) -#define __CFSetLastAllocationEventName(a, b) ((void)0) -#endif - -enum { - __kCFZombieMessagedEvent = 21, -}; + prototype { asm(""); } CF_EXTERN_C_END diff --git a/CoreFoundation/Base.subproj/CFLogUtilities.h b/CoreFoundation/Base.subproj/CFLogUtilities.h index c293b54810..2de40edb72 100644 --- a/CoreFoundation/Base.subproj/CFLogUtilities.h +++ b/CoreFoundation/Base.subproj/CFLogUtilities.h @@ -1,7 +1,7 @@ /* CFLogUtilities.h - Copyright (c) 2004-2017, Apple Inc. and the Swift project authors + Copyright (c) 2004-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -20,9 +20,7 @@ CF_EXTERN_C_BEGIN -// Legal level values for CFLog() -typedef int32_t CFLogLevel; -enum { +typedef CF_ENUM(int32_t, CFLogLevel) { // Legal level values for CFLog() kCFLogLevelEmergency = 0, kCFLogLevelAlert = 1, kCFLogLevelCritical = 2, diff --git a/CoreFoundation/Base.subproj/CFPlatform.c b/CoreFoundation/Base.subproj/CFPlatform.c index 343eb93d1c..5aefe20165 100644 --- a/CoreFoundation/Base.subproj/CFPlatform.c +++ b/CoreFoundation/Base.subproj/CFPlatform.c @@ -1,7 +1,7 @@ /* CFPlatform.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -123,10 +123,6 @@ const char *_CFProcessPath(void) { #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -Boolean _CFIsMainThread(void) { - return pthread_main_np() == 1; -} - const char *_CFProcessPath(void) { if (__CFProcessPath) return __CFProcessPath; #if DEPLOYMENT_TARGET_MACOSX @@ -184,6 +180,12 @@ const char *_CFProcessPath(void) { } return __CFProcessPath; } + +#else + +Boolean _CFIsMainThread(void) { + return pthread_main_np() == 1; +} #endif CF_PRIVATE CFStringRef _CFProcessNameString(void) { @@ -605,7 +607,7 @@ static void *__CFTSDGetSpecific() { #endif } -CF_PRIVATE _Atomic(bool) __CFMainThreadHasExited; +CF_PRIVATE Boolean __CFMainThreadHasExited; static void __CFTSDFinalize(void *arg) { if (pthread_main_np()) { __CFMainThreadHasExited = true; @@ -668,7 +670,7 @@ static __CFTSDTable *__CFTSDGetTable(const Boolean create) { // For the use of CF and Foundation only CF_EXPORT void *_CFGetTSDCreateIfNeeded(const uint32_t slot, const Boolean create) { - if (slot >= CF_TSD_MAX_SLOTS) { + if (slot > CF_TSD_MAX_SLOTS) { _CFLogSimple(kCFLogLevelError, "Error: TSD slot %d out of range (get)", slot); HALT; } @@ -693,7 +695,7 @@ CF_EXPORT void *_CFGetTSD(uint32_t slot) { // For the use of CF and Foundation only CF_EXPORT void *_CFSetTSD(uint32_t slot, void *newVal, tsdDestructor destructor) { - if (slot >= CF_TSD_MAX_SLOTS) { + if (slot > CF_TSD_MAX_SLOTS) { _CFLogSimple(kCFLogLevelError, "Error: TSD slot %d out of range (set)", slot); HALT; } @@ -1265,7 +1267,7 @@ CF_PRIVATE int asprintf(char **ret, const char *format, ...) { if (cnt < sz - 1) return cnt; sz = cnt + 8; char *oldret = *ret; - *ret = __CFSafelyReallocate(*ret, sz * sizeof(char), NULL); + *ret = (char *) realloc(*ret, sz * sizeof(char)); if (!*ret && oldret) free(oldret); if (!*ret) return -1; va_start(args, format); diff --git a/CoreFoundation/Base.subproj/CFPriv.h b/CoreFoundation/Base.subproj/CFPriv.h index 06891b7f29..3b5568f6c6 100644 --- a/CoreFoundation/Base.subproj/CFPriv.h +++ b/CoreFoundation/Base.subproj/CFPriv.h @@ -1,7 +1,7 @@ /* CFPriv.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -46,9 +46,6 @@ CF_EXPORT void _CFRuntimeSetCFMPresent(void *a); CF_EXPORT const char *_CFProcessPath(void); CF_EXPORT const char **_CFGetProcessPath(void); CF_EXPORT const char **_CFGetProgname(void); -CF_EXPORT void _CFGetUGIDs(uid_t *euid, gid_t *egid); -CF_EXPORT uid_t _CFGetEUID(void); -CF_EXPORT uid_t _CFGetEGID(void); #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) @@ -596,18 +593,15 @@ CF_INLINE struct timespec _CFFileTimeSpecFromAbsoluteTime(CFAbsoluteTime at) { 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) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); - -// Returns a set of the keys of the top-level dictionary of a plist. Optimized for bplist (though it works with XML too). Only supports string keys. -CF_EXPORT CFSetRef _CFPropertyListCopyTopLevelKeys(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *outError) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +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 -} API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_8, 6_0); -CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); -CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredLocalizedInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, CFStringRef localizationName, _CFBundleFilteredPlistOptions options) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.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 @@ -640,12 +634,12 @@ CF_EXPORT CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRe CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void); #endif -CF_EXPORT const CFStringRef kCFNumberFormatterUsesCharacterDirection API_AVAILABLE(macos(10.9), ios(6.0), watchos(2.0), tvos(9.0)); // CFBoolean -CF_EXPORT const CFStringRef kCFDateFormatterUsesCharacterDirection API_AVAILABLE(macos(10.9), ios(6.0), watchos(2.0), tvos(9.0)); // CFBoolean +CF_EXPORT const CFStringRef kCFNumberFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0); // CFBoolean +CF_EXPORT const CFStringRef kCFDateFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0); // CFBoolean CF_EXPORT void _CFGetPathExtensionRangesFromPathComponentUniChars(const UniChar *uchars, CFIndex ucharsLength, CFRange *outPrimaryExtRange, CFRange *outSecondaryExtRange) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT void _CFGetPathExtensionRangesFromPathComponent(CFStringRef inName, CFRange *outPrimaryExtRange, CFRange *outSecondaryExtRange) API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT void _CFGetPathExtensionRangesFromPathComponent(CFStringRef inName, CFRange *outPrimaryExtRange, CFRange *outSecondaryExtRange) CF_AVAILABLE(10_11, 9_0); CF_EXPORT Boolean _CFExtensionUniCharsIsValidToAppend(const UniChar *uchars, CFIndex ucharsLength) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); CF_EXPORT Boolean _CFExtensionIsValidToAppend(CFStringRef extension) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); diff --git a/CoreFoundation/Base.subproj/CFRuntime.c b/CoreFoundation/Base.subproj/CFRuntime.c index 9b1224d8fd..50ffb7951c 100644 --- a/CoreFoundation/Base.subproj/CFRuntime.c +++ b/CoreFoundation/Base.subproj/CFRuntime.c @@ -1,7 +1,7 @@ /* CFRuntime.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -116,6 +116,8 @@ void __CFSetLastAllocationEventName(void *ptr, const char *classname) { bool __CFOASafe = false; void __CFOAInitialize(void) { } +void __CFRecordAllocationEvent(int eventnum, void *ptr, int64_t size, uint64_t data, const char *classname) { } +void __CFSetLastAllocationEventName(void *ptr, const char *classname) { } #endif @@ -288,64 +290,6 @@ void _CFEnableZombies(void) { #endif /* DEBUG */ -/* - Layout of CF info field - - 3 2 1 - 1 4 6 7 0 - | | | | | - rrrrrrrrCDX?ttttttttttttaIIIIIII - - r = retain count - C = custom RC - D = deallocating - X = deallocated - t = type ID (12 bits, although only 10 are used because the class table size is 1024) - a = if set, use system default allocator - I = type-specific info bits (6 bits available) - - On 64 bit, also includes 32 bits more of retain count from 32-63 - */ - -#if __CF_BIG_ENDIAN__ -#define RC_INCREMENT (1ULL) -#define RC_CUSTOM_RC_BIT (0x800000ULL << 32) -#define RC_DEALLOCATING_BIT (0x400000ULL << 32) -#define RC_DEALLOCATED_BIT (0x200000ULL << 32) -#else -#define RC_INCREMENT (1ULL << 32) -#define RC_CUSTOM_RC_BIT (0x800000ULL) -#define RC_DEALLOCATING_BIT (0x400000ULL) -#define RC_DEALLOCATED_BIT (0x200000ULL) -#endif - -#if __LP64__ -#define HIGH_RC_START 32 -#define HIGH_RC_END 63 -#endif - -#define LOW_RC_START 24 -#define LOW_RC_END 31 -#define TYPE_ID_START 8 -#define TYPE_ID_END 17 - -CF_INLINE CFTypeID __CFTypeIDFromInfo(__CFInfoType info) { - // yes, 10 bits masked off, though 12 bits are there for the type field; __CFRuntimeClassTableSize is 1024 - return (info & __CFInfoMask(TYPE_ID_END, TYPE_ID_START)) >> TYPE_ID_START; -} - -/// Get the retain count from the low 32-bit field (the only one stored inline in 32 bit, and unused except for a marker in 64 bit) -CF_INLINE uint16_t __CFLowRCFromInfo(__CFInfoType info) { - return __CFBitfieldGetValue(info, LOW_RC_END, LOW_RC_START); -} - -#if __LP64__ -/// Get the retain count from the high 32-bit field (only present in 64 bit) -CF_INLINE uint32_t __CFHighRCFromInfo(__CFInfoType info) { - return __CFBitfield64GetValue(info, HIGH_RC_END, HIGH_RC_START); -} -#endif - CF_INLINE CFRuntimeBase *_cf_aligned_malloc(size_t align, CFIndex size, const char *className) { CFRuntimeBase *memory; @@ -387,10 +331,10 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF CFRuntimeBase *memory = (CFRuntimeBase *)swift_allocObject(isa, size, align - 1); // Zero the rest of the memory, starting at cfinfo - memset(&memory->_cfinfoa, 0, size - (sizeof(memory->_cfisa) + sizeof(memory->_swift_strong_rc) + sizeof(memory->_swift_weak_rc))); + memset(&memory->_cfinfo, 0, size - (sizeof(memory->_cfisa) + sizeof(memory->_swift_strong_rc) + sizeof(memory->_swift_weak_rc))); // Set up the cfinfo struct - uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfoa); + uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfo); // The 0x80 means we use the default allocator *cfinfop = (uint32_t)(((uint32_t)typeID << 8) | (0x80)); @@ -442,29 +386,21 @@ CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CF *(CFAllocatorRef *)((char *)memory) = (CFAllocatorRef)CFRetain(realAllocator); memory = (CFRuntimeBase *)((char *)memory + 16); } - - // No need for atomic operations here - memory is currently private to this thread - uint32_t typeIDMasked = (uint32_t)typeID << 8; - uint32_t usesDefaultAllocatorMasked = usesSystemDefaultAllocator ? 0x80 : 0x00; + uint32_t rc = 0; #if __LP64__ + memory->_rc = 1; if (customRC) { - // The top 32 bits of the word are all FF - // The rc bits in the lower 32 are 0xFF - memory->_cfinfoa = (uint64_t)((0xFFFFFFFFULL << 32) | ((uint32_t)(0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked)); - } else { - // The top 32 bits of the word start at 1 - // The rc bits in the lower 32 are 0 - memory->_cfinfoa = (uint64_t)((1ULL << 32) | typeIDMasked | usesDefaultAllocatorMasked); + memory->_rc = 0xFFFFFFFFU; + rc = 0xFF; } #else + rc = 1; if (customRC) { - // The rc bits in the lower 32 are 0xFF - memory->_cfinfoa = (uint32_t)((0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked); - } else { - // The rc bits in the lower 32 are 1 - memory->_cfinfoa = (uint32_t)((1 << 24) | typeIDMasked | usesDefaultAllocatorMasked); + rc = 0xFF; } #endif + uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfo); + *cfinfop = (uint32_t)((rc << 24) | (customRC ? 0x800000 : 0x0) | ((uint32_t)typeID << 8) | (usesSystemDefaultAllocator ? 0x80 : 0x00)); memory->_cfisa = __CFISAForTypeID(typeID); if (NULL != cls->init) { (cls->init)(memory); @@ -485,23 +421,10 @@ void _CFRuntimeInitStaticInstance(void *ptr, CFTypeID typeID) { return; } CFRuntimeBase *memory = (CFRuntimeBase *)ptr; - // No need for atomic operations here - memory is currently private to this thread - uint32_t typeIDMasked = (uint32_t)typeID << 8; - uint32_t usesDefaultAllocatorMasked = 0x80; + uint32_t *cfinfop = (uint32_t *)&(memory->_cfinfo); + *cfinfop = (uint32_t)(((customRC ? 0xFF : 0) << 24) | (customRC ? 0x800000 : 0x0) | ((uint32_t)typeID << 8) | 0x80); #if __LP64__ - if (customRC) { - // The top 32 bits of the word are the retain count - memory->_cfinfoa = (uint64_t)((0xFFFFFFFFULL << 32) | (uint32_t)((0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked)); - } else { - memory->_cfinfoa = (uint64_t)(typeIDMasked | usesDefaultAllocatorMasked); - } -#else - if (customRC) { - // Retain count is in cfinfo - memory->_cfinfoa = (uint32_t)((0xFF << 24) | RC_CUSTOM_RC_BIT | typeIDMasked | usesDefaultAllocatorMasked); - } else { - memory->_cfinfoa = (uint32_t)(typeIDMasked | usesDefaultAllocatorMasked); - } + memory->_rc = customRC ? 0xFFFFFFFFU : 0x0; #endif memory->_cfisa = 0; if (NULL != cfClass->init) { @@ -512,8 +435,8 @@ void _CFRuntimeInitStaticInstance(void *ptr, CFTypeID typeID) { void _CFRuntimeSetInstanceTypeID(CFTypeRef cf, CFTypeID newTypeID) { if (__CFRuntimeClassTableSize <= newTypeID) HALT; - __CFInfoType info = ((CFRuntimeBase *)cf)->_cfinfoa; - CFTypeID currTypeID = __CFTypeIDFromInfo(info); + uint32_t *cfinfop = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + CFTypeID currTypeID = (*cfinfop >> 8) & 0x03FF; // mask up to 0x0FFF CFRuntimeClass *newcfClass = __CFRuntimeClassTable[newTypeID]; Boolean newCustomRC = (newcfClass->version & _kCFRuntimeCustomRefCount); CFRuntimeClass *currcfClass = __CFRuntimeClassTable[currTypeID]; @@ -527,7 +450,7 @@ void _CFRuntimeSetInstanceTypeID(CFTypeRef cf, CFTypeID newTypeID) { // is to a class doing custom ref counting, the ref count isn't // transferred and there will probably be a crash later when the // object is freed too early. - __CFRuntimeSetValue(cf, TYPE_ID_END, TYPE_ID_START, newTypeID); + *cfinfop = (*cfinfop & 0xFFF000FFU) | ((uint32_t)newTypeID << 8); } CF_PRIVATE void _CFRuntimeSetInstanceTypeIDAndIsa(CFTypeRef cf, CFTypeID newTypeID) { @@ -596,8 +519,10 @@ CF_EXPORT uintptr_t __CFDoExternRefOperation(uintptr_t op, id obj) { CF_EXPORT CFTypeID CFNumberGetTypeID(void); CF_INLINE CFTypeID __CFGenericTypeID_inline(const void *cf) { - - return __CFTypeIDFromInfo(atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa))); + // yes, 10 bits masked off, though 12 bits are there for the type field; __CFRuntimeClassTableSize is 1024 + uint32_t *cfinfop = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + CFTypeID typeID = (*cfinfop >> 8) & 0x03FF; // mask up to 0x0FFF + return typeID; } CFTypeID __CFGenericTypeID(const void *cf) { @@ -692,8 +617,19 @@ void _CFNonObjCRelease(CFTypeRef cf) { void CFRelease(CFTypeRef cf) { if (NULL == cf) { CRSetCrashLogMessage("*** CFRelease() called with NULL ***"); HALT; } +#if 0 + void **addrs[2] = {&&start, &&end}; + start:; + if (addrs[0] <= __builtin_return_address(0) && __builtin_return_address(0) <= addrs[1]) { + CFLog(3, CFSTR("*** WARNING: Recursion in CFRelease(%p) : %p '%s' : 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx 0x%08lx"), cf, object_getClass(cf), object_getClassName(cf), ((uintptr_t *)cf)[0], ((uintptr_t *)cf)[1], ((uintptr_t *)cf)[2], ((uintptr_t *)cf)[3], ((uintptr_t *)cf)[4], ((uintptr_t *)cf)[5]); + HALT; + } +#endif if (cf) __CFGenericAssertIsCF(cf); _CFRelease(cf); +#if 0 + end:; +#endif } @@ -731,15 +667,13 @@ static CFLock_t __CFRuntimeExternRefCountTableLock = CFLockInit; static uint64_t __CFGetFullRetainCount(CFTypeRef cf) { if (NULL == cf) { CRSetCrashLogMessage("*** __CFGetFullRetainCount() called with NULL ***"); HALT; } #if __LP64__ - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - uint32_t rc = __CFHighRCFromInfo(info); - if (0 == rc) { + uint32_t lowBits = ((CFRuntimeBase *)cf)->_rc; + if (0 == lowBits) { return (uint64_t)0x0fffffffffffffffULL; } - return rc; + return lowBits; #else - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - uint32_t lowBits = __CFLowRCFromInfo(info); + uint32_t lowBits = ((CFRuntimeBase *)cf)->_cfinfo[CF_RC_BITS]; if (0 == lowBits) { return (uint64_t)0x0fffffffffffffffULL; } @@ -752,42 +686,18 @@ static uint64_t __CFGetFullRetainCount(CFTypeRef cf) { #endif } -CF_PRIVATE Boolean __CFRuntimeIsConstant(CFTypeRef cf) { - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - uint32_t rc; -#if __LP64__ - rc = __CFHighRCFromInfo(info); -#else - rc = __CFLowRCFromInfo(info); -#endif - return rc == 0; -} - -/// This is for use during initialization only. -CF_PRIVATE void __CFRuntimeSetRC(CFTypeRef cf, uint32_t rc) { - // No real need for atomics or CAS here, memory is private to thread so far - __CFInfoType info = ((CFRuntimeBase *)cf)->_cfinfoa; -#if __LP64__ - __CFBitfield64SetValue(info, HIGH_RC_END, HIGH_RC_START, rc); -#else - __CFBitfieldSetValue(info, LOW_RC_END, LOW_RC_START, rc); -#endif - ((CFRuntimeBase *)cf)->_cfinfoa = info; -} - CFIndex CFGetRetainCount(CFTypeRef cf) { if (NULL == cf) { CRSetCrashLogMessage("*** CFGetRetainCount() called with NULL ***"); HALT; } - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - if (info & RC_CUSTOM_RC_BIT) { // custom ref counting for object - CFTypeID typeID = __CFTypeIDFromInfo(info); + 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 CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; uint32_t (*refcount)(intptr_t, CFTypeRef) = cfClass->refcount; - if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || __CFLowRCFromInfo(info) != 0xFF) { + if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || (((CFRuntimeBase *)cf)->_cfinfo[CF_RC_BITS] != 0xFF)) { HALT; // bogus object } #if __LP64__ - if (__CFHighRCFromInfo(info) != 0xFFFFFFFFU) { - CRSetCrashLogMessage("Detected bogus CFTypeRef"); + if (((CFRuntimeBase *)cf)->_rc != 0xFFFFFFFFU) { HALT; // bogus object } #endif @@ -829,8 +739,8 @@ Boolean _CFNonObjCEqual(CFTypeRef cf1, CFTypeRef cf2) { Boolean CFEqual(CFTypeRef cf1, CFTypeRef cf2) { if (NULL == cf1) { CRSetCrashLogMessage("*** CFEqual() called with NULL first argument ***"); HALT; } - if (cf1 == cf2) return true; 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); CFTYPE_SWIFT_FUNCDISPATCH1(Boolean, cf1, NSObject.isEqual, (CFSwiftRef)cf2); @@ -917,7 +827,7 @@ CF_PRIVATE void __CFTSDInitialize(void); // From CFPlatform.c CF_PRIVATE void __CFTSDWindowsInitialize(void); CF_PRIVATE void __CFTSDWindowsCleanup(void); -CF_PRIVATE void __CFFinalizeWindowsThreadData(void); +CF_PRIVATE void __CFFinalizeWindowsThreadData(); #endif extern void __CFStreamInitialize(void); #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS @@ -925,11 +835,11 @@ extern void __CFXPreferencesInitialize(void); #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -CF_PRIVATE _Atomic(uint8_t) __CF120290 = false; -CF_PRIVATE _Atomic(uint8_t) __CF120291 = false; -CF_PRIVATE _Atomic(uint8_t) __CF120293 = false; +CF_PRIVATE uint8_t __CF120290 = false; +CF_PRIVATE uint8_t __CF120291 = false; +CF_PRIVATE uint8_t __CF120293 = false; CF_PRIVATE char * __crashreporter_info__ = NULL; // Keep this symbol, since it was exported and other things may be linking against it, like GraphicsServices.framework on iOS -__asm(".desc ___crashreporter_info__, 0x10"); +asm(".desc ___crashreporter_info__, 0x10"); static void __01121__(void) { __CF120291 = pthread_is_threaded_np() ? true : false; @@ -1055,7 +965,6 @@ pthread_t _CF_pthread_main_thread_np(void) { #endif - #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD static void __CFInitialize(void) __attribute__ ((constructor)); static @@ -1264,7 +1173,6 @@ void __CFInitialize(void) { __CFProphylacticAutofsAccess = false; - __CFInitializing = 0; __CFInitialized = 1; } @@ -1348,6 +1256,26 @@ int DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID pReserved ) { #endif +#if __CF_BIG_ENDIAN__ +#define RC_INCREMENT (1ULL) +#define RC_MASK (0xFFFFFFFFULL) +#define RC_GET(V) ((V) & RC_MASK) +#define RC_DEALLOCATING_BIT (0x400000ULL << 32) +#define RC_DEALLOCATED_BIT (0x200000ULL << 32) +#else +#define RC_INCREMENT (1ULL << 32) +#define RC_MASK (0xFFFFFFFFULL << 32) +#define RC_GET(V) (((V) & RC_MASK) >> 32) +#define RC_DEALLOCATING_BIT (0x400000ULL) +#define RC_DEALLOCATED_BIT (0x200000ULL) +#endif + +#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; +#endif + #if DEPLOYMENT_RUNTIME_SWIFT extern void swift_retain(void *); extern void swift_release(void *); @@ -1360,80 +1288,78 @@ static CFTypeRef _CFRetain(CFTypeRef cf, Boolean tryR) { swift_retain((void *)cf); return cf; #else - // It's important to load a 64-bit value from cfinfo when running in 64 bit - if we only fetch 32 bits then it's possible we did not atomically fetch the deallocating/deallocated flag and the retain count together (19256102). Therefore it is after this load that we check the deallocating/deallocated flag and the const-ness. - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - if (info & RC_CUSTOM_RC_BIT) { + uint32_t cfinfo = *(uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + if (cfinfo & 0x800000) { // custom ref counting for object if (tryR) return NULL; - CFTypeID typeID = __CFTypeIDFromInfo(info); + CFTypeID typeID = (cfinfo >> 8) & 0x03FF; // mask up to 0x0FFF CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; uint32_t (*refcount)(intptr_t, CFTypeRef) = cfClass->refcount; - if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || __CFLowRCFromInfo(info) != 0xFF) { - CRSetCrashLogMessage("Detected bogus CFTypeRef"); + if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || (((CFRuntimeBase *)cf)->_cfinfo[CF_RC_BITS] != 0xFF)) { HALT; // bogus object } #if __LP64__ - // Custom RC always has high bits all set - if (__CFHighRCFromInfo(info) != 0xFFFFFFFFU) { - CRSetCrashLogMessage("Detected bogus CFTypeRef"); + if (((CFRuntimeBase *)cf)->_rc != 0xFFFFFFFFU) { HALT; // bogus object } #endif refcount(+1, cf); - } else { + return cf; + } + #if __LP64__ - __CFInfoType newInfo; - do { - if (__builtin_expect(tryR && (info & (RC_DEALLOCATING_BIT | RC_DEALLOCATED_BIT)), false)) { - // This object is marked for deallocation - return NULL; - } - - if (__CFHighRCFromInfo(info) == 0) { - // Constant CFTypeRef - return cf; - } - - if (__builtin_expect(__CFHighRCFromInfo(info) == ~0U, false)) { - // Overflow will occur upon add. Turn into constant CFTypeRef (rc == 0). Retain will do nothing, but neither will release. - __CFBitfield64SetValue(newInfo, HIGH_RC_END, HIGH_RC_START, 0); - } - - // Increment the retain count and swap into place - newInfo = info + RC_INCREMENT; - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); +#if !DEPLOYMENT_TARGET_WINDOWS + uint64_t allBits; + do { + // It's important to load a 64-bit value from cfinfo when running in 64 bit - if we use the 'cfinfo' from above then it's possible we did not atomically fetch the deallocating/deallocated flag and the retain count together (19256102). Therefore it is after this load that we check the deallocating/deallocated flag and the const-ness. + allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + if (tryR && (allBits & (RC_DEALLOCATING_BIT | RC_DEALLOCATED_BIT))) return NULL; // This object is marked for deallocation + if (RC_GET(allBits) == 0) return cf; // Constant CFTypeRef + } while (!CAS64(allBits, allBits + RC_INCREMENT, (int64_t *)&((CFRuntimeBase *)cf)->_cfinfo)); #else - CFIndex rc = __CFLowRCFromInfo(info); - if (__builtin_expect(0 == rc, 0)) return cf; // Constant CFTypeRef - bool success = 0; - do { - // if already deallocating, don't allow new retain - if (tryR && (info & RC_DEALLOCATING_BIT)) return NULL; - __CFInfoType newInfo = info; - newInfo += (1 << LOW_RC_START); - rc = __CFLowRCFromInfo(newInfo); - if (__builtin_expect((rc & 0x7f) == 0, 0)) { - /* Roll over another bit to the external ref count - Real ref count = low 7 bits of retain count in info + external ref count << 6 - Bit 8 of low bits indicates that external ref count is in use. - External ref count is shifted by 6 rather than 7 so that we can set the low - bits to to 1100 0000 rather than 1000 0000. - This prevents needing to access the external ref count for successive retains and releases - when the composite retain count is right around a multiple of 1 << 7. - */ - newInfo = info; - __CFBitfieldSetValue(newInfo, LOW_RC_END, LOW_RC_START, ((1 << 7) | (1 << 6))); - __CFLock(&__CFRuntimeExternRefCountTableLock); - success = atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo); - if (__builtin_expect(success, 1)) { - __CFDoExternRefOperation(350, (id)cf); - } - __CFUnlock(&__CFRuntimeExternRefCountTableLock); - } else { - success = atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo); + if (tryR && (cfinfo & (RC_DEALLOCATING_BIT | RC_DEALLOCATED_BIT))) return NULL; // deallocating or deallocated + uint32_t lowBits; + do { + lowBits = ((CFRuntimeBase *)cf)->_rc; + } while (!CAS32(lowBits, lowBits + 1, (int32_t *)&((CFRuntimeBase *)cf)->_rc)); +#endif +#else +#define RC_START 24 +#define RC_END 31 + CFIndex rcLowBits = __CFBitfieldGetValue(cfinfo, RC_END, RC_START); + if (__builtin_expect(0 == rcLowBits, 0)) return cf; // Constant CFTypeRef + volatile uint32_t *infoLocation = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + bool success = 0; + do { + cfinfo = *infoLocation; +#if !DEPLOYMENT_TARGET_WINDOWS + // if already deallocating, don't allow new retain + if (tryR && (cfinfo & 0x400000)) return NULL; +#endif + uint32_t prospectiveNewInfo = cfinfo; // don't want compiler to generate prospectiveNewInfo = *infoLocation. This is why infoLocation is declared as a pointer to volatile memory. + prospectiveNewInfo += (1 << RC_START); + rcLowBits = __CFBitfieldGetValue(prospectiveNewInfo, RC_END, RC_START); + if (__builtin_expect((rcLowBits & 0x7f) == 0, 0)) { + /* Roll over another bit to the external ref count + Real ref count = low 7 bits of info[CF_RC_BITS] + external ref count << 6 + Bit 8 of low bits indicates that external ref count is in use. + External ref count is shifted by 6 rather than 7 so that we can set the low + bits to to 1100 0000 rather than 1000 0000. + This prevents needing to access the external ref count for successive retains and releases + when the composite retain count is right around a multiple of 1 << 7. + */ + prospectiveNewInfo = cfinfo; + __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, ((1 << 7) | (1 << 6))); + __CFLock(&__CFRuntimeExternRefCountTableLock); + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + if (__builtin_expect(success, 1)) { + __CFDoExternRefOperation(350, (id)cf); } - } while (__builtin_expect(!success, 0)); + __CFUnlock(&__CFRuntimeExternRefCountTableLock); + } else { + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + } + } while (__builtin_expect(!success, 0)); #endif - } if (__builtin_expect(__CFOASafe, 0)) { __CFRecordAllocationEvent(__kCFRetainEvent, (void *)cf, 0, CFGetRetainCount(cf), NULL); } @@ -1457,11 +1383,11 @@ Boolean _CFIsDeallocating(CFTypeRef cf) { #if OBJC_HAVE_TAGGED_POINTERS if (_objc_isTaggedPointer(cf)) return false; #endif - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - if (info & RC_CUSTOM_RC_BIT) { - return true; // lie for now; weak references to these objects cannot be formed + 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 } - return (info & RC_DEALLOCATING_BIT) ? true : false; + return (cfinfo & RC_DEALLOCATING_BIT) ? true : false; } #endif @@ -1470,121 +1396,184 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { // We always call through to swift_release, since all CFTypeRefs are at least _NSCFType objects swift_release((void *)cf); #else - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - if (info & RC_DEALLOCATED_BIT) { + + uint32_t cfinfo = *(uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + if (cfinfo & RC_DEALLOCATED_BIT) { CRSetCrashLogMessage("Detected over-release of a CFTypeRef"); HALT; } - CFTypeID typeID = __CFTypeIDFromInfo(info); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wunused-variable" - CFIndex start_rc = __builtin_expect(__CFOASafe, 0) ? CFGetRetainCount(cf) : 0; -#pragma GCC diagnostic pop - Boolean isAllocator = (__kCFAllocatorTypeID_CONST == typeID); - - if (info & RC_CUSTOM_RC_BIT) { // custom ref counting for object + CFTypeID typeID = (cfinfo >> 8) & 0x03FF; // mask up to 0x0FFF + if (cfinfo & 0x800000) { // custom ref counting for object CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; uint32_t (*refcount)(intptr_t, CFTypeRef) = cfClass->refcount; - if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || __CFLowRCFromInfo(info) != 0xFF) { - CRSetCrashLogMessage("Detected bogus CFTypeRef"); + if (!refcount || !(cfClass->version & _kCFRuntimeCustomRefCount) || (((CFRuntimeBase *)cf)->_cfinfo[CF_RC_BITS] != 0xFF)) { HALT; // bogus object } #if __LP64__ - if (__CFHighRCFromInfo(info) != 0xFFFFFFFFU) { - CRSetCrashLogMessage("Detected bogus CFTypeRef"); + if (((CFRuntimeBase *)cf)->_rc != 0xFFFFFFFFU) { HALT; // bogus object } #endif refcount(-1, cf); - } else { + return; + } + + CFIndex start_rc = __builtin_expect(__CFOASafe, 0) ? CFGetRetainCount(cf) : 0; + Boolean isAllocator = (__kCFAllocatorTypeID_CONST == typeID); #if __LP64__ - uint32_t rc; - __CFInfoType newInfo; +#if !DEPLOYMENT_TARGET_WINDOWS + uint32_t lowBits; + uint64_t allBits; again:; - do { - rc = __CFHighRCFromInfo(info); - if (0 == rc) { - return; // Constant CFTypeRef + do { + allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + lowBits = RC_GET(allBits); + if (0 == lowBits) { + return; // Constant CFTypeRef + } + if (1 == lowBits) { + CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; + if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { + cfClass->reclaim(cf); } - if (1 == rc) { - CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; - if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { - cfClass->reclaim(cf); - } - newInfo = info | RC_DEALLOCATING_BIT; - if (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)) { - goto again; - } - void (*func)(CFTypeRef) = __CFRuntimeClassTable[typeID]->finalize; - if (NULL != func) { - func(cf); - } - // Any further ref-count changes after this point are operating on a finalized object - // Re-load in case the finalizer call changed the ref count (blech!) - info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - rc = __CFHighRCFromInfo(info); - if (isAllocator || (1 == rc)) { - do { - // hammer until it takes; trying to retain the object on another thread at this point? too late! - newInfo = (info | RC_DEALLOCATED_BIT) - RC_INCREMENT; - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); - goto really_free; - } - - // drop the deallocating bit; racey, but this resurrection stuff isn't thread-safe anyway - do { - info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - newInfo = info & ~RC_DEALLOCATING_BIT; - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); - goto again; // still need to have the effect of a CFRelease + uint64_t newAllBits = allBits | RC_DEALLOCATING_BIT; + if (!CAS64(allBits, newAllBits, (int64_t *)&((CFRuntimeBase *)cf)->_cfinfo)) { + goto again; + } + void (*func)(CFTypeRef) = __CFRuntimeClassTable[typeID]->finalize; + if (NULL != func) { + func(cf); + } + // Any further ref-count changes after this point are operating on a finalized object + allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + lowBits = RC_GET(allBits); + if (isAllocator || (1 == lowBits)) { + do { // hammer until it takes; trying to retain the object on another thread at this point? too late! + allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + } while (!CAS64(allBits, (allBits | RC_DEALLOCATED_BIT) - RC_INCREMENT, (int64_t *)&((CFRuntimeBase *)cf)->_cfinfo)); + goto really_free; + } + Boolean success = false; + do { // drop the deallocating bit; racey, but this resurrection stuff isn't thread-safe anyway + allBits = *(uint64_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + uint64_t newAllBits = allBits & ~RC_DEALLOCATING_BIT; + success = CAS64(allBits, newAllBits, (int64_t *)&((CFRuntimeBase *)cf)->_cfinfo); + } while (!success); + goto again; // still need to have the effect of a CFRelease + } + } while (!CAS64(allBits, allBits - RC_INCREMENT, (int64_t *)&((CFRuntimeBase *)cf)->_cfinfo)); +#else + uint32_t lowBits; + do { + lowBits = ((CFRuntimeBase *)cf)->_rc; + if (0 == lowBits) { + return; // Constant CFTypeRef + } + if (1 == lowBits) { + // CANNOT WRITE ANY NEW VALUE INTO [CF_RC_BITS] UNTIL AFTER FINALIZATION + CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; + if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { + cfClass->reclaim(cf); } - newInfo = info - RC_INCREMENT; - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); + void (*func)(CFTypeRef) = __CFRuntimeClassTable[typeID]->finalize; + if (NULL != func) { + func(cf); + } + if (isAllocator || CAS32(1, 0, (int32_t *)&((CFRuntimeBase *)cf)->_rc)) { + goto really_free; + } + } + } while (!CAS32(lowBits, lowBits - 1, (int32_t *)&((CFRuntimeBase *)cf)->_rc)); +#endif #else +#if !DEPLOYMENT_TARGET_WINDOWS again:; - CFIndex rc = __CFLowRCFromInfo(info); - if (0 == rc) { - return; // Constant CFTypeRef - } - bool success = 0; - Boolean whack = false; - do { - rc = __CFLowRCFromInfo(info); - if (1 == rc) { - // we think cf should be deallocated - __CFInfoType newInfo = info | RC_DEALLOCATING_BIT; - success = atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo); - if (success) whack = true; - } else { - // not yet junk - __CFInfoType newInfo = info; - if (rc == (1 << 7)) { - // Time to remove a bit from the external ref count - __CFLock(&__CFRuntimeExternRefCountTableLock); - CFIndex rcHighBitsCnt = __CFDoExternRefOperation(500, (id)cf); - if (1 == rcHighBitsCnt) { - __CFBitfieldSetValue(newInfo, LOW_RC_END, LOW_RC_START, (1 << 6) - 1); - } else { - __CFBitfieldSetValue(newInfo, LOW_RC_END, LOW_RC_START, ((1 << 6) | (1 << 7)) - 1); - } - success = atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo); - if (success) { - __CFDoExternRefOperation(450, (id)cf); - } - __CFUnlock(&__CFRuntimeExternRefCountTableLock); + volatile uint32_t *infoLocation = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + CFIndex rcLowBits = __CFBitfieldGetValue(cfinfo, RC_END, RC_START); + if (0 == rcLowBits) { + return; // Constant CFTypeRef + } + bool success = 0; + Boolean whack = false; + do { + cfinfo = *infoLocation; + rcLowBits = __CFBitfieldGetValue(cfinfo, RC_END, RC_START); + if (1 == rcLowBits) { + // we think cf should be deallocated + uint32_t prospectiveNewInfo = cfinfo | (RC_DEALLOCATING_BIT); + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + if (success) whack = true; + } else { + // not yet junk + uint32_t prospectiveNewInfo = cfinfo; // don't want compiler to generate prospectiveNewInfo = *infoLocation. This is why infoLocation is declared as a pointer to volatile memory. + if ((1 << 7) == rcLowBits) { + // Time to remove a bit from the external ref count + __CFLock(&__CFRuntimeExternRefCountTableLock); + CFIndex rcHighBitsCnt = __CFDoExternRefOperation(500, (id)cf); + if (1 == rcHighBitsCnt) { + __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, (1 << 6) - 1); } else { - newInfo -= (1 << LOW_RC_START); - success = atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo); + __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, ((1 << 6) | (1 << 7)) - 1); + } + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + if (success) { + __CFDoExternRefOperation(450, (id)cf); } + __CFUnlock(&__CFRuntimeExternRefCountTableLock); + } else { + prospectiveNewInfo -= (1 << RC_START); + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); } - } while (!success); - - if (whack) { - CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; - if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { - cfClass->reclaim(cf); + } + } while (!success); + + if (whack) { + CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; + if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { + cfClass->reclaim(cf); + } + + if (isAllocator) { + goto really_free; + } else { + void (*func)(CFTypeRef) = __CFRuntimeClassTable[typeID]->finalize; + if (NULL != func) { + func(cf); + } + // Any further ref-count changes after this point are operating on a finalized object + rcLowBits = __CFBitfieldGetValue(*infoLocation, RC_END, RC_START); + if (1 == rcLowBits) { + do { // hammer until it takes; trying to retain the object on another thread at this point? too late! + cfinfo = *infoLocation; + } while (!CAS32(cfinfo, cfinfo | RC_DEALLOCATED_BIT, (int32_t *)infoLocation)); + goto really_free; } - + do { // drop the deallocating bit; racey, but this resurrection stuff isn't thread-safe anyway + cfinfo = *infoLocation; + uint32_t prospectiveNewInfo = (cfinfo & ~(RC_DEALLOCATING_BIT)); + success = CAS32(*(int32_t *)& cfinfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + } while (!success); + goto again; + } + } +#else + volatile uint32_t *infoLocation = (uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + CFIndex rcLowBits = __CFBitfieldGetValue(*infoLocation, RC_END, RC_START); + if (0 == rcLowBits) { + return; // Constant CFTypeRef + } + bool success = 0; + do { + uint32_t initialCheckInfo = *infoLocation; + rcLowBits = __CFBitfieldGetValue(initialCheckInfo, RC_END, RC_START); + if (1 == rcLowBits) { + // we think cf should be deallocated + // CANNOT WRITE ANY NEW VALUE INTO [CF_RC_BITS] UNTIL AFTER FINALIZATION + CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; + if ((cfClass->version & _kCFRuntimeResourcefulObject) && cfClass->reclaim != NULL) { + cfClass->reclaim(cf); + } + if (isAllocator) { goto really_free; } else { @@ -1592,27 +1581,43 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { if (NULL != func) { func(cf); } - // Any further ref-count changes after this point are operating on a finalized object - info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - __CFInfoType newInfo; - rc = __CFLowRCFromInfo(info); - if (1 == rc) { - do { - // hammer until it takes; trying to retain the object on another thread at this point? too late! - newInfo = info | RC_DEALLOCATED_BIT; - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); + // We recheck rcLowBits to see if the object has been retained again during + // the finalization process. This allows for the finalizer to resurrect, + // but the main point is to allow finalizers to be able to manage the + // removal of objects from uniquing caches, which may race with other threads + // which are allocating (looking up and finding) objects from those caches, + // which (that thread) would be the thing doing the extra retain in that case. + rcLowBits = __CFBitfieldGetValue(*infoLocation, RC_END, RC_START); + success = (1 == rcLowBits); + if (success) { goto really_free; } - - // drop the deallocating bit; racey, but this resurrection stuff isn't thread-safe anyway - do { - newInfo = info & ~(RC_DEALLOCATING_BIT); - } while (!atomic_compare_exchange_strong(&(((CFRuntimeBase *)cf)->_cfinfoa), &info, newInfo)); - goto again; + } + } else { + // not yet junk + uint32_t prospectiveNewInfo = initialCheckInfo; // don't want compiler to generate prospectiveNewInfo = *infoLocation. This is why infoLocation is declared as a pointer to volatile memory. + if ((1 << 7) == rcLowBits) { + // Time to remove a bit from the external ref count + __CFLock(&__CFRuntimeExternRefCountTableLock); + CFIndex rcHighBitsCnt = __CFDoExternRefOperation(500, (id)cf); + if (1 == rcHighBitsCnt) { + __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, (1 << 6) - 1); + } else { + __CFBitfieldSetValue(prospectiveNewInfo, RC_END, RC_START, ((1 << 6) | (1 << 7)) - 1); + } + success = CAS32(*(int32_t *)&initialCheckInfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); + if (success) { + __CFDoExternRefOperation(450, (id)cf); + } + __CFUnlock(&__CFRuntimeExternRefCountTableLock); + } else { + prospectiveNewInfo -= (1 << RC_START); + success = CAS32(*(int32_t *)&initialCheckInfo, *(int32_t *)&prospectiveNewInfo, (int32_t *)infoLocation); } } + } while (!success); +#endif #endif - } if (__builtin_expect(__CFOASafe, 0)) { __CFRecordAllocationEvent(__kCFReleaseEvent, (void *)cf, 0, start_rc - 1, NULL); } @@ -1630,7 +1635,7 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { CFAllocatorRef allocator = kCFAllocatorSystemDefault; Boolean usesSystemDefaultAllocator = true; - if (!__CFRuntimeGetFlag(cf, 7)) { + if (!__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7)) { allocator = CFGetAllocator(cf); usesSystemDefaultAllocator = _CFAllocatorIsSystemDefault(allocator); } @@ -1647,14 +1652,13 @@ static void _CFRelease(CFTypeRef CF_RELEASES_ARGUMENT cf) { #endif } - #if DEPLOYMENT_RUNTIME_SWIFT struct _CFSwiftBridge __CFSwiftBridge = { { NULL } }; // Call out to the CF-level finalizer, because the object is going to go away. CF_SWIFT_EXPORT void _CFDeinit(CFTypeRef cf) { - __CFInfoType info = atomic_load(&(((CFRuntimeBase *)cf)->_cfinfoa)); - CFTypeID typeID = __CFTypeIDFromInfo(info); + uint32_t cfinfo = *(uint32_t *)&(((CFRuntimeBase *)cf)->_cfinfo); + CFTypeID typeID = (cfinfo >> 8) & 0x03FF; // mask up to 0x0FFF CFRuntimeClass *cfClass = __CFRuntimeClassTable[typeID]; void (*func)(CFTypeRef) = __CFRuntimeClassTable[typeID]->finalize; if (NULL != func) { @@ -1694,7 +1698,7 @@ const char *_NSPrintForDebugger(void *cf) { return result; } } - + CFHashCode __CFHashDouble(double d) { return _CFHashDouble(d); } diff --git a/CoreFoundation/Base.subproj/CFRuntime.h b/CoreFoundation/Base.subproj/CFRuntime.h index d7aa26cfc9..b7b5f1cab8 100644 --- a/CoreFoundation/Base.subproj/CFRuntime.h +++ b/CoreFoundation/Base.subproj/CFRuntime.h @@ -1,7 +1,7 @@ /* CFRuntime.h - Copyright (c) 1999-2017, Apple Inc. All rights reserved. + Copyright (c) 1999-2016, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -196,26 +196,30 @@ typedef struct __CFRuntimeBase { uint32_t _swift_strong_rc; uint32_t _swift_weak_rc; // This is for CF's use, and must match _NSCFType layout - _Atomic(uint64_t) _cfinfoa; + uint8_t _cfinfo[4]; + uint8_t _pad[4]; } CFRuntimeBase; -#define INIT_CFRUNTIME_BASE(...) {0, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x0000000000000080ULL} +#if __BIG_ENDIAN__ +#define INIT_CFRUNTIME_BASE(...) {0, _CF_CONSTANT_OBJECT_STRONG_RC, 0, {0, 0, 0, 0x80}, {0, 0, 0, 0}} +#else +#define INIT_CFRUNTIME_BASE(...) {0, _CF_CONSTANT_OBJECT_STRONG_RC, 0, {0x80, 0, 0, 0}, {0, 0, 0, 0}} +#endif #else typedef struct __CFRuntimeBase { uintptr_t _cfisa; + uint8_t _cfinfo[4]; #if __LP64__ - _Atomic(uint64_t) _cfinfoa; -#else - _Atomic(uint32_t) _cfinfoa; + uint32_t _rc; #endif } CFRuntimeBase; -#if __LP64__ -#define INIT_CFRUNTIME_BASE(...) {0, 0x0000000000000080ULL} +#if __BIG_ENDIAN__ +#define INIT_CFRUNTIME_BASE(...) {0, {0, 0, 0, 0x80}} #else -#define INIT_CFRUNTIME_BASE(...) {0, 0x00000080UL} +#define INIT_CFRUNTIME_BASE(...) {0, {0x80, 0, 0, 0}} #endif #endif diff --git a/CoreFoundation/Base.subproj/CFSortFunctions.c b/CoreFoundation/Base.subproj/CFSortFunctions.c index 05bd43ef91..172860a6c4 100644 --- a/CoreFoundation/Base.subproj/CFSortFunctions.c +++ b/CoreFoundation/Base.subproj/CFSortFunctions.c @@ -1,7 +1,7 @@ /* CFSortFunctions.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -14,8 +14,6 @@ #include #if (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED) && __has_include() #include -#else -#define DISPATCH_APPLY_CURRENT_ROOT_QUEUE ((dispatch_queue_t _Nonnull)0) #endif #endif #include "CFLogUtilities.h" @@ -50,8 +48,10 @@ enum { #define __check_int64_div(x, y, err) (x / y) #define __check_uint64_div(x, y, err) (x / y) -#define __checkint_int64_mul(x, y, err) (x * y) -#define __checkint_uint64_add(x, y, err) (x + y) +#define __checkint_int64_mul(x, y, err) __check_int64_mul(x, y, err) +#define __checkint_int32_mul(x, y, err) __check_int32_mul(x, y, err) +#define __checkint_uint64_add(x, y, err) __check_uint64_add(x, y, err) +#define __checkint_uint32_add(x, y, err) __check_uint32_add(x, y, err) #endif @@ -232,7 +232,8 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore } VALUE_TYPE **tmps = stack_tmps; - dispatch_apply(num_sect, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { + dispatch_queue_t q = __CFDispatchQueueGetGenericMatchingCurrent(); + dispatch_apply(num_sect, q, ^(size_t sect) { INDEX_TYPE sect_len = (sect < num_sect - 1) ? sz : last_sect_len; __CFSimpleMergeSort(listp + sect * sz, sect_len, tmps[sect], cmp); // naturally stable }); @@ -240,7 +241,7 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore INDEX_TYPE even_phase_cnt = ((num_sect / 2) * 2); INDEX_TYPE odd_phase_cnt = (((num_sect - 1) / 2) * 2); for (INDEX_TYPE idx = 0; idx < (num_sect + 1) / 2; idx++) { - dispatch_apply(even_phase_cnt, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { // merge even + dispatch_apply(even_phase_cnt, q, ^(size_t sect) { // merge even size_t right = sect & (size_t)0x1; VALUE_TYPE *left_base = listp + sect * sz - (right ? sz : 0); VALUE_TYPE *right_base = listp + sect * sz + (right ? 0 : sz); @@ -250,7 +251,7 @@ static void __CFSortIndexesN(VALUE_TYPE listp[], INDEX_TYPE count, int32_t ncore if (num_sect & 0x1) { memmove(tmps[num_sect - 1], listp + (num_sect - 1) * sz, last_sect_len * sizeof(VALUE_TYPE)); } - dispatch_apply(odd_phase_cnt, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t sect) { // merge odd + dispatch_apply(odd_phase_cnt, q, ^(size_t sect) { // merge odd size_t right = sect & (size_t)0x1; VALUE_TYPE *left_base = tmps[sect + (right ? 0 : 1)]; VALUE_TYPE *right_base = tmps[sect + (right ? 1 : 2)]; @@ -294,13 +295,11 @@ void CFSortIndexes(CFIndex *indexBuffer, CFIndex count, CFOptionFlags opts, CFCo for (CFIndex idx = 0; idx < count; idx++) indexBuffer[idx] = idx; } else { /* Specifically hard-coded to 8; the count has to be very large before more chunks and/or cores is worthwhile. */ - dispatch_queue_t q = dispatch_queue_create(__CF_QUEUE_NAME("NSSortIndexes"), DISPATCH_QUEUE_CONCURRENT); CFIndex sz = ((((size_t)count + 15) / 16) * 16) / 8; - dispatch_apply(8, DISPATCH_APPLY_CURRENT_ROOT_QUEUE, ^(size_t n) { + dispatch_apply(8, __CFDispatchQueueGetGenericMatchingCurrent(), ^(size_t n) { CFIndex idx = n * sz, lim = __CFMin(idx + sz, count); for (; idx < lim; idx++) indexBuffer[idx] = idx; }); - dispatch_release(q); } #else for (CFIndex idx = 0; idx < count; idx++) indexBuffer[idx] = idx; diff --git a/CoreFoundation/Base.subproj/CFSystemDirectories.c b/CoreFoundation/Base.subproj/CFSystemDirectories.c index c3d6a4dbf2..867f7b571d 100644 --- a/CoreFoundation/Base.subproj/CFSystemDirectories.c +++ b/CoreFoundation/Base.subproj/CFSystemDirectories.c @@ -1,7 +1,7 @@ /* CFSystemDirectories.c - Copyright (c) 1997-2017, Apple Inc. and the Swift project authors + Copyright (c) 1997-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFUUID.c b/CoreFoundation/Base.subproj/CFUUID.c index c302c6e1a2..9fdd9220e2 100644 --- a/CoreFoundation/Base.subproj/CFUUID.c +++ b/CoreFoundation/Base.subproj/CFUUID.c @@ -1,7 +1,7 @@ /* CFUUID.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFUUID.h b/CoreFoundation/Base.subproj/CFUUID.h index f951bb4e12..6f7d7201f0 100644 --- a/CoreFoundation/Base.subproj/CFUUID.h +++ b/CoreFoundation/Base.subproj/CFUUID.h @@ -1,7 +1,7 @@ /* CFUUID.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CFUtilities.c b/CoreFoundation/Base.subproj/CFUtilities.c index 03f7b8c3b1..aa40131b7d 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.c +++ b/CoreFoundation/Base.subproj/CFUtilities.c @@ -1,7 +1,7 @@ /* CFUtilities.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -195,17 +195,6 @@ CF_PRIVATE CFDataRef _CFDataCreateFromURL(CFURLRef resourceURL, CFErrorRef *erro return result; } -static CFStringRef copySystemVersionPath(CFStringRef suffix) { -#if TARGET_IPHONE_SIMULATOR - const char *simulatorRoot = getenv("IPHONE_SIMULATOR_ROOT"); - if (!simulatorRoot) simulatorRoot = getenv("CFFIXED_USER_HOME"); - if (!simulatorRoot) simulatorRoot = "/"; - return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%s%@"), simulatorRoot, suffix); -#else - return CFStringCreateCopy(kCFAllocatorSystemDefault, suffix); -#endif -} - // Looks for localized version of "nonLocalized" in the SystemVersion bundle // If not found, and returnNonLocalizedFlag == true, will return the non localized string (retained of course), otherwise NULL // If bundlePtr != NULL, will use *bundlePtr and will return the bundle in there; otherwise bundle is created and released @@ -214,9 +203,7 @@ static CFStringRef _CFCopyLocalizedVersionKey(CFBundleRef *bundlePtr, CFStringRe CFStringRef localized = NULL; CFBundleRef locBundle = bundlePtr ? *bundlePtr : NULL; if (!locBundle) { - CFStringRef path = copySystemVersionPath(CFSTR("/System/Library/CoreServices/SystemVersion.bundle")); - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, path, kCFURLPOSIXPathStyle, false); - CFRelease(path); + CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR("/System/Library/CoreServices/SystemVersion.bundle"), kCFURLPOSIXPathStyle, false); if (url) { locBundle = CFBundleCreate(kCFAllocatorSystemDefault, url); CFRelease(url); @@ -318,37 +305,37 @@ CFStringRef CFCopySystemVersionString(void) { return versionString; } +// Obsolete: These two functions cache the dictionaries to avoid calling _CFCopyVersionDictionary() more than once per dict desired +// In fact, they do not cache any more, because the file can change after +// apps are running in some situations, and apps need the new info. +// Proper caching and testing to see if the file has changed, without race +// conditions, would require semi-convoluted use of fstat(). + +static CFStringRef copySystemVersionPath(CFStringRef suffix) { +#if TARGET_IPHONE_SIMULATOR + const char *simulatorRoot = getenv("IPHONE_SIMULATOR_ROOT"); + if (!simulatorRoot) simulatorRoot = getenv("CFFIXED_USER_HOME"); + if (!simulatorRoot) simulatorRoot = "/"; + return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%s%@"), simulatorRoot, suffix); +#else + return CFStringCreateCopy(kCFAllocatorSystemDefault, suffix); +#endif +} + + CFDictionaryRef _CFCopySystemVersionDictionary(void) { - static dispatch_once_t onceToken; - static CFDictionaryRef result = NULL; - dispatch_once(&onceToken, ^{ - // TODO: Populate this dictionary differently on non-Darwin platforms - CFStringRef path = copySystemVersionPath(CFSTR("/System/Library/CoreServices/SystemVersion.plist")); - CFPropertyListRef plist = _CFCopyVersionDictionary(path); - CFRelease(path); - result = (CFDictionaryRef)plist; - }); - if (result) { - return CFRetain(result); - } else { - return NULL; - } + // TODO: Populate this dictionary differently on non-Darwin platforms + CFStringRef path = copySystemVersionPath(CFSTR("/System/Library/CoreServices/SystemVersion.plist")); + CFPropertyListRef plist = _CFCopyVersionDictionary(path); + CFRelease(path); + return (CFDictionaryRef)plist; } CFDictionaryRef _CFCopyServerVersionDictionary(void) { - static dispatch_once_t onceToken; - static CFDictionaryRef result = NULL; - dispatch_once(&onceToken, ^{ - CFStringRef path = copySystemVersionPath(CFSTR("/System/Library/CoreServices/ServerVersion.plist")); - CFPropertyListRef plist = _CFCopyVersionDictionary(path); - CFRelease(path); - result = (CFDictionaryRef)plist; - }); - if (result) { - return CFRetain(result); - } else { - return NULL; - } + CFStringRef path = copySystemVersionPath(CFSTR("/System/Library/CoreServices/ServerVersion.plist")); + CFPropertyListRef plist = _CFCopyVersionDictionary(path); + CFRelease(path); + return (CFDictionaryRef)plist; } CONST_STRING_DECL(_kCFSystemVersionProductNameKey, "ProductName") @@ -483,97 +470,19 @@ CF_PRIVATE uint64_t __CFMemorySize() { return memsize; } -#if TARGET_OS_MAC -static uid_t _CFGetSVUID(BOOL *successful) { - uid_t uid = -1; - struct kinfo_proc kinfo; - u_int miblen = 4; - size_t len; - int mib[miblen]; - int ret; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - len = sizeof(struct kinfo_proc); - ret = sysctl(mib, miblen, &kinfo, &len, NULL, 0); - if (ret != 0) { - uid = -1; - *successful = NO; - } else { - uid = kinfo.kp_eproc.e_pcred.p_svuid; - *successful = YES; - } - return uid; -} -#endif - -CF_INLINE BOOL _CFCanChangeEUIDs(void) { -#if TARGET_OS_MAC - static BOOL canChangeEUIDs; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - uid_t euid = geteuid(); - uid_t uid = getuid(); - BOOL gotSVUID = NO; - uid_t svuid = _CFGetSVUID(&gotSVUID); - canChangeEUIDs = (uid == 0 || uid != euid || svuid != euid || !gotSVUID); - }); - return canChangeEUIDs; -#else - return true; -#endif -} - -typedef struct _ugids { - uid_t _euid; - uid_t _egid; -} ugids; - CF_PRIVATE void __CFGetUGIDs(uid_t *euid, gid_t *egid) { - ugids(^lookup)() = ^{ - ugids ids; #if 1 && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI) - if (0 != pthread_getugid_np(&ids._euid, &ids._egid)) + uid_t uid; + gid_t gid; + if (0 == pthread_getugid_np(&uid, &gid)) { + if (euid) *euid = uid; + if (egid) *egid = gid; + } else #endif - { - ids._euid = geteuid(); - ids._egid = getegid(); - } - return ids; - }; - - ugids ids; - - if (_CFCanChangeEUIDs()) { - ids = lookup(); - } else { - static ugids cachedUGIDs = { -1, -1 }; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - cachedUGIDs = lookup(); - }); - ids = cachedUGIDs; + { + if (euid) *euid = geteuid(); + if (egid) *egid = getegid(); } - - if (euid) *euid = ids._euid; - if (egid) *egid = ids._egid; -} - -CF_EXPORT void _CFGetUGIDs(uid_t *euid, gid_t *egid) { - __CFGetUGIDs(euid, egid); -} - -CF_EXPORT uid_t _CFGetEUID(void) { - uid_t euid; - __CFGetUGIDs(&euid, NULL); - return euid; -} - -CF_EXPORT uid_t _CFGetEGID(void) { - uid_t egid; - __CFGetUGIDs(NULL, &egid); - return egid; } const char *_CFPrintForDebugger(const void *obj) { @@ -1069,39 +978,39 @@ kern_return_t _CFDiscorporateMemoryMaterialize(CFDiscorporateMemory *hm) { #if SUDDEN_TERMINATION_ENABLE_VPROC -static os_unfair_lock __CFProcessKillingLock = OS_UNFAIR_LOCK_INIT; +static OSSpinLock __CFProcessKillingLock = OS_SPINLOCK_INIT; static CFIndex __CFProcessKillingDisablingCount = 1; static Boolean __CFProcessKillingWasTurnedOn = false; void _CFSuddenTerminationDisable(void) { - os_unfair_lock_lock(&__CFProcessKillingLock); + OSSpinLockLock(&__CFProcessKillingLock); __CFProcessKillingDisablingCount++; - os_unfair_lock_unlock(&__CFProcessKillingLock); + OSSpinLockUnlock(&__CFProcessKillingLock); } void _CFSuddenTerminationEnable(void) { // In our model the first call of _CFSuddenTerminationEnable() that does not balance a previous call of _CFSuddenTerminationDisable() actually enables sudden termination so we have to keep a count that's almost redundant with vproc's. - os_unfair_lock_lock(&__CFProcessKillingLock); + OSSpinLockLock(&__CFProcessKillingLock); __CFProcessKillingDisablingCount--; if (__CFProcessKillingDisablingCount==0 && !__CFProcessKillingWasTurnedOn) { __CFProcessKillingWasTurnedOn = true; } else { } - os_unfair_lock_unlock(&__CFProcessKillingLock); + OSSpinLockUnlock(&__CFProcessKillingLock); } void _CFSuddenTerminationExitIfTerminationEnabled(int exitStatus) { // This is for when the caller wants to try to exit quickly if possible but not automatically exit the process when it next becomes clean, because quitting might still be cancelled by the user. - os_unfair_lock_lock(&__CFProcessKillingLock); - os_unfair_lock_unlock(&__CFProcessKillingLock); + OSSpinLockLock(&__CFProcessKillingLock); + OSSpinLockUnlock(&__CFProcessKillingLock); } void _CFSuddenTerminationExitWhenTerminationEnabled(int exitStatus) { // The user has had their final opportunity to cancel quitting. Exit as soon as the process is clean. Same carefulness as in _CFSuddenTerminationExitIfTerminationEnabled(). - os_unfair_lock_lock(&__CFProcessKillingLock); + OSSpinLockLock(&__CFProcessKillingLock); if (__CFProcessKillingWasTurnedOn) { } - os_unfair_lock_unlock(&__CFProcessKillingLock); + OSSpinLockUnlock(&__CFProcessKillingLock); } size_t _CFSuddenTerminationDisablingCount(void) { @@ -1110,11 +1019,134 @@ size_t _CFSuddenTerminationDisablingCount(void) { #else -//The non-vproc implementation is present in the commit history, but long ago began failing to compile and nobody noticed. If you need to resurrect it, start there. -#error Building with vproc sudden termination API disabled. +#warning Building with vproc sudden termination API disabled. + +static OSSpinLockUnlock __CFProcessKillingLock = OS_SPINLOCK_INIT; +static size_t __CFProcessKillingDisablingCount = 1; +static Boolean __CFProcessExitNextTimeKillingIsEnabled = false; +static int32_t __CFProcessExitStatus = 0; +static int __CFProcessIsKillableNotifyToken; +static Boolean __CFProcessIsKillableNotifyTokenIsFigured = false; + +CF_PRIVATE void _CFSetSuddenTerminationEnabled(Boolean isEnabled) { + if (!__CFProcessIsKillableNotifyTokenIsFigured) { + char *notificationName = NULL; + asprintf(¬ificationName, "com.apple.isKillable.%i", getpid()); + uint32_t notifyResult = notify_register_check(notificationName, &__CFProcessIsKillableNotifyToken); + if (notifyResult != NOTIFY_STATUS_OK) { + CFLog(kCFLogLevelError, CFSTR("%s: notify_register_check() returned %i."), __PRETTY_FUNCTION__, notifyResult); + } + free(notificationName); + __CFProcessIsKillableNotifyTokenIsFigured = true; + } + uint32_t notifyResult = notify_set_state(__CFProcessIsKillableNotifyToken, isEnabled); + if (notifyResult != NOTIFY_STATUS_OK) { + CFLog(kCFLogLevelError, CFSTR("%s: notify_set_state() returned %i"), __PRETTY_FUNCTION__, notifyResult); + } +} + +void _CFSuddenTerminationDisable(void) { + OSSpinLockLock(&__CFProcessKillingLock); + if (__CFProcessKillingDisablingCount == 0) { + _CFSetSuddenTerminationEnabled(false); + } + __CFProcessKillingDisablingCount++; + OSSpinLockUnlock(&__CFProcessKillingLock); +} + +void _CFSuddenTerminationEnable(void) { + OSSpinLockLock(&__CFProcessKillingLock); + __CFProcessKillingDisablingCount--; + if (__CFProcessKillingDisablingCount == 0) { + if (__CFProcessExitNextTimeKillingIsEnabled) { + _exit(__CFProcessExitStatus); + } else { + _CFSetSuddenTerminationEnabled(true); + } + } + OSSpinLockUnlock(&__CFProcessKillingLock); +} + +void _CFSuddenTerminationExitIfTerminationEnabled(int exitStatus) { + OSSpinLockLock(&__CFProcessKillingLock); + if (__CFProcessKillingDisablingCount == 0) { + _exit(exitStatus); + } + OSSpinLockUnlock(&__CFProcessKillingLock); +} + +void _CFSuddenTerminationExitWhenTerminationEnabled(int exitStatus) { + OSSpinLockLock(&__CFProcessKillingLock); + if (__CFProcessKillingDisablingCount == 0) { + _exit(exitStatus); + } else { + __CFProcessExitNextTimeKillingIsEnabled = YES; + __CFProcessExitStatus = exitStatus; + } + OSSpinLockUnlock(&__CFProcessKillingLock); +} + +size_t _CFSuddenTerminationDisablingCount(void) { + return __CFProcessKillingDisablingCount; +} + +#endif #endif +#if 0 +#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 + +CF_PRIVATE ThrottleTypeA __CFCreateThrottleTypeA(uint16_t calls, uint64_t nanoseconds) { + struct mach_timebase_info info; + mach_timebase_info(&info); + uint64_t period = nanoseconds / info.numer * info.denom; + + if (0 == calls || 0 == period) return NULL; + + __block OSSpinLock b_lock = OS_SPINLOCK_INIT; + __block uint64_t b_values[calls]; + __block uint64_t *b_oldest = b_values; + memset(b_values, 0, sizeof(b_values)); + + return Block_copy(^{ + uint64_t curr_time = mach_absolute_time(); + OSSpinLockLock(&b_lock); + uint64_t next_time = *b_oldest + period; + *b_oldest = (curr_time < next_time) ? next_time : curr_time; + b_oldest++; + if (b_values + calls <= b_oldest) b_oldest = b_values; + OSSpinLockUnlock(&b_lock); + if (curr_time < next_time) { + mach_wait_until(next_time); + } + }); +} + +CF_PRIVATE ThrottleTypeB __CFCreateThrottleTypeB(uint64_t amount, uint64_t nanoseconds) { + struct mach_timebase_info info; + mach_timebase_info(&info); + uint64_t period = nanoseconds / info.numer * info.denom; + + if (0 == amount || 0 == period) return NULL; + + __block OSSpinLock b_lock = OS_SPINLOCK_INIT; + __block uint64_t b_sum = 0ULL; + __block uint16_t b_num_values = 8; + __block uint64_t *b_values = calloc(b_num_values, 2 * sizeof(uint64_t)); + __block uint64_t *b_oldest = b_values; + + return Block_copy(^(uint64_t amt){ + OSSpinLockLock(&b_lock); +// unimplemented + OSSpinLockUnlock(&b_lock); + }); +} + +#endif #endif #pragma mark File Reading @@ -1416,11 +1448,9 @@ CF_INLINE Boolean __ExtensionIsValidToAppend(CFStringInlineBuffer *buffer) { // Look backwards for a period. If a period is found, it must not be the // last character and any characters after the period must be valid in an // extension, and all characters before the period are considered valid - // except for the path separator character '/' (this allow strings like - // "tar.gz" to be appended as an extension). The path separator - // character '/' isn't allowed anywhere in the extension. If there's no - // period, the entire string must be characters valid in an extension. - // The extension may be of any length. + // (this allow strings like "tar.gz" to be appended as an extension). + // If there's no period, the entire string must be characters valid in an + // extension. The extension may be of any length. CFIndex nameLen = buffer->rangeToBuffer.length; if ( nameLen ) { @@ -1431,16 +1461,6 @@ CF_INLINE Boolean __ExtensionIsValidToAppend(CFStringInlineBuffer *buffer) { if ( (UniChar)'.' == c ) { // Found a period. If it's the last character, then return false; otherwise true result = i < nameLen - 1; - if ( result ) { - // check the rest of the string before the period for '/' - for ( CFIndex j = i - 1; j >= 0; j-- ) { - c = __CFStringGetCharacterFromInlineBufferQuickReverse(buffer, j); - if ( c == (UniChar)'/'){ - result = false; - break; - } - } - } break; } else if ( __IsInvalidExtensionCharacter(c) ) { diff --git a/CoreFoundation/Base.subproj/CFUtilities.h b/CoreFoundation/Base.subproj/CFUtilities.h index 6429fdcf45..623c86adee 100644 --- a/CoreFoundation/Base.subproj/CFUtilities.h +++ b/CoreFoundation/Base.subproj/CFUtilities.h @@ -1,7 +1,7 @@ /* CFUtilities.h - Copyright (c) 2005-2017, Apple Inc. and the Swift project authors + Copyright (c) 2005-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -18,7 +18,7 @@ CF_IMPLICIT_BRIDGING_ENABLED CF_EXTERN_C_BEGIN CF_EXPORT -CFURLRef CFCopyHomeDirectoryURL(void) API_AVAILABLE(ios(5.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); +CFURLRef CFCopyHomeDirectoryURL(void) CF_AVAILABLE_IOS(5_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Base.subproj/CFWindowsUtilities.c b/CoreFoundation/Base.subproj/CFWindowsUtilities.c index 83872c349b..9f4c0c6c43 100644 --- a/CoreFoundation/Base.subproj/CFWindowsUtilities.c +++ b/CoreFoundation/Base.subproj/CFWindowsUtilities.c @@ -1,8 +1,8 @@ /* CFWindowsUtilities.c - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CoreFoundation.h b/CoreFoundation/Base.subproj/CoreFoundation.h index 2b71481b1e..4e36d8ad32 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation.h +++ b/CoreFoundation/Base.subproj/CoreFoundation.h @@ -1,7 +1,7 @@ /* CoreFoundation.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h index 66d43b1358..5f151955c8 100644 --- a/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h +++ b/CoreFoundation/Base.subproj/CoreFoundation_Prefix.h @@ -1,7 +1,7 @@ /* CoreFoundation_Prefix.h - Copyright (c) 2005-2017, Apple Inc. and the Swift project authors + Copyright (c) 2005-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -111,7 +111,7 @@ static dispatch_queue_t __ ## PREFIX ## Queue(void) { \ // hint to the analyzer that the caller is no longer responsable for the object and that it will be transfered to the reciver that is opaque to the caller #if __clang_analyzer__ -#define CF_TRANSFER_OWNERSHIP(obj) (__typeof(obj))[(id)obj autorelease] +#define CF_TRANSFER_OWNERSHIP(obj) (typeof(obj))[(id)obj autorelease] #else #define CF_TRANSFER_OWNERSHIP(obj) obj #endif @@ -212,13 +212,6 @@ bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, volati void OSMemoryBarrier(); -#if TARGET_OS_CYGWIN -#define HAVE_STRUCT_TIMESPEC 1 -#define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c) -#define _NO_BOOL_TYPEDEF -#undef interface -#endif - #include CF_INLINE size_t malloc_size(void *memblock) { return malloc_usable_size(memblock); @@ -259,7 +252,14 @@ void OSMemoryBarrier(); #endif -#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX +#if TARGET_OS_CYGWIN +#define HAVE_STRUCT_TIMESPEC 1 +#define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c) +#define _NO_BOOL_TYPEDEF +#undef interface +#endif + +#if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX #if !defined(MIN) #define MIN(A,B) ((A) < (B) ? (A) : (B)) #endif @@ -458,14 +458,6 @@ CF_EXPORT int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *_ #if !defined(CF_PRIVATE) #define CF_PRIVATE __attribute__((__visibility__("hidden"))) #endif - -#if !defined(CF_TEST_PRIVATE) -#ifdef UNIT_TEST -#define CF_TEST_PRIVATE -#else -#define CF_TEST_PRIVATE __attribute__((__visibility__("hidden"))) extern -#endif -#endif #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS diff --git a/CoreFoundation/Base.subproj/ForFoundationOnly.h b/CoreFoundation/Base.subproj/ForFoundationOnly.h index 786bbe7b6d..931404c698 100644 --- a/CoreFoundation/Base.subproj/ForFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForFoundationOnly.h @@ -1,7 +1,7 @@ /* ForFoundationOnly.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -66,15 +66,6 @@ CF_IMPLICIT_BRIDGING_DISABLED #include #endif -/* These functions implement standard error handling for reallocation. Their parameters match their unsafe variants (realloc/CFAllocatorReallocate). They differ from reallocf as they provide a chance for you to clean up a buffers contents (in addition to freeing the buffer, etc.) - - The optional reallocationFailureHandler is called only when the reallocation fails (with the original buffer passed in, so you can clean up the buffer/throw/abort/etc. - - The outRecovered BOOL can be used to control what happens after the handler is called. If left unset, and the reallocationFailureHandler does unwind-the-stack/abort, we use the standard CF out-of-memory flow. If set to YES, then __CFSafelyReallocate{,WithAllocator} will return NULL. - */ -CF_EXPORT void *_Nonnull __CFSafelyReallocate(void * _Nullable destination, size_t newCapacity, void (^_Nullable reallocationFailureHandler)(void *_Nonnull original, _Bool *_Nonnull outRecovered)); -CF_EXPORT void *_Nonnull __CFSafelyReallocateWithAllocator(CFAllocatorRef _Nullable, void * _Nullable destination, size_t newCapacity, CFOptionFlags options, void (^_Nullable reallocationFailureHandler)(void *_Nonnull original, _Bool *_Nonnull outRecovered)); - // ---- CFBundle material ---------------------------------------- #include @@ -100,6 +91,7 @@ CF_EXPORT CFErrorRef _CFBundleCreateError(CFAllocatorRef _Nullable allocator, CF _CF_EXPORT_SCOPE_END + // ---- CFPreferences material ---------------------------------------- #define DEBUG_PREFERENCES_MEMORY 0 @@ -118,7 +110,7 @@ typedef struct { CFTypeRef _Null_unspecified (*_Null_unspecified fetchValue)(CFTypeRef context, void *domain, CFStringRef key); // Caller releases void (*_Null_unspecified writeValue)(CFTypeRef context, void *domain, CFStringRef key, CFTypeRef value); Boolean (*_Null_unspecified synchronize)(CFTypeRef context, void *domain); - void (*_Null_unspecified getKeysAndValues)(CFAllocatorRef _Nullable alloc, CFTypeRef context, void *domain, void *_Null_unspecified * _Null_unspecified buf[_Null_unspecified], CFIndex *numKeyValuePairs); + void (*_Null_unspecified getKeysAndValues)(CFAllocatorRef _Nullable alloc, CFTypeRef context, void *domain, void *_Null_unspecified * _Null_unspecified buf[_Nullable], CFIndex *numKeyValuePairs); CFDictionaryRef _Null_unspecified (*_Null_unspecified copyDomainDictionary)(CFTypeRef context, void *domain); /* HACK - see comment on _CFPreferencesDomainSetIsWorldReadable(), below */ void (*setIsWorldReadable)(CFTypeRef context, void *domain, Boolean isWorldReadable); @@ -357,7 +349,6 @@ CF_EXPORT CFStringRef _CFStringCreateWithFormatAndArgumentsAux(CFAllocatorRef _ CF_EXPORT void _CFStringAppendFormatAndArgumentsAux2(CFMutableStringRef outputString, CFStringRef _Nonnull (*_Nullable copyDescFunc)(void *, const void *loc), CFStringRef _Nonnull (*_Nullable contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef _Nullable formatOptions, CFStringRef formatString, va_list args); CF_EXPORT CFStringRef _CFStringCreateWithFormatAndArgumentsAux2(CFAllocatorRef _Nullable alloc, CFStringRef _Nonnull (*_Nullable copyDescFunc)(void *, const void *loc), CFStringRef _Nonnull (*_Nullable contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef _Nullable formatOptions, CFStringRef format, va_list arguments); -CF_EXPORT CFStringRef CFStringCreateStringWithValidatedFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef validFormatSpecifiers, CFStringRef format, va_list arguments, CFErrorRef *errorPtr) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); /* For NSString (and NSAttributedString) usage, mutate with isMutable check */ @@ -468,16 +459,15 @@ CF_EXPORT void *_Nullable _CFSetTSD(uint32_t slot, void * _Nullable newVal, void */ #if __BLOCKS__ typedef CFTypeRef _Nonnull (^CFErrorUserInfoKeyCallBackBlock)(CFErrorRef err, CFStringRef key); -CF_EXPORT void CFErrorSetCallBackBlockForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBackBlock _Nullable provider) API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT CFErrorUserInfoKeyCallBackBlock CFErrorGetCallBackBlockForDomain(CFStringRef domainName) API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT CFErrorUserInfoKeyCallBackBlock CFErrorCopyCallBackBlockForDomain(CFStringRef domainName) API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +CF_EXPORT void CFErrorSetCallBackBlockForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBackBlock _Nullable provider) CF_AVAILABLE(10_11, 9_0); +CF_EXPORT CFErrorUserInfoKeyCallBackBlock CFErrorGetCallBackBlockForDomain(CFStringRef domainName) CF_AVAILABLE(10_11, 9_0); #endif /* This variant of the error domain callback has been deprecated and will be removed. This callback function is consulted if a key is not present in the userInfo dictionary. Note that setting a callback for the same domain again simply replaces the previous callback. Set NULL as the callback to remove it. The callback function should return a result that is retained. */ typedef CFTypeRef _Nonnull (*CFErrorUserInfoKeyCallBack)(CFErrorRef err, CFStringRef key); -CF_EXPORT void CFErrorSetCallBackForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBack _Nullable callBack) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); -CF_EXPORT CFErrorUserInfoKeyCallBack _Nullable CFErrorGetCallBackForDomain(CFStringRef domainName) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CF_EXPORT void CFErrorSetCallBackForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBack _Nullable callBack) CF_AVAILABLE(10_5, 2_0); +CF_EXPORT CFErrorUserInfoKeyCallBack _Nullable CFErrorGetCallBackForDomain(CFStringRef domainName) CF_AVAILABLE(10_5, 2_0); #if DEPLOYMENT_TARGET_WINDOWS // ---- Windows-specific material --------------------------------------- @@ -511,7 +501,7 @@ CF_EXPORT void _CFSetSetCapacity(CFMutableSetRef set, CFIndex cap); CF_EXPORT void CFCharacterSetCompact(CFMutableCharacterSetRef theSet); CF_EXPORT void CFCharacterSetFast(CFMutableCharacterSetRef theSet); -CF_EXPORT const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx, Boolean *outOfBounds); +CF_EXPORT const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx); CF_EXPORT void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void *_Nullable * _Nullable newValues, CFIndex newCount); @@ -540,22 +530,14 @@ CF_INLINE CFHashCode _CFHashInt(long i) { return ((i > 0) ? (CFHashCode)(i) : (CFHashCode)(-i)) * HASHFACTOR; } -CF_INLINE CFHashCode _CFHashDouble(const double d) { - const double positive = (d < 0) ? -d : d; - const double positiveInt = floor(positive + 0.5); - const double fractional = (positive - positiveInt) * ULONG_MAX; - CFHashCode result = HASHFACTOR * (CFHashCode)fmod(positiveInt, (double)ULONG_MAX); - if (fractional < 0) { - // UBSan: Certain negative floating-point numbers are unrepresentable as 'unsigned long' which enters into undefined behavior territory in C. Thus we ensure it is positive, cast and then subtract as an integer where numbers behave correctly. - result += -((CFHashCode)(fabs(fractional))); - } else if (fractional > 0) { - // Caveat: the > 0 is incredibly important [28612173] - result += fractional; - } - return result; +CF_INLINE CFHashCode _CFHashDouble(double d) { + double dInt; + if (d < 0) d = -d; + dInt = floor(d+0.5); + CFHashCode integralHash = HASHFACTOR * (CFHashCode)fmod(dInt, (double)ULONG_MAX); + return (CFHashCode)(integralHash + (CFHashCode)((d - dInt) * ULONG_MAX)); } - CF_SWIFT_EXPORT void _CFNumberInitBool(CFNumberRef result, Boolean value); CF_SWIFT_EXPORT void _CFNumberInitInt8(CFNumberRef result, int8_t value); CF_SWIFT_EXPORT void _CFNumberInitUInt8(CFNumberRef result, uint8_t value); @@ -590,7 +572,7 @@ CF_EXPORT CFTypeRef _CFRunLoopGet2(CFRunLoopRef rl); CF_EXPORT Boolean _CFRunLoopIsCurrent(CFRunLoopRef rl); CF_EXPORT CFIndex _CFStreamInstanceSize(void); -CF_EXPORT CFReadStreamRef CFReadStreamCreateWithData(_Nullable CFAllocatorRef alloc, CFDataRef data); +CF_EXPORT CFReadStreamRef CFReadStreamCreateWithData(CFAllocatorRef alloc, CFDataRef data); #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED typedef struct { @@ -615,7 +597,7 @@ enum { // This is for NSNumberFormatter use only! CF_EXPORT void *_CFNumberFormatterGetFormatter(CFNumberFormatterRef formatter); -CF_SWIFT_EXPORT void _CFDataInit(CFMutableDataRef memory, CFOptionFlags variety, CFIndex capacity, const uint8_t *_Nullable bytes, CFIndex length, Boolean noCopy); +CF_SWIFT_EXPORT void _CFDataInit(CFMutableDataRef memory, CFOptionFlags flags, CFIndex capacity, const uint8_t *_Nullable bytes, CFIndex length, Boolean noCopy); CF_EXPORT CFRange _CFDataFindBytes(CFDataRef data, CFDataRef dataToFind, CFRange searchRange, CFDataSearchFlags compareOptions); @@ -655,7 +637,6 @@ CF_EXPORT CFStringRef _CFProcessNameString(void); CF_EXPORT CFIndex __CFActiveProcessorCount(void); CF_EXPORT CFDictionaryRef __CFGetEnvironment(void); CF_EXPORT int32_t __CFGetPid(void); -CF_EXPORT int32_t __CFGetPid(void); CF_EXPORT CFTimeInterval CFGetSystemUptime(void); CF_EXPORT CFStringRef CFCopySystemVersionString(void); CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void); @@ -696,30 +677,6 @@ CF_EXPORT CFTypeRef _CFNonObjCRetain(CFTypeRef cf); CF_EXPORT void _CFNonObjCRelease(CFTypeRef cf); CF_EXPORT CFHashCode _CFNonObjCHash(CFTypeRef cf); -CF_EXPORT void *__CFTSANTagMutableArray; -CF_EXPORT void *__CFTSANTagMutableDictionary; -CF_EXPORT void *__CFTSANTagMutableSet; -CF_EXPORT void *__CFTSANTagMutableOrderedSet; - -CF_EXPORT void *_CFRegisterThreadSanitizerTag(char *name); -CF_EXPORT void _CFAssignThreadSanitizerTag(void *const _Nonnull ptr, void *const tag); - -CF_EXPORT void (*__cf_tsanReadFunction)(void *, void *, void *); -#define _CFRecordReadForDataOwnedBy(P, T) do {\ - if (__builtin_expect(__cf_tsanReadFunction != NULL, false) && (P) && (T)) {\ - __cf_tsanReadFunction((P), __builtin_return_address(0), (T));\ - }\ -} while(0) - -CF_EXPORT void (*__cf_tsanWriteFunction)(void *, void *, void *); -#define _CFRecordWriteForDataOwnedBy(P, T) do {\ - if (__builtin_expect(__cf_tsanWriteFunction != NULL, false) && (P) && (T)) {\ - __cf_tsanWriteFunction((P), __builtin_return_address(0), (T));\ - }\ -} while (0) - -CF_EXPORT void *_CFCreateArrayStorage(size_t numPointers, Boolean zeroed, size_t *actualNumPointers); - _CF_EXPORT_SCOPE_END #endif /* ! __COREFOUNDATION_FORFOUNDATIONONLY__ */ diff --git a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h index 65a50bf445..57e2f122b5 100644 --- a/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h +++ b/CoreFoundation/Base.subproj/ForSwiftFoundationOnly.h @@ -323,9 +323,11 @@ CF_EXPORT Boolean _CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, CF_EXPORT CFCharacterSetRef _CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet); CF_EXPORT CFMutableCharacterSetRef _CFCharacterSetCreateMutableCopy(CFAllocatorRef alloc, CFCharacterSetRef theSet); -CF_EXPORT _Nullable CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream); +CF_EXPORT CFReadStreamRef CFReadStreamCreateWithData(CFAllocatorRef alloc, CFDataRef data); -CF_EXPORT _Nullable CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream); +CF_EXPORT _Nullable CFErrorRef _CFReadStreamCopyError(CFReadStreamRef stream); + +CF_EXPORT _Nullable CFErrorRef _CFWriteStreamCopyError(CFWriteStreamRef stream); // https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html // Version 0.8 diff --git a/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap b/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap index 13f56b787d..bd86bad575 100644 Binary files a/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap and b/CoreFoundation/CharacterSets/CFCharacterSetBitmaps.bitmap differ diff --git a/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data b/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data index 17fa59f704..bf0bdd3105 100644 Binary files a/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data and b/CoreFoundation/CharacterSets/CFUniCharPropertyDatabase.data differ diff --git a/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping b/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping index 35934e482e..c851efd226 100644 Binary files a/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping and b/CoreFoundation/CharacterSets/CFUnicodeData-B.mapping differ diff --git a/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping b/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping index b7194c6878..3bcc72f2c8 100644 Binary files a/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping and b/CoreFoundation/CharacterSets/CFUnicodeData-L.mapping differ diff --git a/CoreFoundation/Collections.subproj/CFArray.c b/CoreFoundation/Collections.subproj/CFArray.c index 58a5f29310..6a5e3c4cc0 100644 --- a/CoreFoundation/Collections.subproj/CFArray.c +++ b/CoreFoundation/Collections.subproj/CFArray.c @@ -1,11 +1,11 @@ /* CFArray.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Michael Lehew + Responsibility: Christopher Kane */ #include @@ -13,10 +13,6 @@ #include "CFInternal.h" #include -#define CF_ARRAY_ALWAYS_BRIDGE 0 - - - const CFArrayCallBacks kCFTypeArrayCallBacks = {0, __CFTypeCollectionRetain, __CFTypeCollectionRelease, CFCopyDescription, CFEqual}; static const CFArrayCallBacks __kCFNullArrayCallBacks = {0, NULL, NULL, NULL, NULL}; @@ -61,14 +57,14 @@ enum { /* Bits 2-3 */ }; CF_INLINE CFIndex __CFArrayGetType(CFArrayRef array) { - return __CFRuntimeGetValue(array, 1, 0); + return __CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 1, 0); } CF_INLINE CFIndex __CFArrayGetSizeOfType(CFIndex t) { CFIndex size = 0; - size += sizeof(struct __CFArray); + size += sizeof(struct __CFArray); if (__CFBitfieldGetValue(t, 3, 2) == __kCFArrayHasCustomCallBacks) { - size += sizeof(CFArrayCallBacks); + size += sizeof(CFArrayCallBacks); } return size; } @@ -85,12 +81,12 @@ CF_INLINE void __CFArraySetCount(CFArrayRef array, CFIndex v) { * Returns the bucket holding the left-most real value in the latter case. */ CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketsPtr(CFArrayRef array) { switch (__CFArrayGetType(array)) { - case __kCFArrayImmutable: - return (struct __CFArrayBucket *)((uint8_t *)array + __CFArrayGetSizeOfType(__CFRuntimeGetValue(array, 6, 0))); - case __kCFArrayDeque: { - struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store; - return (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque) + deque->_leftIdx * sizeof(struct __CFArrayBucket)); - } + case __kCFArrayImmutable: + return (struct __CFArrayBucket *)((uint8_t *)array + __CFArrayGetSizeOfType(((CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS])); + case __kCFArrayDeque: { + struct __CFArrayDeque *deque = (struct __CFArrayDeque *)array->_store; + return (struct __CFArrayBucket *)((uint8_t *)deque + sizeof(struct __CFArrayDeque) + deque->_leftIdx * sizeof(struct __CFArrayBucket)); + } } return NULL; } @@ -98,30 +94,30 @@ CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketsPtr(CFArrayRef array) { /* This shouldn't be called if the array count is 0. */ CF_INLINE struct __CFArrayBucket *__CFArrayGetBucketAtIndex(CFArrayRef array, CFIndex idx) { switch (__CFArrayGetType(array)) { - case __kCFArrayImmutable: - case __kCFArrayDeque: - return __CFArrayGetBucketsPtr(array) + idx; + case __kCFArrayImmutable: + case __kCFArrayDeque: + return __CFArrayGetBucketsPtr(array) + idx; } return NULL; } CF_PRIVATE CFArrayCallBacks *__CFArrayGetCallBacks(CFArrayRef array) { CFArrayCallBacks *result = NULL; - switch (__CFRuntimeGetValue(array, 3, 2)) { - case __kCFArrayHasNullCallBacks: - return (CFArrayCallBacks *)&__kCFNullArrayCallBacks; - case __kCFArrayHasCFTypeCallBacks: - return (CFArrayCallBacks *)&kCFTypeArrayCallBacks; - case __kCFArrayHasCustomCallBacks: - break; + switch (__CFBitfieldGetValue(((const CFRuntimeBase *)array)->_cfinfo[CF_INFO_BITS], 3, 2)) { + case __kCFArrayHasNullCallBacks: + return (CFArrayCallBacks *)&__kCFNullArrayCallBacks; + case __kCFArrayHasCFTypeCallBacks: + return (CFArrayCallBacks *)&kCFTypeArrayCallBacks; + case __kCFArrayHasCustomCallBacks: + break; } switch (__CFArrayGetType(array)) { - case __kCFArrayImmutable: - result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray)); - break; - case __kCFArrayDeque: - result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray)); - break; + case __kCFArrayImmutable: + result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray)); + break; + case __kCFArrayDeque: + result = (CFArrayCallBacks *)((uint8_t *)array + sizeof(struct __CFArray)); + break; } return result; } @@ -168,8 +164,8 @@ static void __CFArrayReleaseValues(CFArrayRef array, CFRange range, bool release allocator = __CFGetAllocator(array); for (idx = 0; idx < range.length; idx++) { INVOKE_CALLBACK2(cb->release, allocator, buckets[idx + range.location]._item); + buckets[idx + range.location]._item = NULL; } - memset(buckets + range.location, 0, sizeof(struct __CFArrayBucket) * range.length); } break; case __kCFArrayDeque: { @@ -180,9 +176,13 @@ static void __CFArrayReleaseValues(CFArrayRef array, CFRange range, bool release allocator = __CFGetAllocator(array); for (idx = 0; idx < range.length; idx++) { INVOKE_CALLBACK2(cb->release, allocator, buckets[idx + range.location]._item); + buckets[idx + range.location]._item = NULL; } - } - memset(buckets + range.location, 0, sizeof(struct __CFArrayBucket) * range.length); + } else { + for (idx = 0; idx < range.length; idx++) { + buckets[idx + range.location]._item = NULL; + } + } } if (releaseStorageIfPossible && 0 == range.location && __CFArrayGetCount(array) == range.length) { allocator = __CFGetAllocator(array); @@ -240,7 +240,7 @@ static CFStringRef __CFArrayCopyDescription(CFTypeRef cf) { CFAllocatorRef allocator; CFIndex idx, cnt; cnt = __CFArrayGetCount(array); - allocator = __CFGetAllocator(array); + allocator = CFGetAllocator(array); result = CFStringCreateMutable(allocator, 0); switch (__CFArrayGetType(array)) { case __kCFArrayImmutable: @@ -321,7 +321,7 @@ static CFArrayRef __CFArrayInit(CFAllocatorRef allocator, UInt32 flags, CFIndex if (NULL == memory) { return NULL; } - __CFRuntimeSetValue(memory, 6, 0, flags); + __CFBitfieldSetValue(memory->_base._cfinfo[CF_INFO_BITS], 6, 0, flags); __CFArraySetCount((CFArrayRef)memory, 0); switch (__CFBitfieldGetValue(flags, 1, 0)) { case __kCFArrayImmutable: @@ -356,7 +356,7 @@ CF_PRIVATE CFArrayRef __CFArrayCreateTransfer(CFAllocatorRef allocator, const vo if (NULL == memory) { return NULL; } - __CFRuntimeSetValue(memory, 6, 0, flags); + __CFBitfieldSetValue(memory->_base._cfinfo[CF_INFO_BITS], 6, 0, flags); __CFArraySetCount(memory, numValues); memmove(__CFArrayGetBucketsPtr(memory), values, sizeof(void *) * numValues); if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFArray (immutable)"); @@ -415,7 +415,7 @@ CF_PRIVATE CFArrayRef __CFArrayCreateCopy0(CFAllocatorRef allocator, CFArrayRef if (NULL != cb->retain) { value = (void *)INVOKE_CALLBACK2(cb->retain, allocator, value); } - buckets->_item = value; + __CFAssignWithWriteBarrier((void **)&buckets->_item, (void *)value); buckets++; } __CFArraySetCount(result, numValues); @@ -465,12 +465,6 @@ CFMutableArrayRef CFArrayCreateMutableCopy(CFAllocatorRef allocator, CFIndex cap #endif -CF_PRIVATE CFIndex _CFNonObjCArrayGetCount(CFArrayRef array) { - __CFGenericValidateType(array, CFArrayGetTypeID()); - CHECK_FOR_MUTATION(array); - return __CFArrayGetCount(array); -} - CFIndex CFArrayGetCount(CFArrayRef array) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), CFIndex, (CFSwiftRef)array, NSArray.count); CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), CFIndex, (NSArray *)array, count); @@ -479,6 +473,7 @@ CFIndex CFArrayGetCount(CFArrayRef array) { return __CFArrayGetCount(array); } + CFIndex CFArrayGetCountOfValue(CFArrayRef array, CFRange range, const void *value) { CFIndex idx, count = 0; __CFGenericValidateType(array, CFArrayGetTypeID()); @@ -511,23 +506,17 @@ Boolean CFArrayContainsValue(CFArrayRef array, CFRange range, const void *value) const void *CFArrayGetValueAtIndex(CFArrayRef array, CFIndex idx) { CF_SWIFT_FUNCDISPATCHV(CFArrayGetTypeID(), const void *, (CFSwiftRef)array, NSArray.objectAtIndex, idx); - - -#if !CF_ARRAY_ALWAYS_BRIDGE + CF_OBJC_FUNCDISPATCHV(CFArrayGetTypeID(), const void *, (NSArray *)array, objectAtIndex:idx); __CFGenericValidateType(array, CFArrayGetTypeID()); CFAssert2(0 <= idx && idx < __CFArrayGetCount(array), __kCFLogAssertion, "%s(): index (%ld) out of bounds", __PRETTY_FUNCTION__, idx); - Boolean outOfBounds = false; - const void *result = _CFArrayCheckAndGetValueAtIndex(array, idx, &outOfBounds); - if (outOfBounds) HALT; - return result; -#endif + CHECK_FOR_MUTATION(array); + return __CFArrayGetBucketAtIndex(array, idx)->_item; } // This is for use by NSCFArray; it avoids ObjC dispatch, and checks for out of bounds -const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx, Boolean *outOfBounds) { +const void *_CFArrayCheckAndGetValueAtIndex(CFArrayRef array, CFIndex idx) { CHECK_FOR_MUTATION(array); if (0 <= idx && idx < __CFArrayGetCount(array)) return __CFArrayGetBucketAtIndex(array, idx)->_item; - if (outOfBounds) *outOfBounds = true; return (void *)(-1); } @@ -646,7 +635,7 @@ void CFArraySetValueAtIndex(CFMutableArrayRef array, CFIndex idx, const void *va value = (void *)INVOKE_CALLBACK2(cb->retain, allocator, value); } old_value = bucket->_item; - bucket->_item = value; + __CFAssignWithWriteBarrier((void **)&bucket->_item, (void *)value); if (NULL != cb->release) { INVOKE_CALLBACK2(cb->release, allocator, old_value); } @@ -681,8 +670,9 @@ void CFArrayExchangeValuesAtIndices(CFMutableArrayRef array, CFIndex idx1, CFInd bucket1 = __CFArrayGetBucketAtIndex(array, idx1); bucket2 = __CFArrayGetBucketAtIndex(array, idx2); tmp = bucket1->_item; - bucket1->_item = bucket2->_item; - bucket2->_item = tmp; + // XXX these aren't needed. + __CFAssignWithWriteBarrier((void **)&bucket1->_item, (void *)bucket2->_item); + __CFAssignWithWriteBarrier((void **)&bucket2->_item, (void *)tmp); array->_mutations++; END_MUTATION(array); } @@ -747,7 +737,7 @@ static void __CFArrayRepositionDequeRegions(CFMutableArrayRef array, CFRange ran newDeque->_capacity = capacity; if (0 < A) memmove(newBuckets + newL, buckets + oldL, A * sizeof(struct __CFArrayBucket)); if (0 < C) memmove(newBuckets + newC0, buckets + oldC0, C * sizeof(struct __CFArrayBucket)); - array->_store = newDeque; + __CFAssignWithWriteBarrier((void **)&array->_store, (void *)newDeque); if (deque) CFAllocatorDeallocate(allocator, deque); //printf("3: array %p store is now %p (%lx)\n", array, array->_store, *(unsigned long *)(array->_store)); return; @@ -832,7 +822,7 @@ void _CFArraySetCapacity(CFMutableArrayRef array, CFIndex cap) { if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)"); } deque->_capacity = capacity; - array->_store = deque; + __CFAssignWithWriteBarrier((void **)&array->_store, (void *)deque); } END_MUTATION(array); } @@ -900,7 +890,7 @@ void _CFArrayReplaceValues(CFMutableArrayRef array, CFRange range, const void ** if (__CFOASafe) __CFSetLastAllocationEventName(deque, "CFArray (store-deque)"); deque->_leftIdx = (capacity - newCount) / 2; deque->_capacity = capacity; - array->_store = deque; + __CFAssignWithWriteBarrier((void **)&array->_store, (void *)deque); } } else { // Deque // reposition regions A and C for new region B elements in gap diff --git a/CoreFoundation/Collections.subproj/CFArray.h b/CoreFoundation/Collections.subproj/CFArray.h index 6ce9b1e000..06b603c330 100644 --- a/CoreFoundation/Collections.subproj/CFArray.h +++ b/CoreFoundation/Collections.subproj/CFArray.h @@ -1,5 +1,5 @@ /* CFArray.h - Copyright (c) 1998-2017, Apple Inc. All rights reserved. + Copyright (c) 1998-2016, Apple Inc. All rights reserved. */ /*! diff --git a/CoreFoundation/Collections.subproj/CFBag.c b/CoreFoundation/Collections.subproj/CFBag.c index b8ca20fbb0..3cbedda04e 100644 --- a/CoreFoundation/Collections.subproj/CFBag.c +++ b/CoreFoundation/Collections.subproj/CFBag.c @@ -1,7 +1,7 @@ /* CFBag.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -402,10 +402,7 @@ void CFBagGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { #endif #if CFDictionary if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFBagGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); -#pragma GCC diagnostic pop #endif #if CFSet if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFBagGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); @@ -469,11 +466,11 @@ CF_EXPORT void _CFBagSetCapacity(CFMutableHashRef hc, CFIndex cap) { } CF_INLINE CFIndex __CFBagGetKVOBit(CFHashRef hc) { - return __CFRuntimeGetFlag(hc, 0); + return __CFBitfieldGetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0); } CF_INLINE void __CFBagSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); + __CFBitfieldSetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0, ((uintptr_t)bit & 0x1)); } // This function is for Foundation's benefit; no one else should use it. diff --git a/CoreFoundation/Collections.subproj/CFBag.h b/CoreFoundation/Collections.subproj/CFBag.h index 82f87af56e..46353fd86c 100644 --- a/CoreFoundation/Collections.subproj/CFBag.h +++ b/CoreFoundation/Collections.subproj/CFBag.h @@ -1,7 +1,7 @@ /* CFBag.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFBasicHash.c b/CoreFoundation/Collections.subproj/CFBasicHash.c index f4a192dfb7..83eabd067d 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHash.c +++ b/CoreFoundation/Collections.subproj/CFBasicHash.c @@ -1,7 +1,7 @@ /* CFBasicHash.m - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -311,18 +311,12 @@ struct __CFBasicHash { void *pointers[1]; }; -#define CFBasicHashSmallSize (1<<8) -#define CFBasicHashMaxSize (1<<10) -static void **CFBasicHashCallBackPtrs; -static _Atomic(int32_t) CFBasicHashCallBackPtrsCount = 0; +static void *CFBasicHashCallBackPtrs[(1UL << 10)]; +static int32_t CFBasicHashCallBackPtrsCount = 0; static int32_t CFBasicHashGetPtrIndex(void *ptr) { static dispatch_once_t once; dispatch_once(&once, ^{ - CFBasicHashCallBackPtrs = malloc(sizeof(void *) * CFBasicHashSmallSize); - if (CFBasicHashCallBackPtrs == NULL) { - HALT; - } CFBasicHashCallBackPtrs[0] = NULL; CFBasicHashCallBackPtrs[1] = (void *)CFCopyDescription; CFBasicHashCallBackPtrs[2] = (void *)__CFTypeCollectionRelease; @@ -333,27 +327,23 @@ static int32_t CFBasicHashGetPtrIndex(void *ptr) { CFBasicHashCallBackPtrs[7] = NULL; CFBasicHashCallBackPtrsCount = 8; }); + + // The uniquing here is done locklessly for best performance, and in + // a way that will keep multiple threads from stomping each other's + // newly registered values, but may result in multiple slots + // containing the same pointer value. + int32_t idx; for (idx = 0; idx < CFBasicHashCallBackPtrsCount; idx++) { - if (CFBasicHashCallBackPtrs[idx] == ptr) { - return idx; - } + if (CFBasicHashCallBackPtrs[idx] == ptr) return idx; } - - if (CFBasicHashCallBackPtrsCount == CFBasicHashSmallSize) { - CFBasicHashCallBackPtrs = __CFSafelyReallocate(CFBasicHashCallBackPtrs, sizeof(id) * CFBasicHashMaxSize, NULL); - } else if (1000 < CFBasicHashCallBackPtrsCount) HALT; - - idx = ++CFBasicHashCallBackPtrsCount; + + if (1000 < CFBasicHashCallBackPtrsCount) HALT; + idx = OSAtomicIncrement32(&CFBasicHashCallBackPtrsCount); // returns new value CFBasicHashCallBackPtrs[idx - 1] = ptr; return idx - 1; } -// Tell TSAN to ignore this function for sanitization - it races intentionally -static inline void *CFBasicHashGetPtrAtIndex(int32_t i) __attribute__((no_sanitize("thread"))) { - return CFBasicHashCallBackPtrs[i]; -} - CF_PRIVATE Boolean CFBasicHashHasStrongValues(CFConstBasicHashRef ht) { #if DEPLOYMENT_TARGET_MACOSX return ht->bits.strong_values ? true : false; @@ -379,67 +369,67 @@ CF_INLINE Boolean __CFBasicHashHasHashCache(CFConstBasicHashRef ht) { } CF_INLINE uintptr_t __CFBasicHashImportValue(CFConstBasicHashRef ht, uintptr_t stack_value) { - uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__vret); + uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vret]; if (!func || ht->bits.null_rc) return stack_value; - CFAllocatorRef alloc = __CFGetAllocator(ht); + CFAllocatorRef alloc = CFGetAllocator(ht); return func(alloc, stack_value); } CF_INLINE uintptr_t __CFBasicHashImportKey(CFConstBasicHashRef ht, uintptr_t stack_key) { - uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__kret); + uintptr_t (*func)(CFAllocatorRef, uintptr_t) = (uintptr_t (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kret]; if (!func || ht->bits.null_rc) return stack_key; - CFAllocatorRef alloc = __CFGetAllocator(ht); + CFAllocatorRef alloc = CFGetAllocator(ht); return func(alloc, stack_key); } CF_INLINE void __CFBasicHashEjectValue(CFConstBasicHashRef ht, uintptr_t stack_value) { - void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__vrel); + void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vrel]; if (!func || ht->bits.null_rc) return; - CFAllocatorRef alloc = __CFGetAllocator(ht); + CFAllocatorRef alloc = CFGetAllocator(ht); func(alloc, stack_value); } CF_INLINE void __CFBasicHashEjectKey(CFConstBasicHashRef ht, uintptr_t stack_key) { - void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__krel); + void (*func)(CFAllocatorRef, uintptr_t) = (void (*)(CFAllocatorRef, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__krel]; if (!func || ht->bits.null_rc) return; - CFAllocatorRef alloc = __CFGetAllocator(ht); + CFAllocatorRef alloc = CFGetAllocator(ht); func(alloc, stack_key); } CF_INLINE CFStringRef __CFBasicHashDescValue(CFConstBasicHashRef ht, uintptr_t stack_value) CF_RETURNS_RETAINED { - CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__vdes); + CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vdes]; if (!func) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_value); return func(stack_value); } CF_INLINE CFStringRef __CFBasicHashDescKey(CFConstBasicHashRef ht, uintptr_t stack_key) CF_RETURNS_RETAINED { - CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__kdes); + CFStringRef (*func)(uintptr_t) = (CFStringRef (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kdes]; if (!func) return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<%p>"), (void *)stack_key); return func(stack_key); } CF_INLINE Boolean __CFBasicHashTestEqualValue(CFConstBasicHashRef ht, uintptr_t stack_value_a, uintptr_t stack_value_b) { - Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__vequ); + Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__vequ]; if (!func) return (stack_value_a == stack_value_b); return func(stack_value_a, stack_value_b); } CF_INLINE Boolean __CFBasicHashTestEqualKey(CFConstBasicHashRef ht, uintptr_t in_coll_key, uintptr_t stack_key) { COCOA_HASHTABLE_TEST_EQUAL(ht, in_coll_key, stack_key); - Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__kequ); + Boolean (*func)(uintptr_t, uintptr_t) = (Boolean (*)(uintptr_t, uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kequ]; if (!func) return (in_coll_key == stack_key); return func(in_coll_key, stack_key); } CF_INLINE CFHashCode __CFBasicHashHashKey(CFConstBasicHashRef ht, uintptr_t stack_key) { - CFHashCode (*func)(uintptr_t) = (CFHashCode (*)(uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__khas); + CFHashCode (*func)(uintptr_t) = (CFHashCode (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__khas]; CFHashCode hash_code = func ? func(stack_key) : stack_key; COCOA_HASHTABLE_HASH_KEY(ht, stack_key, hash_code); return hash_code; } CF_INLINE uintptr_t __CFBasicHashGetIndirectKey(CFConstBasicHashRef ht, uintptr_t coll_key) { - uintptr_t (*func)(uintptr_t) = (uintptr_t (*)(uintptr_t))CFBasicHashGetPtrAtIndex(ht->bits.__kget); + uintptr_t (*func)(uintptr_t) = (uintptr_t (*)(uintptr_t))CFBasicHashCallBackPtrs[ht->bits.__kget]; if (!func) return coll_key; return func(coll_key); } diff --git a/CoreFoundation/Collections.subproj/CFBasicHash.h b/CoreFoundation/Collections.subproj/CFBasicHash.h index 90ec452e85..14f39f425f 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHash.h +++ b/CoreFoundation/Collections.subproj/CFBasicHash.h @@ -1,7 +1,7 @@ /* CFBasicHash.h - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -62,13 +62,13 @@ typedef struct { typedef struct __CFBasicHash *CFBasicHashRef; typedef const struct __CFBasicHash *CFConstBasicHashRef; +// Bit 6 in the CF_INFO_BITS of the CFRuntimeBase inside the CFBasicHashRef is the "is immutable" bit CF_INLINE Boolean CFBasicHashIsMutable(CFConstBasicHashRef ht) { - // Bit 6 in the info bits of the CFRuntimeBase inside the CFBasicHashRef is the "is immutable" bit, so flip the return value of the get function - return !__CFRuntimeGetFlag(ht, 6); + return __CFBitfieldGetValue(((CFRuntimeBase *)ht)->_cfinfo[CF_INFO_BITS], 6, 6) ? false : true; } CF_INLINE void CFBasicHashMakeImmutable(CFBasicHashRef ht) { - __CFRuntimeSetFlag(ht, 6, true); + __CFBitfieldSetValue(((CFRuntimeBase *)ht)->_cfinfo[CF_INFO_BITS], 6, 6, 1); } diff --git a/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m b/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m index 2d8f8eb1ba..4805206166 100644 --- a/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m +++ b/CoreFoundation/Collections.subproj/CFBasicHashFindBucket.m @@ -1,7 +1,7 @@ /* CFBasicHashFindBucket.m - Copyright (c) 2009-2017, Apple Inc. and the Swift project authors + Copyright (c) 2009-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFBinaryHeap.c b/CoreFoundation/Collections.subproj/CFBinaryHeap.c index 1fa621f494..a39ca58f27 100644 --- a/CoreFoundation/Collections.subproj/CFBinaryHeap.c +++ b/CoreFoundation/Collections.subproj/CFBinaryHeap.c @@ -1,7 +1,7 @@ /* CFBinaryHeap.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -73,11 +73,11 @@ enum { /* bits 1-0 */ }; CF_INLINE UInt32 __CFBinaryHeapMutableVariety(const void *cf) { - return __CFRuntimeGetValue(cf, 3, 2); + return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2); } CF_INLINE void __CFBinaryHeapSetMutableVariety(void *cf, UInt32 v) { - __CFRuntimeSetValue(cf, 3, 2, v); + __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2, v); } CF_INLINE UInt32 __CFBinaryHeapMutableVarietyFromFlags(UInt32 flags) { @@ -325,9 +325,10 @@ static void __CFBinaryHeapGrow(CFBinaryHeapRef heap, CFIndex numNewValues) { CFAllocatorRef allocator = CFGetAllocator(heap); __CFBinaryHeapSetCapacity(heap, capacity); __CFBinaryHeapSetNumBuckets(heap, __CFBinaryHeapNumBucketsForCapacity(capacity)); - void *buckets = __CFSafelyReallocateWithAllocator(allocator, heap->_buckets, __CFBinaryHeapNumBuckets(heap) * sizeof(struct __CFBinaryHeapBucket), 0, NULL); + void *buckets = CFAllocatorReallocate(allocator, heap->_buckets, __CFBinaryHeapNumBuckets(heap) * sizeof(struct __CFBinaryHeapBucket), 0); *((void **)&heap->_buckets) = buckets; if (__CFOASafe) __CFSetLastAllocationEventName(heap->_buckets, "CFBinaryHeap (store)"); + if (NULL == heap->_buckets) HALT; } void CFBinaryHeapAddValue(CFBinaryHeapRef heap, const void *value) { diff --git a/CoreFoundation/Collections.subproj/CFBinaryHeap.h b/CoreFoundation/Collections.subproj/CFBinaryHeap.h index aaec0f542d..c59cddf657 100644 --- a/CoreFoundation/Collections.subproj/CFBinaryHeap.h +++ b/CoreFoundation/Collections.subproj/CFBinaryHeap.h @@ -1,7 +1,7 @@ /* CFBinaryHeap.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -72,7 +72,7 @@ CF_EXPORT const CFBinaryHeapCallBacks kCFStringBinaryHeapCallBacks; @typedef CFBinaryHeapApplierFunction Type of the callback function used by the apply functions of CFBinaryHeap. - @param val The current value from the binary heap. + @param value The current value from the binary heap. @param context The user-defined context parameter given to the apply function. */ diff --git a/CoreFoundation/Collections.subproj/CFBitVector.c b/CoreFoundation/Collections.subproj/CFBitVector.c index fa50220b9d..0545337e52 100644 --- a/CoreFoundation/Collections.subproj/CFBitVector.c +++ b/CoreFoundation/Collections.subproj/CFBitVector.c @@ -1,7 +1,7 @@ /* CFBitVector.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -46,11 +46,11 @@ struct __CFBitVector { }; CF_INLINE UInt32 __CFBitVectorMutableVariety(const void *cf) { - return __CFRuntimeGetValue(cf, 3, 2); + return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2); } CF_INLINE void __CFBitVectorSetMutableVariety(void *cf, UInt32 v) { - __CFRuntimeSetValue(cf, 3, 2, v); + __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 2, v); } CF_INLINE UInt32 __CFBitVectorMutableVarietyFromFlags(UInt32 flags) { @@ -422,8 +422,9 @@ static void __CFBitVectorGrow(CFMutableBitVectorRef bv, CFIndex numNewValues) { CFAllocatorRef allocator = CFGetAllocator(bv); __CFBitVectorSetCapacity(bv, capacity); __CFBitVectorSetNumBuckets(bv, __CFBitVectorNumBucketsForCapacity(capacity)); - *((void **)&bv->_buckets) = __CFSafelyReallocateWithAllocator(allocator, bv->_buckets, __CFBitVectorNumBuckets(bv) * sizeof(__CFBitVectorBucket), 0, NULL); + *((void **)&bv->_buckets) = CFAllocatorReallocate(allocator, bv->_buckets, __CFBitVectorNumBuckets(bv) * sizeof(__CFBitVectorBucket), 0); if (__CFOASafe) __CFSetLastAllocationEventName(bv->_buckets, "CFBitVector (store)"); + if (NULL == bv->_buckets) HALT; } static __CFBitVectorBucket __CFBitVectorZeroBits(__CFBitVectorBucket bucketValue, __CFBitVectorBucket bucketValueMask, void *context) { diff --git a/CoreFoundation/Collections.subproj/CFBitVector.h b/CoreFoundation/Collections.subproj/CFBitVector.h index 2e91d84fc3..7ff963532d 100644 --- a/CoreFoundation/Collections.subproj/CFBitVector.h +++ b/CoreFoundation/Collections.subproj/CFBitVector.h @@ -1,7 +1,7 @@ /* CFBitVector.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFData.c b/CoreFoundation/Collections.subproj/CFData.c index c735a3845c..22555af1bf 100644 --- a/CoreFoundation/Collections.subproj/CFData.c +++ b/CoreFoundation/Collections.subproj/CFData.c @@ -1,7 +1,7 @@ /* CFData.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -15,7 +15,6 @@ - #if __LP64__ #define CFDATA_MAX_SIZE ((1ULL << 42) - 1) #else @@ -23,7 +22,7 @@ #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -#import +#include CF_INLINE unsigned long __CFPageSize() { return vm_page_size; } #elif DEPLOYMENT_TARGET_WINDOWS CF_INLINE unsigned long __CFPageSize() { @@ -57,6 +56,7 @@ struct __CFData { Bit 2 = bytes inline Bit 3 = use given CFAllocator Bit 4 = don't deallocate + Bit 5 = allocate collectable memory Bits 1-0 are used for mutability variation @@ -64,69 +64,52 @@ struct __CFData { */ enum { - __kCFMutableMask = 0x01, - __kCFGrowableMask = 0x02, + __kCFMutable = 0x01, + __kCFGrowable = 0x02, + __kCFMutableVarietyMask = 0x03, + __kCFBytesInline = 0x04, + __kCFUseAllocator = 0x08, + __kCFDontDeallocate = 0x10, }; enum { - // These bits are within the mutable mask and growable mask - __kCFMutable = 0, - __kCFGrowable = 1, - - // These bits are stand-alone - __kCFBytesInline = 2, - __kCFUseAllocator = 3, - __kCFDontDeallocate = 4, - __kCFNeedsZero = 6, -}; - -typedef enum { kCFImmutable = 0x0, /* unchangable and fixed capacity; default */ kCFFixedMutable = 0x1, /* changeable and fixed capacity */ kCFMutable = 0x3 /* changeable and variable capacity */ -} _CFDataMutableVariety; - -CF_INLINE Boolean __CFDataIsMutable(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFMutable); -} +}; -CF_INLINE Boolean __CFDataIsGrowable(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFGrowable); -} +CF_INLINE void __CFDataSetInfoBits(CFDataRef data, UInt32 v) {__CFBitfieldSetValue(((CFRuntimeBase *)data)->_cfinfo[CF_INFO_BITS], 5, 0, v);} +CF_INLINE Boolean __CFDataGetInfoBit(CFDataRef data, UInt32 b) {return ((((const CFRuntimeBase *)data)->_cfinfo[CF_INFO_BITS] & b) != 0);} +CF_INLINE Boolean __CFDataIsMutable(CFDataRef data) {return __CFDataGetInfoBit(data, __kCFMutable);} +CF_INLINE Boolean __CFDataIsGrowable(CFDataRef data) {return __CFDataGetInfoBit(data, __kCFGrowable);} +CF_INLINE Boolean __CFDataBytesInline(CFDataRef data) {return __CFDataGetInfoBit(data, __kCFBytesInline);} +CF_INLINE Boolean __CFDataUseAllocator(CFDataRef data) {return __CFDataGetInfoBit(data, __kCFUseAllocator);} -CF_INLINE Boolean __CFDataBytesInline(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFBytesInline); -} -CF_INLINE void __CFDataSetInline(CFDataRef data, Boolean flag) { - __CFRuntimeSetFlag(data, __kCFBytesInline, flag); +CF_INLINE UInt32 __CFMutableVariety(const void *cf) { + return __CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 1, 0); } -CF_INLINE Boolean __CFDataUseAllocator(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFUseAllocator); -} -CF_INLINE void __CFDataSetUseAllocator(CFDataRef data, Boolean flag) { - __CFRuntimeSetFlag(data, __kCFUseAllocator, flag); +CF_INLINE void __CFSetMutableVariety(void *cf, UInt32 v) { + __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 1, 0, v); } -CF_INLINE Boolean __CFDataDontDeallocate(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFDontDeallocate); -} -CF_INLINE void __CFDataSetDontDeallocate(CFDataRef data, Boolean flag) { - __CFRuntimeSetFlag(data, __kCFDontDeallocate, flag); +CF_INLINE UInt32 __CFMutableVarietyFromFlags(UInt32 flags) { + return (flags & __kCFMutableVarietyMask); } -CF_INLINE _CFDataMutableVariety __CFMutableVariety(const void *cf) { - return __CFRuntimeGetValue(cf, 1, 0); -} -CF_INLINE void __CFSetMutableVariety(void *cf, _CFDataMutableVariety v) { - __CFRuntimeSetValue(cf, 1, 0, v); +#define __CFGenericValidateMutabilityFlags(flags) \ + CFAssert2(__CFMutableVarietyFromFlags(flags) != 0x2, __kCFLogAssertion, "%s(): flags 0x%lx do not correctly specify the mutable variety", __PRETTY_FUNCTION__, (unsigned long)flags); + +CF_INLINE void __CFDataSetInline(CFDataRef data, Boolean flag) { + __CFBitfieldSetValue(((CFRuntimeBase *)data)->_cfinfo[CF_INFO_BITS], 2, 2, (flag ? 1 : 0)); } CF_INLINE Boolean __CFDataNeedsToZero(CFDataRef data) { - return __CFRuntimeGetFlag(data, __kCFNeedsZero); + return __CFBitfieldGetValue(((CFRuntimeBase *)data)->_cfinfo[CF_INFO_BITS], 6, 6); } + CF_INLINE void __CFDataSetNeedsToZero(CFDataRef data, Boolean zero) { - __CFRuntimeSetFlag(data, __kCFNeedsZero, zero); + __CFBitfieldSetValue(((CFRuntimeBase *)data)->_cfinfo[CF_INFO_BITS], 6, 6, (zero ? 1 : 0)); } CF_INLINE CFIndex __CFDataLength(CFDataRef data) { @@ -218,15 +201,14 @@ static Boolean __CFDataEqual(CFTypeRef cf1, CFTypeRef cf2) { CFIndex length; length = __CFDataLength(data1); if (length != __CFDataLength(data2)) return false; - const uint8_t *bytePtr1 = _CFDataGetBytePtrNonObjC(data1); - const uint8_t *bytePtr2 = _CFDataGetBytePtrNonObjC(data2); - if (bytePtr1 == bytePtr2) return true; + const uint8_t *bytePtr1 = CFDataGetBytePtr(data1); + const uint8_t *bytePtr2 = CFDataGetBytePtr(data2); return 0 == memcmp(bytePtr1, bytePtr2, length); } static CFHashCode __CFDataHash(CFTypeRef cf) { CFDataRef data = (CFDataRef)cf; - return CFHashBytes((uint8_t *)_CFDataGetBytePtrNonObjC(data), __CFMin(__CFDataLength(data), 80)); + return CFHashBytes((uint8_t *)CFDataGetBytePtr(data), __CFMin(__CFDataLength(data), 80)); } static CFStringRef __CFDataCopyDescription(CFTypeRef cf) { @@ -236,7 +218,7 @@ static CFStringRef __CFDataCopyDescription(CFTypeRef cf) { CFIndex len; const uint8_t *bytes; len = __CFDataLength(data); - bytes = _CFDataGetBytePtrNonObjC(data); + bytes = CFDataGetBytePtr(data); result = CFStringCreateMutable(CFGetAllocator(data), 0); CFStringAppendFormat(result, NULL, CFSTR("{length = %lu, capacity = %lu, bytes = 0x"), cf, CFGetAllocator(data), (unsigned long)len, (unsigned long)__CFDataCapacity(data)); if (24 < len) { @@ -290,7 +272,7 @@ static void *__CFDataAllocate(CFDataRef data, CFIndex size, Boolean clear) { static void __CFDataDeallocate(CFTypeRef cf) { CFMutableDataRef data = (CFMutableDataRef)cf; - if (!__CFDataBytesInline(data) && !__CFDataDontDeallocate(data)) { + if (!__CFDataBytesInline(data) && !__CFDataGetInfoBit(data, __kCFDontDeallocate)) { CFAllocatorRef deallocator = data->_bytesDeallocator; if (deallocator != NULL) { CFAllocatorDeallocate(deallocator, data->_bytes); @@ -327,13 +309,16 @@ CFTypeID CFDataGetTypeID(void) { return __kCFDataTypeID; } -void _CFDataInit(CFMutableDataRef memory, CFOptionFlags variety, CFIndex capacity, const uint8_t *bytes, CFIndex length, Boolean noCopy) { - Boolean isMutable = ((variety & __kCFMutableMask) != 0); - Boolean isGrowable = ((variety & __kCFGrowableMask) != 0); +void _CFDataInit(CFMutableDataRef memory, CFOptionFlags flags, CFIndex capacity, const uint8_t *bytes, CFIndex length, Boolean noCopy) { + Boolean isMutable = ((flags & __kCFMutable) != 0); + Boolean isGrowable = ((flags & __kCFGrowable) != 0); + Boolean isDontDeallocate = ((flags & __kCFDontDeallocate) != 0); __CFDataSetNumBytesUsed(memory, 0); __CFDataSetLength(memory, 0); - __CFDataSetDontDeallocate(memory, true); + if (isDontDeallocate) { + __CFDataSetInfoBits(memory, __kCFDontDeallocate); + } if (isMutable && isGrowable) { __CFDataSetCapacity(memory, __CFDataRoundUpCapacity(1)); @@ -346,14 +331,14 @@ void _CFDataInit(CFMutableDataRef memory, CFOptionFlags variety, CFIndex capacit __CFSetMutableVariety(memory, kCFFixedMutable); } if (noCopy) { - memory->_bytes = (uint8_t *)bytes; + __CFAssignWithWriteBarrier((void **)&memory->_bytes, (uint8_t *)bytes); __CFDataSetNumBytesUsed(memory, length); __CFDataSetLength(memory, length); // Mutable no-copy datas are not allowed, so don't bother setting needsToZero flag. } else { Boolean cleared = (isMutable && !isGrowable && !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)); // assume that allocators give 16-byte aligned memory back -- it is their responsibility - memory->_bytes = __CFDataAllocate(memory, __CFDataNumBytes(memory) * sizeof(uint8_t), cleared); + __CFAssignWithWriteBarrier((void **)&memory->_bytes, __CFDataAllocate(memory, __CFDataNumBytes(memory) * sizeof(uint8_t), cleared)); if (__CFOASafe) __CFSetLastAllocationEventName(memory->_bytes, "CFData (store)"); if (NULL == memory->_bytes) { return; @@ -362,29 +347,25 @@ void _CFDataInit(CFMutableDataRef memory, CFOptionFlags variety, CFIndex capacit __CFDataSetNeedsToZero(memory, !cleared); CFDataReplaceBytes(memory, CFRangeMake(0, 0), bytes, length); } - __CFSetMutableVariety(memory, variety); + __CFSetMutableVariety(memory, __CFMutableVarietyFromFlags(flags)); } -static Boolean __CFDataShouldUseAllocator(CFAllocatorRef allocator) { - CFAllocatorRef const effectiveAllocator = (allocator == kCFAllocatorDefault) ? __CFGetDefaultAllocator() : allocator; - return effectiveAllocator != kCFAllocatorSystemDefault && effectiveAllocator != kCFAllocatorMalloc && effectiveAllocator != kCFAllocatorMallocZone; -} - // NULL bytesDeallocator to this function does not mean the default allocator, it means // that there should be no deallocator, and the bytes should be copied. -static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVariety variety, CFIndex capacity, const uint8_t *bytes, CFIndex length, CFAllocatorRef bytesDeallocator) CF_RETURNS_RETAINED { +static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, CFOptionFlags flags, CFIndex capacity, const uint8_t *bytes, CFIndex length, CFAllocatorRef bytesDeallocator) CF_RETURNS_RETAINED { CFMutableDataRef memory; + __CFGenericValidateMutabilityFlags(flags); CFAssert2(0 <= capacity, __kCFLogAssertion, "%s(): capacity (%ld) cannot be less than zero", __PRETTY_FUNCTION__, capacity); - CFAssert3(kCFFixedMutable != variety || length <= capacity, __kCFLogAssertion, "%s(): for kCFFixedMutable type, capacity (%ld) must be greater than or equal to number of initial elements (%ld)", __PRETTY_FUNCTION__, capacity, length); + CFAssert3(kCFFixedMutable != __CFMutableVarietyFromFlags(flags) || length <= capacity, __kCFLogAssertion, "%s(): for kCFFixedMutable type, capacity (%ld) must be greater than or equal to number of initial elements (%ld)", __PRETTY_FUNCTION__, capacity, length); CFAssert2(0 <= length, __kCFLogAssertion, "%s(): length (%ld) cannot be less than zero", __PRETTY_FUNCTION__, length); Boolean noCopy = bytesDeallocator != NULL; - Boolean isMutable = ((variety & __kCFMutableMask) != 0); - Boolean isGrowable = ((variety & __kCFGrowableMask) != 0); + Boolean isMutable = ((flags & __kCFMutable) != 0); + Boolean isGrowable = ((flags & __kCFGrowable) != 0); Boolean allocateInline = !isGrowable && !noCopy && capacity < INLINE_BYTES_THRESHOLD; allocator = (allocator == NULL) ? __CFGetDefaultAllocator() : allocator; - Boolean useAllocator = __CFDataShouldUseAllocator(allocator); + Boolean useAllocator = (allocator != kCFAllocatorSystemDefault && allocator != kCFAllocatorMalloc && allocator != kCFAllocatorMallocZone); CFIndex size = sizeof(struct __CFData) - sizeof(CFRuntimeBase); if (allocateInline) { @@ -399,8 +380,9 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVar #endif __CFDataSetNumBytesUsed(memory, 0); __CFDataSetLength(memory, 0); - __CFDataSetInline(memory, allocateInline); - __CFDataSetUseAllocator(memory, useAllocator); + __CFDataSetInfoBits(memory, + (allocateInline ? __kCFBytesInline : 0) | + (useAllocator ? __kCFUseAllocator : 0)); if (isMutable && isGrowable) { __CFDataSetCapacity(memory, __CFDataRoundUpCapacity(1)); @@ -441,7 +423,7 @@ static CFMutableDataRef __CFDataInit(CFAllocatorRef allocator, _CFDataMutableVar memory->_bytesDeallocator = NULL; CFDataReplaceBytes(memory, CFRangeMake(0, 0), bytes, length); } - __CFSetMutableVariety(memory, variety); + __CFSetMutableVariety(memory, __CFMutableVarietyFromFlags(flags)); return memory; } @@ -456,30 +438,6 @@ CFDataRef CFDataCreateWithBytesNoCopy(CFAllocatorRef allocator, const uint8_t *b } CFDataRef CFDataCreateCopy(CFAllocatorRef allocator, CFDataRef data) { - Boolean allowRetain = true; - if (allowRetain) { - CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (NSData *)data, copy); - CF_SWIFT_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSObject.copyWithZone, NULL); - - // If the data isn't mutable... - if (!__CFDataIsMutable(data)) { - - // ... and the requested allocator is the same as the data's ... - CFAllocatorRef const effectiveCopyAllocator = __CFDataShouldUseAllocator(allocator) ? allocator : NULL; - CFAllocatorRef const effectiveDataAllocator = __CFDataUseAllocator(data) ? __CFGetAllocator(data) : NULL; - if (effectiveCopyAllocator == effectiveDataAllocator) { - // ... and the buffer is owned by the CFData. - if (__CFDataBytesInline(data) || (data->_bytesDeallocator == NULL)) { - - // Then just retain instead of making a true copy - return CFRetain(data); - - } - } - - } - } - CFIndex length = CFDataGetLength(data); return __CFDataInit(allocator, kCFImmutable, length, CFDataGetBytePtr(data), length, NULL); } @@ -504,26 +462,24 @@ CFIndex CFDataGetLength(CFDataRef data) { return __CFDataLength(data); } -CF_PRIVATE uint8_t *_CFDataGetBytePtrNonObjC(CFDataRef data) { - __CFGenericValidateType(data, CFDataGetTypeID()); - return __CFDataBytesInline(data) ? (uint8_t *)__CFDataInlineBytesPtr(data) : data->_bytes; -} - const uint8_t *CFDataGetBytePtr(CFDataRef data) { CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), const uint8_t *, (NSData *)data, bytes); - return _CFDataGetBytePtrNonObjC(data); + __CFGenericValidateType(data, CFDataGetTypeID()); + // compaction: if inline, always do the computation. + return __CFDataBytesInline(data) ? (uint8_t *)__CFDataInlineBytesPtr(data) : data->_bytes; } uint8_t *CFDataGetMutableBytePtr(CFMutableDataRef data) { CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), uint8_t *, (NSMutableData *)data, mutableBytes); CFAssert1(__CFDataIsMutable(data), __kCFLogAssertion, "%s(): data is immutable", __PRETTY_FUNCTION__); - return _CFDataGetBytePtrNonObjC(data); + // 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_FUNCDISPATCHV(CFDataGetTypeID(), void, (NSData *)data, getBytes:(void *)buffer range:NSMakeRange(range.location, range.length)); __CFDataValidateRange(data, range, __PRETTY_FUNCTION__); - memmove(buffer, _CFDataGetBytePtrNonObjC(data) + range.location, range.length); + memmove(buffer, CFDataGetBytePtr(data) + range.location, range.length); } /* Allocates new block of data with at least numNewValues more bytes than the current length. If clear is true, the new bytes up to at least the new length with be zeroed. */ @@ -549,9 +505,9 @@ static void __CFDataGrow(CFMutableDataRef data, CFIndex numNewValues, Boolean cl // If the calloc/memmove approach either failed or was never attempted, then realloc. allocateCleared = false; if (__CFDataUseAllocator(data)) { - bytes = __CFSafelyReallocateWithAllocator(allocator, oldBytes, numBytes * sizeof(uint8_t), 0, NULL); + bytes = CFAllocatorReallocate(allocator, oldBytes, numBytes * sizeof(uint8_t), 0); } else { - bytes = __CFSafelyReallocate(oldBytes, numBytes * sizeof(uint8_t), NULL); + bytes = realloc(oldBytes, numBytes * sizeof(uint8_t)); } } if (NULL == bytes) __CFDataHandleOutOfMemory(data, numBytes * sizeof(uint8_t)); @@ -587,7 +543,7 @@ void CFDataSetLength(CFMutableDataRef data, CFIndex newLength) { if (newLength > __CFDataCapacity(data)) HALT; } } else if (oldLength < newLength && __CFDataNeedsToZero(data)) { - memset(_CFDataGetBytePtrNonObjC(data) + oldLength, 0, newLength - oldLength); + memset(CFDataGetMutableBytePtr(data) + oldLength, 0, newLength - oldLength); } else if (newLength < oldLength) { __CFDataSetNeedsToZero(data, true); } @@ -627,7 +583,7 @@ void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *new CFIndex newCount = len - range.length + newLength; if (newCount < 0) HALT; - uint8_t *bytePtr = _CFDataGetBytePtrNonObjC(data); + uint8_t *bytePtr = (uint8_t *)CFDataGetMutableBytePtr(data); uint8_t *srcBuf = (uint8_t *)newBytes; switch (__CFMutableVariety(data)) { case kCFMutable: @@ -637,7 +593,7 @@ void CFDataReplaceBytes(CFMutableDataRef data, CFRange range, const uint8_t *new memmove(srcBuf, newBytes, newLength * sizeof(uint8_t)); } __CFDataGrow(data, newLength - range.length, false); - bytePtr = _CFDataGetBytePtrNonObjC(data); + bytePtr = (uint8_t *)CFDataGetMutableBytePtr(data); } break; case kCFFixedMutable: @@ -705,30 +661,13 @@ static void _computeGoodSubstringShift(const uint8_t *needle, int needleLength, } } -#define new_ulong_array(N, C) \ - size_t N ## _count__ = (C); \ - if (N ## _count__ > LONG_MAX / sizeof(unsigned long)) { \ - __CFDataHandleOutOfMemory(data, (N ## _count__) * sizeof(unsigned long)); \ - } \ - Boolean N ## _is_stack__ = (N ## _count__ <= 256); \ - if (N ## _count__ == 0) N ## _count__ = 1; \ - STACK_BUFFER_DECL(unsigned long, N ## _buffer__, N ## _is_stack__ ? N ## _count__ : 1); \ - unsigned long * N = N ## _is_stack__ ? N ## _buffer__ : (unsigned long *)malloc((N ## _count__) * sizeof(unsigned long)); \ - if (! N) { \ - __CFDataHandleOutOfMemory(data, (N ## _count__) * sizeof(unsigned long)); \ - } \ - do {} while (0) - -#define free_ulong_array(N) \ - if (! N ## _is_stack__) { \ - free(N); \ - } \ - do {} while (0) - static const uint8_t * __CFDataSearchBoyerMoore(const CFDataRef data, const uint8_t *haystack, unsigned long haystackLength, const uint8_t *needle, unsigned long needleLength, Boolean backwards) { unsigned long badCharacterShift[UCHAR_MAX + 1] = {0}; - new_ulong_array(goodSubstringShift, needleLength); - new_ulong_array(suffixLengths, needleLength); + unsigned long *goodSubstringShift = (unsigned long *)malloc(needleLength * sizeof(unsigned long)); + unsigned long *suffixLengths = (unsigned long *)malloc(needleLength * sizeof(unsigned long)); + if (!goodSubstringShift || !suffixLengths) { + __CFDataHandleOutOfMemory(data, needleLength * sizeof(unsigned long)); + } if(backwards) { for (int i = 0; i < sizeof(badCharacterShift) / sizeof(*badCharacterShift); i++) @@ -794,8 +733,8 @@ static const uint8_t * __CFDataSearchBoyerMoore(const CFDataRef data, const uint } } - free_ulong_array(goodSubstringShift); - free_ulong_array(suffixLengths); + free(goodSubstringShift); + free(suffixLengths); return result; } @@ -839,6 +778,7 @@ CFRange CFDataFind(CFDataRef data, CFDataRef dataToFind, CFRange searchRange, CF } #undef __CFDataValidateRange +#undef __CFGenericValidateMutabilityFlags #undef INLINE_BYTES_THRESHOLD #undef CFDATA_MAX_SIZE #undef REVERSE_BUFFER diff --git a/CoreFoundation/Collections.subproj/CFData.h b/CoreFoundation/Collections.subproj/CFData.h index 2d8edd4533..ea35587bb1 100644 --- a/CoreFoundation/Collections.subproj/CFData.h +++ b/CoreFoundation/Collections.subproj/CFData.h @@ -1,7 +1,7 @@ /* CFData.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -67,10 +67,10 @@ void CFDataDeleteBytes(CFMutableDataRef theData, CFRange range); typedef CF_OPTIONS(CFOptionFlags, CFDataSearchFlags) { kCFDataSearchBackwards = 1UL << 0, kCFDataSearchAnchored = 1UL << 1 -} API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_6, 4_0); CF_EXPORT -CFRange CFDataFind(CFDataRef theData, CFDataRef dataToFind, CFRange searchRange, CFDataSearchFlags compareOptions) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFRange CFDataFind(CFDataRef theData, CFDataRef dataToFind, CFRange searchRange, CFDataSearchFlags compareOptions) CF_AVAILABLE(10_6, 4_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Collections.subproj/CFDictionary.c b/CoreFoundation/Collections.subproj/CFDictionary.c index f82c32e5e5..053b9a4d98 100644 --- a/CoreFoundation/Collections.subproj/CFDictionary.c +++ b/CoreFoundation/Collections.subproj/CFDictionary.c @@ -1,7 +1,7 @@ /* CFDictionary.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -402,10 +402,7 @@ void CFDictionaryGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { #endif #if CFDictionary if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); -#pragma GCC diagnostic pop #endif #if CFSet if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFDictionaryGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); @@ -469,11 +466,11 @@ CF_EXPORT void _CFDictionarySetCapacity(CFMutableHashRef hc, CFIndex cap) { } CF_INLINE CFIndex __CFDictionaryGetKVOBit(CFHashRef hc) { - return __CFRuntimeGetFlag(hc, 0); + return __CFBitfieldGetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0); } CF_INLINE void __CFDictionarySetKVOBit(CFHashRef hc, CFIndex bit) { - __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); + __CFBitfieldSetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0, ((uintptr_t)bit & 0x1)); } // This function is for Foundation's benefit; no one else should use it. diff --git a/CoreFoundation/Collections.subproj/CFDictionary.h b/CoreFoundation/Collections.subproj/CFDictionary.h index 94035c0db7..de90bad5f6 100644 --- a/CoreFoundation/Collections.subproj/CFDictionary.h +++ b/CoreFoundation/Collections.subproj/CFDictionary.h @@ -1,7 +1,7 @@ /* CFDictionary.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFSet.c b/CoreFoundation/Collections.subproj/CFSet.c index 7ff89cf54a..174d64bd59 100644 --- a/CoreFoundation/Collections.subproj/CFSet.c +++ b/CoreFoundation/Collections.subproj/CFSet.c @@ -1,7 +1,7 @@ /* CFSet.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -402,10 +402,7 @@ void CFSetGetValues(CFHashRef hc, const_any_pointer_t *keybuf) { #endif #if CFDictionary if (CFDictionary) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSDictionary.getObjects, valuebuf, keybuf); -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated" if (CFDictionary) CF_OBJC_FUNCDISPATCHV(CFSetGetTypeID(), void, (NSDictionary *)hc, getObjects:(id *)valuebuf andKeys:(id *)keybuf); -#pragma GCC diagnostic pop #endif #if CFSet if (CFSet) CF_SWIFT_FUNCDISPATCHV(CFSetGetTypeID(), void, (CFSwiftRef)hc, NSSet.getObjects, keybuf); @@ -469,11 +466,11 @@ CF_EXPORT void _CFSetSetCapacity(CFMutableHashRef hc, CFIndex cap) { } CF_INLINE CFIndex __CFSetGetKVOBit(CFHashRef hc) { - return __CFRuntimeGetFlag(hc, 0); + return __CFBitfieldGetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0); } CF_INLINE void __CFSetSetKVOBit(CFHashRef hc, CFIndex bit) { - __CFRuntimeSetFlag(hc, 0, ((uintptr_t)bit & 0x1)); + __CFBitfieldSetValue(((CFRuntimeBase *)hc)->_cfinfo[CF_INFO_BITS], 0, 0, ((uintptr_t)bit & 0x1)); } // This function is for Foundation's benefit; no one else should use it. diff --git a/CoreFoundation/Collections.subproj/CFSet.h b/CoreFoundation/Collections.subproj/CFSet.h index b22d81557a..3741f4d250 100644 --- a/CoreFoundation/Collections.subproj/CFSet.h +++ b/CoreFoundation/Collections.subproj/CFSet.h @@ -1,7 +1,7 @@ /* CFSet.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFStorage.c b/CoreFoundation/Collections.subproj/CFStorage.c index 82843344ca..bdea2e68d7 100644 --- a/CoreFoundation/Collections.subproj/CFStorage.c +++ b/CoreFoundation/Collections.subproj/CFStorage.c @@ -1,7 +1,7 @@ /* CFStorage.c - Copyright (c) 1999-2017, Apple Inc. All rights reserved. + Copyright (c) 1999-2016, Apple Inc. All rights reserved. - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -134,7 +134,7 @@ CF_INLINE void __CFStorageAllocLeafNodeMemory(CFAllocatorRef allocator, CFStorag __CFLock(&(storage->cacheReaderMemoryAllocationLock)); /* Check again now that we've acquired the lock. We know that we can do this because two simulaneous readers will always pass the same capacity. This is the fix for 8203146. This probably needs a memory barrier. */ if ((compact ? (cap != node->info.leaf.capacityInBytes) : (cap > node->info.leaf.capacityInBytes))) { - *((void **)&node->info.leaf.memory) = __CFSafelyReallocateWithAllocator(allocator, node->info.leaf.memory, cap, 0, NULL); // This will free... + *((void **)&node->info.leaf.memory) = CFAllocatorReallocate(allocator, node->info.leaf.memory, cap, 0); // This will free... if (__CFOASafe) __CFSetLastAllocationEventName(node->info.leaf.memory, "CFStorage (node bytes)"); node->info.leaf.capacityInBytes = cap; } diff --git a/CoreFoundation/Collections.subproj/CFStorage.h b/CoreFoundation/Collections.subproj/CFStorage.h index d35868b3d3..9baf3fb4f8 100644 --- a/CoreFoundation/Collections.subproj/CFStorage.h +++ b/CoreFoundation/Collections.subproj/CFStorage.h @@ -1,7 +1,7 @@ /* CFStorage.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Collections.subproj/CFTree.c b/CoreFoundation/Collections.subproj/CFTree.c index 0b2e42c431..673491b3a1 100644 --- a/CoreFoundation/Collections.subproj/CFTree.c +++ b/CoreFoundation/Collections.subproj/CFTree.c @@ -1,7 +1,7 @@ /* CFTree.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -41,7 +41,7 @@ enum { /* Bits 0-1 */ }; CF_INLINE uint32_t __CFTreeGetCallBacksType(CFTreeRef tree) { - return (__CFRuntimeGetValue(tree, 1, 0)); + return (__CFBitfieldGetValue(tree->_base._cfinfo[CF_INFO_BITS], 1, 0)); } CF_INLINE const struct __CFTreeCallBacks *__CFTreeGetCallBacks(CFTreeRef tree) { @@ -137,7 +137,7 @@ CFTreeRef CFTreeCreate(CFAllocatorRef allocator, const CFTreeContext *context) { memory->_rightmostChild = NULL; /* Start the context off in a recognizable state */ - __CFRuntimeSetValue(memory, 1, 0, __kCFTreeHasNullCallBacks); + __CFBitfieldSetValue(memory->_base._cfinfo[CF_INFO_BITS], 1, 0, __kCFTreeHasNullCallBacks); CFTreeSetContext(memory, context); return memory; } @@ -213,7 +213,7 @@ void CFTreeSetContext(CFTreeRef tree, const CFTreeContext *context) { FAULT_CALLBACK((void **)&(tree->_callbacks->release)); FAULT_CALLBACK((void **)&(tree->_callbacks->copyDescription)); } - __CFRuntimeSetValue(tree, 1, 0, newtype); + __CFBitfieldSetValue(tree->_base._cfinfo[CF_INFO_BITS], 1, 0, newtype); newcb = (struct __CFTreeCallBacks *)__CFTreeGetCallBacks(tree); if (NULL != newcb->retain) { tree->_info = (void *)INVOKE_CALLBACK1(newcb->retain, context->info); diff --git a/CoreFoundation/Collections.subproj/CFTree.h b/CoreFoundation/Collections.subproj/CFTree.h index 7aaf4f1bcc..6ba9312b6c 100644 --- a/CoreFoundation/Collections.subproj/CFTree.h +++ b/CoreFoundation/Collections.subproj/CFTree.h @@ -1,7 +1,7 @@ /* CFTree.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -192,6 +192,7 @@ CFTreeRef CFTreeGetChildAtIndex(CFTreeRef tree, CFIndex idx); @param children A C array of pointer-sized values to be filled with children from the tree. If this parameter is not a valid pointer to a C array of at least CFTreeGetChildCount() pointers, the behavior is undefined. + @result A reference to the specified child tree. */ CF_EXPORT void CFTreeGetChildren(CFTreeRef tree, CFTreeRef *children); @@ -201,7 +202,7 @@ void CFTreeGetChildren(CFTreeRef tree, CFTreeRef *children); Calls a function once for each child of the tree. Note that the applier only operates one level deep, and does not operate on descendents further removed than the immediate children of the tree. - @param tree The tree to be operated upon. If this parameter is not a + @param heap The tree to be operated upon. If this parameter is not a valid CFTree, the behavior is undefined. @param applier The callback function to call once for each child of the given tree. If this parameter is not a pointer to a diff --git a/CoreFoundation/Error.subproj/CFError.c b/CoreFoundation/Error.subproj/CFError.c index 8a9b2133a9..a89ea52730 100644 --- a/CoreFoundation/Error.subproj/CFError.c +++ b/CoreFoundation/Error.subproj/CFError.c @@ -1,7 +1,7 @@ /* CFError.c - Copyright (c) 2006-2017, Apple Inc. and the Swift project authors + Copyright (c) 2006-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -29,7 +29,6 @@ /* Pre-defined userInfo keys */ CONST_STRING_DECL(kCFErrorLocalizedDescriptionKey, "NSLocalizedDescription"); -CONST_STRING_DECL(kCFErrorLocalizedFailureKey, "NSLocalizedFailure"); CONST_STRING_DECL(kCFErrorLocalizedFailureReasonKey, "NSLocalizedFailureReason"); CONST_STRING_DECL(kCFErrorLocalizedRecoverySuggestionKey, "NSLocalizedRecoverySuggestion"); CONST_STRING_DECL(kCFErrorDescriptionKey, "NSDescription"); @@ -174,10 +173,17 @@ static CFDictionaryRef _CFErrorCreateEmptyDictionary(CFAllocatorRef allocator) { if (allocator == NULL) allocator = __CFGetDefaultAllocator(); if (_CFAllocatorIsSystemDefault(allocator)) { static CFDictionaryRef emptyErrorDictionary = NULL; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - emptyErrorDictionary = CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - }); + if (emptyErrorDictionary == NULL) { + CFDictionaryRef tmp = CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + __CFLock(&_CFErrorSpinlock); + if (emptyErrorDictionary == NULL) { + emptyErrorDictionary = tmp; + __CFUnlock(&_CFErrorSpinlock); + } else { + __CFUnlock(&_CFErrorSpinlock); + CFRelease(tmp); + } + } return (CFDictionaryRef)CFRetain(emptyErrorDictionary); } else { return CFDictionaryCreate(allocator, NULL, NULL, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); @@ -192,82 +198,43 @@ static CFDictionaryRef _CFErrorGetUserInfo(CFErrorRef err) { return err->userInfo; } -/* Retrieve the value for the error key from the userInfo dictionary only - */ -static CFStringRef _CFErrorCopyUserInfoKeyFromUserInfo(CFErrorRef err, CFStringRef key) { +/* This function retrieves the value of the specified key from the userInfo, or from the callback. It works with a CF or NSError. +*/ +static CFStringRef _CFErrorCopyUserInfoKey(CFErrorRef err, CFStringRef key) { CFStringRef result = NULL; + // First consult the userInfo dictionary CFDictionaryRef userInfo = _CFErrorGetUserInfo(err); - if (userInfo) { - result = (CFStringRef)CFDictionaryGetValue(userInfo, key); - if (result) CFRetain(result); - } - return result; -} - -/* Retrieve the value for the error key from the callback only - */ -static CFStringRef _CFErrorCopyUserInfoKeyFromCallBack(CFErrorRef err, CFStringRef key) { - CFStringRef result = NULL; + if (userInfo) result = (CFStringRef)CFDictionaryGetValue(userInfo, key); + // If that doesn't work, consult the callback + if (result) { + CFRetain(result); + } else { #if USES_CALLBACK_BLOCKS - CFErrorUserInfoKeyCallBackBlock callBackBlock = CFErrorCopyCallBackBlockForDomain(CFErrorGetDomain(err)); - if (callBackBlock) { - result = (CFStringRef)callBackBlock(err, key); - if (result) CFRetain(result); - CFRelease(callBackBlock); - } + CFErrorUserInfoKeyCallBackBlock callBackBlock = CFErrorGetCallBackBlockForDomain(CFErrorGetDomain(err)); + if (callBackBlock) { + result = (CFStringRef)callBackBlock(err, key); + if (result) CFRetain(result); + } #endif + } return result; } -/* This function retrieves the value of the specified key from the userInfo, or from the callback. It works with a CF or NSError. -*/ -static CFStringRef _CFErrorCopyUserInfoKey(CFErrorRef err, CFStringRef key) { - CFStringRef result = _CFErrorCopyUserInfoKeyFromUserInfo(err, key); - if (!result) result = _CFErrorCopyUserInfoKeyFromCallBack(err, key); - return result; -} - - -/* The real guts of the localized description creation functionality. See the header file comments for -localizedDescription for the steps this function goes through to compute the description. This function can take a CF or NSError. It's called by NSError for the localizedDescription computation. +/* The real guts of the localized description creation functionality. See the header file comments for CFErrorCopyDescription() or -localizedDescription for the steps this function goes through to compute the description. This function can take a CF or NSError. It's called by NSError for the localizedDescription computation. */ CFStringRef _CFErrorCreateLocalizedDescription(CFErrorRef err) { - // We first do two passes for kCFErrorLocalizedDescriptionKey and kCFErrorLocalizedFailureKey, first looking in userInfo, then callback. - // This two-pass approach allows an entry in the userInfo for either one to override the (presumably more generic) entry from the callback. - for (int pass = 0; pass < 2; pass++) { - CFStringRef (*keyLookupFunc)(CFErrorRef, CFStringRef) = ((pass == 0) ? _CFErrorCopyUserInfoKeyFromUserInfo : _CFErrorCopyUserInfoKeyFromCallBack); - - // First look for kCFErrorLocalizedDescriptionKey; if non-NULL, return that as-is - CFStringRef localizedDesc = (keyLookupFunc)(err, kCFErrorLocalizedDescriptionKey); - if (localizedDesc) return localizedDesc; - - // If a we have kCFErrorLocalizedFailureKey, use it, in conjunction with kCFErrorLocalizedFailureReasonKey if we have that, otherwise by itself - CFStringRef failure = (keyLookupFunc)(err, kCFErrorLocalizedFailureKey); - if (failure) { - CFStringRef reason = _CFErrorCopyUserInfoKey(err, kCFErrorLocalizedFailureReasonKey); // This can come from userInfo or callback - if (reason) { - CFStringRef const backstopComboString = CFSTR("%@ %@"); - CFStringRef comboString = backstopComboString; -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS - CFBundleRef cfBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreFoundation")); - if (cfBundle) comboString = CFCopyLocalizedStringFromTableInBundle(CFSTR("%@ %@"), CFSTR("Error"), cfBundle, "Used for presenting the 'what failed' and 'why it failed' sections of an error message, where each one is one or more complete sentences. The first %@ corresponds to the 'what failed' (For instance 'The file could not be saved.') and the second one 'why it failed' (For instance 'The volume is out of space.')"); -#endif - CFStringRef result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, comboString, failure, reason); - if (comboString && comboString != backstopComboString) CFRelease(comboString); - CFRelease(failure); - CFRelease(reason); - return result; - } else { - return failure; - } - } - } - + // First look for kCFErrorLocalizedDescriptionKey; if non-NULL, return that as-is. + CFStringRef localizedDesc = _CFErrorCopyUserInfoKey(err, kCFErrorLocalizedDescriptionKey); + if (localizedDesc) return localizedDesc; + #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS - // Cache the CF bundle since we will be using it for localized strings. Note that for platforms without bundle support we also go this non-localized route. + // Cache the CF bundle since we will be using it for localized strings. CFBundleRef cfBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.CoreFoundation")); + if (!cfBundle) { // This should be rare, but has been observed in the wild, due to running out of file descriptors. Normally we might not go to such extremes, but since we want to be able to present reasonable errors even in the case of errors such as running out of file descriptors, why not. This is CFError after all. !!! Be sure to have the same logic here as below for going through various options for fetching the strings. #endif - CFStringRef result = NULL, reasonOrDesc; + + CFStringRef result = NULL, reasonOrDesc; if ((reasonOrDesc = _CFErrorCopyUserInfoKey(err, kCFErrorLocalizedFailureReasonKey))) { // First look for kCFErrorLocalizedFailureReasonKey result = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("The operation couldn\\U2019t be completed. %@"), reasonOrDesc); @@ -280,7 +247,9 @@ CFStringRef _CFErrorCreateLocalizedDescription(CFErrorRef err) { return result; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS } - +#endif + +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS // Then look for kCFErrorLocalizedFailureReasonKey; if there, create a full sentence from that. CFStringRef reason = _CFErrorCopyUserInfoKey(err, kCFErrorLocalizedFailureReasonKey); if (reason) { @@ -544,7 +513,6 @@ static CFTypeRef _CFErrorMachCallBack(CFErrorRef err, CFStringRef key) CF_RETURN static const void *blockCopyValueCallBack(CFAllocatorRef allocator, const void *value) {return _Block_copy(value);} static void blockReleaseValueCallBack(CFAllocatorRef allocator, const void *value) {_Block_release(value);} -static void __CFErrorSetCallBackForDomainNoLock(CFStringRef domainName, CFErrorUserInfoKeyCallBack callBack); /* This initialize function is meant to be called lazily, the first time a callback is registered or requested. It creates the table and registers the built-in callbacks. Clearly doing this non-lazily in _CFErrorInitialize() would be simpler, but this is a fine example of something that should not have to happen at launch time. */ @@ -558,16 +526,16 @@ static void _CFErrorInitializeCallBackTable(void) { __CFLock(&_CFErrorSpinlock); if (!_CFErrorCallBackTable) { _CFErrorCallBackTable = table; - // Register the known providers, going thru a special variant of the function that doesn't lock - __CFErrorSetCallBackForDomainNoLock(kCFErrorDomainPOSIX, _CFErrorPOSIXCallBack); -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED - __CFErrorSetCallBackForDomainNoLock(kCFErrorDomainMach, _CFErrorMachCallBack); -#endif __CFUnlock(&_CFErrorSpinlock); } else { __CFUnlock(&_CFErrorSpinlock); CFRelease(table); + // Note, even though the table looks like it was initialized, we go on to register the items on this thread as well, since otherwise we might consult the table before the items are actually registered. } + CFErrorSetCallBackForDomain(kCFErrorDomainPOSIX, _CFErrorPOSIXCallBack); +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED + CFErrorSetCallBackForDomain(kCFErrorDomainMach, _CFErrorMachCallBack); +#endif } void CFErrorSetCallBackBlockForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBackBlock block) { @@ -589,29 +557,24 @@ CFErrorUserInfoKeyCallBackBlock CFErrorGetCallBackBlockForDomain(CFStringRef dom return callBack; } -CFErrorUserInfoKeyCallBackBlock CFErrorCopyCallBackBlockForDomain(CFStringRef domainName) { - if (!_CFErrorCallBackTable) _CFErrorInitializeCallBackTable(); - __CFLock(&_CFErrorSpinlock); - CFErrorUserInfoKeyCallBackBlock callBack = _CFErrorCallBackTable ? (CFErrorUserInfoKeyCallBackBlock)CFDictionaryGetValue(_CFErrorCallBackTable, domainName) : NULL; - if (callBack) CFRetain(callBack); - __CFUnlock(&_CFErrorSpinlock); - return callBack; -} - -// This is meant to be called only with _CFErrorSpinlock taken and with _CFErrorCallBackTable already created -static void __CFErrorSetCallBackForDomainNoLock(CFStringRef domainName, CFErrorUserInfoKeyCallBack callBack) { - // Since we have replaced the callback functionality with a callback block functionality, we register callback function embedded in a block which autoreleases the result - if (callBack) { - CFErrorUserInfoKeyCallBackBlock block = ^(CFErrorRef err, CFStringRef key){ - CFTypeRef result = callBack(err, key); +void CFErrorSetCallBackForDomain(CFStringRef domainName, CFErrorUserInfoKeyCallBack callBack) { + // Since we have replaced the callback functionality with a callback block functionality, we now register (legacy) callback functions embedded in a block which autoreleases the result + CFErrorUserInfoKeyCallBackBlock block = (!callBack) ? NULL : ^(CFErrorRef err, CFStringRef key){ + CFTypeRef result = callBack(err, key); #if !DEPLOYMENT_RUNTIME_SWIFT - if (result) CFAutorelease(result); + if (result) CFAutorelease(result); #endif - return result; - }; - CFDictionarySetValue(_CFErrorCallBackTable, domainName, (void *)block); - } else { - CFDictionaryRemoveValue(_CFErrorCallBackTable, domainName); - } + return result; + }; + CFErrorSetCallBackBlockForDomain(domainName, block); +} + +CFErrorUserInfoKeyCallBack CFErrorGetCallBackForDomain(CFStringRef domainName) { + // Since there were no callers other than CF, removed as of 10.11/iOS9 + // Otherwise would have had to have separate tables for callback functions and blocks + return NULL; } + + + diff --git a/CoreFoundation/Error.subproj/CFError.h b/CoreFoundation/Error.subproj/CFError.h index 8f36f41efc..1d01fdc051 100644 --- a/CoreFoundation/Error.subproj/CFError.h +++ b/CoreFoundation/Error.subproj/CFError.h @@ -1,7 +1,7 @@ /* CFError.h - Copyright (c) 2006-2017, Apple Inc. and the Swift project authors + Copyright (c) 2006-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -54,28 +54,27 @@ typedef struct CF_BRIDGED_TYPE(NSError) __CFError * CFErrorRef; Returns the type identifier of all CFError instances. */ CF_EXPORT -CFTypeID CFErrorGetTypeID(void) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFTypeID CFErrorGetTypeID(void) CF_AVAILABLE(10_5, 2_0); // Predefined domains; value of "code" will correspond to preexisting values in these domains. -CF_EXPORT const CFErrorDomain kCFErrorDomainPOSIX API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFErrorDomain kCFErrorDomainOSStatus API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFErrorDomain kCFErrorDomainMach API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFErrorDomain kCFErrorDomainCocoa API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFErrorDomain kCFErrorDomainPOSIX CF_AVAILABLE(10_5, 2_0); +CF_EXPORT const CFErrorDomain kCFErrorDomainOSStatus CF_AVAILABLE(10_5, 2_0); +CF_EXPORT const CFErrorDomain kCFErrorDomainMach CF_AVAILABLE(10_5, 2_0); +CF_EXPORT const CFErrorDomain kCFErrorDomainCocoa CF_AVAILABLE(10_5, 2_0); -// Keys in userInfo for localizable, end-user presentable error messages. At minimum provide kCFErrorLocalizedDescriptionKey, or add kCFErrorLocalizedFailureKey into errors generated by lower levels to have it combine with kCFErrorLocalizedFailureReasonKey. -CF_EXPORT const CFStringRef kCFErrorLocalizedDescriptionKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // Key to identify the end user-presentable description in userInfo. Should be one or more complete sentence(s) describing both what failed and why. For instance 'You can't save the file "To Do List" because the volume "Macintosh HD" is out of space.' -CF_EXPORT const CFStringRef kCFErrorLocalizedFailureKey API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); // Key to identify the end user-presentable failing operation ("what failed") description in userInfo. Should be one or more complete sentence(s), for instance 'The file "To Do List" couldn't be saved.' -CF_EXPORT const CFStringRef kCFErrorLocalizedFailureReasonKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // Key to identify the end user-presentable failure reason ("why it failed") description in userInfo. Should be one or more complete sentence(s), for instance 'The volume "Macintosh HD" is out of space.' -CF_EXPORT const CFStringRef kCFErrorLocalizedRecoverySuggestionKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // Key to identify the end user-presentable recovery suggestion in userInfo. Should be one or more complete sentence(s), for instance 'Remove some files from the volume, and then try again.' +// Keys in userInfo for localizable, end-user presentable error messages. At minimum provide one of first two; ideally provide all three. +CF_EXPORT const CFStringRef kCFErrorLocalizedDescriptionKey CF_AVAILABLE(10_5, 2_0); // Key to identify the end user-presentable description in userInfo. +CF_EXPORT const CFStringRef kCFErrorLocalizedFailureReasonKey CF_AVAILABLE(10_5, 2_0); // Key to identify the end user-presentable failure reason in userInfo. +CF_EXPORT const CFStringRef kCFErrorLocalizedRecoverySuggestionKey CF_AVAILABLE(10_5, 2_0); // Key to identify the end user-presentable recovery suggestion in userInfo. // If you do not have localizable error strings, you can provide a value for this key instead. -CF_EXPORT const CFStringRef kCFErrorDescriptionKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // Key to identify the description in the userInfo dictionary. Should be a complete sentence if possible. Should not contain domain name or error code. +CF_EXPORT const CFStringRef kCFErrorDescriptionKey CF_AVAILABLE(10_5, 2_0); // Key to identify the description in the userInfo dictionary. Should be a complete sentence if possible. Should not contain domain name or error code. // Other keys in userInfo. -CF_EXPORT const CFStringRef kCFErrorUnderlyingErrorKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // Key to identify the underlying error in userInfo. -CF_EXPORT const CFStringRef kCFErrorURLKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); // Key to identify associated URL in userInfo. Typically one of this or kCFErrorFilePathKey is provided. -CF_EXPORT const CFStringRef kCFErrorFilePathKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); // Key to identify associated file path in userInfo. Typically one of this or kCFErrorURLKey is provided. +CF_EXPORT const CFStringRef kCFErrorUnderlyingErrorKey CF_AVAILABLE(10_5, 2_0); // Key to identify the underlying error in userInfo. +CF_EXPORT const CFStringRef kCFErrorURLKey CF_AVAILABLE(10_7, 5_0); // Key to identify associated URL in userInfo. Typically one of this or kCFErrorFilePathKey is provided. +CF_EXPORT const CFStringRef kCFErrorFilePathKey CF_AVAILABLE(10_7, 5_0); // Key to identify associated file path in userInfo. Typically one of this or kCFErrorURLKey is provided. /*! @@ -90,7 +89,7 @@ CF_EXPORT const CFStringRef kCFErrorFilePathKey API_AVAILABL @result A reference to the new CFError. */ CF_EXPORT -CFErrorRef CFErrorCreate(CFAllocatorRef allocator, CFErrorDomain domain, CFIndex code, CFDictionaryRef userInfo) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFErrorRef CFErrorCreate(CFAllocatorRef allocator, CFErrorDomain domain, CFIndex code, CFDictionaryRef userInfo) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorCreateWithUserInfoKeysAndValues @@ -105,7 +104,7 @@ CFErrorRef CFErrorCreate(CFAllocatorRef allocator, CFErrorDomain domain, CFIndex @result A reference to the new CFError. numUserInfoValues CF types are gathered from each of userInfoKeys and userInfoValues to create the userInfo dictionary. */ CF_EXPORT -CFErrorRef CFErrorCreateWithUserInfoKeysAndValues(CFAllocatorRef allocator, CFErrorDomain domain, CFIndex code, const void *const *userInfoKeys, const void *const *userInfoValues, CFIndex numUserInfoValues) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFErrorRef CFErrorCreateWithUserInfoKeysAndValues(CFAllocatorRef allocator, CFErrorDomain domain, CFIndex code, const void *const *userInfoKeys, const void *const *userInfoValues, CFIndex numUserInfoValues) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorGetDomain @@ -114,7 +113,7 @@ CFErrorRef CFErrorCreateWithUserInfoKeysAndValues(CFAllocatorRef allocator, CFEr @result The error domain of the CFError. Since this is a "Get" function, the caller shouldn't CFRelease the return value. */ CF_EXPORT -CFErrorDomain CFErrorGetDomain(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFErrorDomain CFErrorGetDomain(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorGetCode @@ -123,7 +122,7 @@ CFErrorDomain CFErrorGetDomain(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2. @result The error code of the CFError (not an error return for the current call). */ CF_EXPORT -CFIndex CFErrorGetCode(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFIndex CFErrorGetCode(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorCopyUserInfo @@ -133,22 +132,21 @@ CFIndex CFErrorGetCode(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watc @result The user info of the CFError. */ CF_EXPORT -CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFDictionaryRef CFErrorCopyUserInfo(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorCopyDescription @abstract Returns a human-presentable description for the error. CFError creators should strive to make sure the return value is human-presentable and localized by providing a value for kCFErrorLocalizedDescriptionKey at the time of CFError creation. - @discussion This is a complete sentence or two which says what failed and why it failed. Please refer to header comments for -[NSError localizedDescription] for details on the steps used to compute this; but roughly: - - Use value of kCFErrorLocalizedDescriptionKey as-is if provided. - - Use value of kCFErrorLocalizedFailureKey if provided, optionally followed by kCFErrorLocalizedFailureReasonKey if available. - - Use value of kCFErrorLocalizedFailureReasonKey, combining with a generic failure message such as: "Operation code not be completed. " + kCFErrorLocalizedFailureReasonKey. - - If all of the above fail, generate a semi-user presentable string from kCFErrorDescriptionKey, the domain, and code. Something like: "Operation could not be completed. Error domain/code occurred. " or "Operation could not be completed. " + kCFErrorDescriptionKey + " (Error domain/code)" + @discussion This is a complete sentence or two which says what failed and why it failed. Rules for computing the return value: + - Look for kCFErrorLocalizedDescriptionKey in the user info and if not NULL, returns that as-is. + - Otherwise, if there is a kCFErrorLocalizedFailureReasonKey in the user info, generate an error from that. Something like: "Operation code not be completed. " + kCFErrorLocalizedFailureReasonKey + - Otherwise, generate a semi-user presentable string from kCFErrorDescriptionKey, the domain, and code. Something like: "Operation could not be completed. Error domain/code occurred. " or "Operation could not be completed. " + kCFErrorDescriptionKey + " (Error domain/code)" Toll-free bridged NSError instances might provide additional behaviors for manufacturing a description string. Do not count on the exact contents or format of the returned string, it might change. @param err The CFError whose description is to be returned. If this reference is not a valid CFError, the behavior is undefined. @result A CFString with human-presentable description of the CFError. Never NULL. */ CF_EXPORT -CFStringRef CFErrorCopyDescription(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFStringRef CFErrorCopyDescription(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorCopyFailureReason @@ -160,7 +158,7 @@ CFStringRef CFErrorCopyDescription(CFErrorRef err) API_AVAILABLE(macos(10.5), io @result A CFString with the localized, end-user presentable failure reason of the CFError, or NULL. */ CF_EXPORT -CFStringRef CFErrorCopyFailureReason(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFStringRef CFErrorCopyFailureReason(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); /*! @function CFErrorCopyRecoverySuggestion @@ -172,7 +170,7 @@ CFStringRef CFErrorCopyFailureReason(CFErrorRef err) API_AVAILABLE(macos(10.5), @result A CFString with the localized, end-user presentable recovery suggestion of the CFError, or NULL. */ CF_EXPORT -CFStringRef CFErrorCopyRecoverySuggestion(CFErrorRef err) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFStringRef CFErrorCopyRecoverySuggestion(CFErrorRef err) CF_AVAILABLE(10_5, 2_0); diff --git a/CoreFoundation/Error.subproj/CFError_Private.h b/CoreFoundation/Error.subproj/CFError_Private.h index db4eaf3dfd..50a7e04c27 100644 --- a/CoreFoundation/Error.subproj/CFError_Private.h +++ b/CoreFoundation/Error.subproj/CFError_Private.h @@ -1,7 +1,7 @@ /* CFError_Private.h - Copyright (c) 2006-2017, Apple Inc. and the Swift project authors + Copyright (c) 2006-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -19,7 +19,8 @@ CF_EXTERN_C_BEGIN /* A key for "true" debugging descriptions which should never be shown to the user. It's only used when the CFError is shown to the console, and nothing else is available. For instance the rather terse and techie OSStatus descriptions are in this boat. */ -CF_EXPORT const CFStringRef kCFErrorDebugDescriptionKey API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFErrorDebugDescriptionKey CF_AVAILABLE(10_5, 2_0); + CF_EXTERN_C_END diff --git a/CoreFoundation/Locale.subproj/CFCalendar.c b/CoreFoundation/Locale.subproj/CFCalendar.c index b47a692645..1c18bc782b 100644 --- a/CoreFoundation/Locale.subproj/CFCalendar.c +++ b/CoreFoundation/Locale.subproj/CFCalendar.c @@ -1,7 +1,7 @@ /* CFCalendar.c - Copyright (c) 2004-2017, Apple Inc. and the Swift project authors + Copyright (c) 2004-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -56,12 +56,12 @@ static CFTypeID __kCFCalendarTypeID = _kCFRuntimeNotATypeID; static const CFRuntimeClass __CFCalendarClass = { 0, "CFCalendar", - NULL, // init - NULL, // copy + NULL, // init + NULL, // copy __CFCalendarDeallocate, __CFCalendarEqual, __CFCalendarHash, - NULL, // + NULL, // __CFCalendarCopyDescription }; @@ -73,22 +73,22 @@ CFTypeID CFCalendarGetTypeID(void) { CF_PRIVATE UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz) { if (calendarID) { - CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeID); - CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components); - CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, calendarID); - localeID = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents); - CFRelease(mcomponents); - CFRelease(components); + CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeID); + CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components); + CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, calendarID); + localeID = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents); + CFRelease(mcomponents); + CFRelease(components); } char buffer[BUFFER_SIZE]; const char *cstr = CFStringGetCStringPtr(localeID, kCFStringEncodingASCII); if (NULL == cstr) { - if (CFStringGetCString(localeID, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer; + if (CFStringGetCString(localeID, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer; } if (NULL == cstr) { - if (calendarID) CFRelease(localeID); - return NULL; + if (calendarID) CFRelease(localeID); + return NULL; } UChar ubuffer[BUFFER_SIZE]; @@ -224,7 +224,7 @@ CFCalendarRef CFCalendarCopyCurrent(void) { if (calID) { CFCalendarRef calendar = CFCalendarCreateWithIdentifier(kCFAllocatorSystemDefault, (CFStringRef)calID); CFCalendarSetLocale(calendar, locale); - CFRelease(locale); + CFRelease(locale); return calendar; } return NULL; @@ -266,21 +266,21 @@ CFCalendarRef CFCalendarCreateWithIdentifier(CFAllocatorRef allocator, CFStringR // return NULL until Chinese calendar is available if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar) { // if (identifier != kCFGregorianCalendar && identifier != kCFBuddhistCalendar && identifier != kCFJapaneseCalendar && identifier != kCFIslamicCalendar && identifier != kCFIslamicCivilCalendar && identifier != kCFHebrewCalendar && identifier != kCFChineseCalendar) { - if (CFEqual(kCFGregorianCalendar, identifier)) identifier = kCFGregorianCalendar; - else if (CFEqual(kCFBuddhistCalendar, identifier)) identifier = kCFBuddhistCalendar; - else if (CFEqual(kCFJapaneseCalendar, identifier)) identifier = kCFJapaneseCalendar; - else if (CFEqual(kCFIslamicCalendar, identifier)) identifier = kCFIslamicCalendar; - else if (CFEqual(kCFIslamicCivilCalendar, identifier)) identifier = kCFIslamicCivilCalendar; - else if (CFEqual(kCFHebrewCalendar, identifier)) identifier = kCFHebrewCalendar; + if (CFEqual(kCFGregorianCalendar, identifier)) identifier = kCFGregorianCalendar; + else if (CFEqual(kCFBuddhistCalendar, identifier)) identifier = kCFBuddhistCalendar; + else if (CFEqual(kCFJapaneseCalendar, identifier)) identifier = kCFJapaneseCalendar; + else if (CFEqual(kCFIslamicCalendar, identifier)) identifier = kCFIslamicCalendar; + else if (CFEqual(kCFIslamicCivilCalendar, identifier)) identifier = kCFIslamicCivilCalendar; + else if (CFEqual(kCFHebrewCalendar, identifier)) identifier = kCFHebrewCalendar; else if (CFEqual(kCFISO8601Calendar, identifier)) identifier = kCFISO8601Calendar; -// else if (CFEqual(kCFChineseCalendar, identifier)) identifier = kCFChineseCalendar; - else return NULL; +// else if (CFEqual(kCFChineseCalendar, identifier)) identifier = kCFChineseCalendar; + else return NULL; } struct __CFCalendar *calendar = NULL; uint32_t size = sizeof(struct __CFCalendar) - sizeof(CFRuntimeBase); calendar = (struct __CFCalendar *)_CFRuntimeCreateInstance(allocator, CFCalendarGetTypeID(), size, NULL); if (NULL == calendar) { - return NULL; + return NULL; } calendar->_identifier = (CFStringRef)CFRetain(identifier); calendar->_locale = NULL; @@ -308,9 +308,9 @@ void CFCalendarSetLocale(CFCalendarRef calendar, CFLocaleRef locale) { __CFGenericValidateType(locale, CFLocaleGetTypeID()); CFStringRef localeID = CFLocaleGetIdentifier(locale); if (localeID != calendar->_localeID) { - CFRelease(calendar->_localeID); - CFRetain(localeID); - calendar->_localeID = localeID; + CFRelease(calendar->_localeID); + CFRetain(localeID); + calendar->_localeID = localeID; if (calendar->_cal) __CFCalendarZapCal(calendar); } } @@ -326,8 +326,8 @@ void CFCalendarSetTimeZone(CFCalendarRef calendar, CFTimeZoneRef tz) { __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (tz) __CFGenericValidateType(tz, CFTimeZoneGetTypeID()); if (tz != calendar->_tz) { - CFRelease(calendar->_tz); - calendar->_tz = tz ? (CFTimeZoneRef)CFRetain(tz) : CFTimeZoneCopyDefault(); + CFRelease(calendar->_tz); + calendar->_tz = tz ? (CFTimeZoneRef)CFRetain(tz) : CFTimeZoneCopyDefault(); if (calendar->_cal) __CFCalendarZapCal(calendar); } } @@ -337,7 +337,7 @@ CFIndex CFCalendarGetFirstWeekday(CFCalendarRef calendar) { __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - return ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK); + return ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK); } return -1; } @@ -347,7 +347,7 @@ void CFCalendarSetFirstWeekday(CFCalendarRef calendar, CFIndex wkdy) { __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - ucal_setAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy); + ucal_setAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK, wkdy); } } @@ -372,8 +372,8 @@ CFDateRef CFCalendarCopyGregorianStartDate(CFCalendarRef calendar) { UErrorCode status = U_ZERO_ERROR; UDate udate = calendar->_cal ? ucal_getGregorianChange(calendar->_cal, &status) : 0; if (calendar->_cal && U_SUCCESS(status)) { - CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970; - return CFDateCreate(CFGetAllocator(calendar), at); + CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970; + return CFDateCreate(CFGetAllocator(calendar), at); } return NULL; } @@ -385,19 +385,19 @@ void CFCalendarSetGregorianStartDate(CFCalendarRef calendar, CFDateRef date) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (!calendar->_cal) return; if (!date) { - UErrorCode status = U_ZERO_ERROR; - UCalendar *cal = __CFCalendarCreateUCalendar(calendar->_identifier, calendar->_localeID, calendar->_tz); - UDate udate = cal ? ucal_getGregorianChange(cal, &status) : 0; - if (cal && U_SUCCESS(status)) { - status = U_ZERO_ERROR; - if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status); - } - if (cal) ucal_close(cal); + UErrorCode status = U_ZERO_ERROR; + UCalendar *cal = __CFCalendarCreateUCalendar(calendar->_identifier, calendar->_localeID, calendar->_tz); + UDate udate = cal ? ucal_getGregorianChange(cal, &status) : 0; + if (cal && U_SUCCESS(status)) { + status = U_ZERO_ERROR; + if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status); + } + if (cal) ucal_close(cal); } else { - CFAbsoluteTime at = CFDateGetAbsoluteTime(date); - UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; - UErrorCode status = U_ZERO_ERROR; - if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status); + CFAbsoluteTime at = CFDateGetAbsoluteTime(date); + UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0; + UErrorCode status = U_ZERO_ERROR; + if (calendar->_cal) ucal_setGregorianChange(calendar->_cal, udate, &status); } } @@ -469,13 +469,13 @@ CFRange CFCalendarGetMinimumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit u __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - ucal_clear(calendar->_cal); - UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); - UErrorCode status = U_ZERO_ERROR; - range.location = ucal_getLimit(calendar->_cal, field, UCAL_GREATEST_MINIMUM, &status); - range.length = ucal_getLimit(calendar->_cal, field, UCAL_LEAST_MAXIMUM, &status) - range.location + 1; - if (UCAL_MONTH == field) range.location++; - if (100000 < range.length) range.length = 100000; + ucal_clear(calendar->_cal); + UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); + UErrorCode status = U_ZERO_ERROR; + range.location = ucal_getLimit(calendar->_cal, field, UCAL_GREATEST_MINIMUM, &status); + range.length = ucal_getLimit(calendar->_cal, field, UCAL_LEAST_MAXIMUM, &status) - range.location + 1; + if (UCAL_MONTH == field) range.location++; + if (100000 < range.length) range.length = 100000; } return range; } @@ -486,13 +486,13 @@ CFRange CFCalendarGetMaximumRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit u __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - ucal_clear(calendar->_cal); - UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); - UErrorCode status = U_ZERO_ERROR; - range.location = ucal_getLimit(calendar->_cal, field, UCAL_MINIMUM, &status); - range.length = ucal_getLimit(calendar->_cal, field, UCAL_MAXIMUM, &status) - range.location + 1; - if (UCAL_MONTH == field) range.location++; - if (100000 < range.length) range.length = 100000; + ucal_clear(calendar->_cal); + UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); + UErrorCode status = U_ZERO_ERROR; + range.location = ucal_getLimit(calendar->_cal, field, UCAL_MINIMUM, &status); + range.length = ucal_getLimit(calendar->_cal, field, UCAL_MAXIMUM, &status) - range.location + 1; + if (UCAL_MONTH == field) range.location++; + if (100000 < range.length) range.length = 100000; } return range; } @@ -509,111 +509,111 @@ static void __CFCalendarSetToFirstInstant(CFCalendarRef calendar, CFCalendarUnit case kCFCalendarUnitWeek: case kCFCalendarUnitWeekOfMonth:; case kCFCalendarUnitWeekOfYear:; - { - // reduce to first day of week, then reduce the rest of the day + { + // reduce to first day of week, then reduce the rest of the day int32_t goal = ucal_getAttribute(calendar->_cal, UCAL_FIRST_DAY_OF_WEEK); - int32_t dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status); - while (dow != goal) { - ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status); - dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status); - } - goto day; - } + int32_t dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status); + while (dow != goal) { + ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, -1, &status); + dow = ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status); + } + goto day; + } case kCFCalendarUnitEra: - { - target_era = ucal_get(calendar->_cal, UCAL_ERA, &status); - ucal_set(calendar->_cal, UCAL_YEAR, ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_ACTUAL_MINIMUM, &status)); - } + { + target_era = ucal_get(calendar->_cal, UCAL_ERA, &status); + ucal_set(calendar->_cal, UCAL_YEAR, ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_ACTUAL_MINIMUM, &status)); + } case kCFCalendarUnitYear: - ucal_set(calendar->_cal, UCAL_MONTH, ucal_getLimit(calendar->_cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status)); + ucal_set(calendar->_cal, UCAL_MONTH, ucal_getLimit(calendar->_cal, UCAL_MONTH, UCAL_ACTUAL_MINIMUM, &status)); case kCFCalendarUnitMonth: - ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, ucal_getLimit(calendar->_cal, UCAL_DAY_OF_MONTH, UCAL_ACTUAL_MINIMUM, &status)); + ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, ucal_getLimit(calendar->_cal, UCAL_DAY_OF_MONTH, UCAL_ACTUAL_MINIMUM, &status)); case kCFCalendarUnitWeekday: case kCFCalendarUnitDay: day:; - ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, ucal_getLimit(calendar->_cal, UCAL_HOUR_OF_DAY, UCAL_ACTUAL_MINIMUM, &status)); + ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, ucal_getLimit(calendar->_cal, UCAL_HOUR_OF_DAY, UCAL_ACTUAL_MINIMUM, &status)); case kCFCalendarUnitHour: - ucal_set(calendar->_cal, UCAL_MINUTE, ucal_getLimit(calendar->_cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status)); + ucal_set(calendar->_cal, UCAL_MINUTE, ucal_getLimit(calendar->_cal, UCAL_MINUTE, UCAL_ACTUAL_MINIMUM, &status)); case kCFCalendarUnitMinute: - ucal_set(calendar->_cal, UCAL_SECOND, ucal_getLimit(calendar->_cal, UCAL_SECOND, UCAL_ACTUAL_MINIMUM, &status)); + ucal_set(calendar->_cal, UCAL_SECOND, ucal_getLimit(calendar->_cal, UCAL_SECOND, UCAL_ACTUAL_MINIMUM, &status)); case kCFCalendarUnitSecond: - ucal_set(calendar->_cal, UCAL_MILLISECOND, 0); + ucal_set(calendar->_cal, UCAL_MILLISECOND, 0); } if (INT_MIN != target_era && ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) { - // In the Japanese calendar, and possibly others, eras don't necessarily - // start on the first day of a year, so the previous code may have backed - // up into the previous era, and we have to correct forward. - UDate bad_udate = ucal_getMillis(calendar->_cal, &status); - ucal_add(calendar->_cal, UCAL_MONTH, 1, &status); - while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) { - bad_udate = ucal_getMillis(calendar->_cal, &status); - ucal_add(calendar->_cal, UCAL_MONTH, 1, &status); - } - udate = ucal_getMillis(calendar->_cal, &status); - // target date is between bad_udate and udate - for (;;) { - UDate test_udate = (udate + bad_udate) / 2; - ucal_setMillis(calendar->_cal, test_udate, &status); - if (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) { - bad_udate = test_udate; - } else { - udate = test_udate; - } - if (fabs(udate - bad_udate) < 1000) break; - } - do { - bad_udate = floor((bad_udate + 1000) / 1000) * 1000; - ucal_setMillis(calendar->_cal, bad_udate, &status); - } while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era); + // In the Japanese calendar, and possibly others, eras don't necessarily + // start on the first day of a year, so the previous code may have backed + // up into the previous era, and we have to correct forward. + UDate bad_udate = ucal_getMillis(calendar->_cal, &status); + ucal_add(calendar->_cal, UCAL_MONTH, 1, &status); + while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) { + bad_udate = ucal_getMillis(calendar->_cal, &status); + ucal_add(calendar->_cal, UCAL_MONTH, 1, &status); + } + udate = ucal_getMillis(calendar->_cal, &status); + // target date is between bad_udate and udate + for (;;) { + UDate test_udate = (udate + bad_udate) / 2; + ucal_setMillis(calendar->_cal, test_udate, &status); + if (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era) { + bad_udate = test_udate; + } else { + udate = test_udate; + } + if (fabs(udate - bad_udate) < 1000) break; + } + do { + bad_udate = floor((bad_udate + 1000) / 1000) * 1000; + ucal_setMillis(calendar->_cal, bad_udate, &status); + } while (ucal_get(calendar->_cal, UCAL_ERA, &status) < target_era); } } static Boolean __validUnits(CFCalendarUnit smaller, CFCalendarUnit bigger) { switch (bigger) { case kCFCalendarUnitEra: - if (kCFCalendarUnitEra == smaller) return false; - if (kCFCalendarUnitWeekday == smaller) return false; - if (kCFCalendarUnitMinute == smaller) return false; // this causes CFIndex overflow in range.length - if (kCFCalendarUnitSecond == smaller) return false; // this causes CFIndex overflow in range.length - return true; + if (kCFCalendarUnitEra == smaller) return false; + if (kCFCalendarUnitWeekday == smaller) return false; + if (kCFCalendarUnitMinute == smaller) return false; // this causes CFIndex overflow in range.length + if (kCFCalendarUnitSecond == smaller) return false; // this causes CFIndex overflow in range.length + return true; case kCFCalendarUnitYearForWeekOfYear: case kCFCalendarUnitYear: - if (kCFCalendarUnitEra == smaller) return false; - if (kCFCalendarUnitYear == smaller) return false; + if (kCFCalendarUnitEra == smaller) return false; + if (kCFCalendarUnitYear == smaller) return false; if (kCFCalendarUnitYearForWeekOfYear == smaller) return false; - if (kCFCalendarUnitWeekday == smaller) return false; - return true; + if (kCFCalendarUnitWeekday == smaller) return false; + return true; case kCFCalendarUnitMonth: - if (kCFCalendarUnitEra == smaller) return false; - if (kCFCalendarUnitYear == smaller) return false; - if (kCFCalendarUnitMonth == smaller) return false; - if (kCFCalendarUnitWeekday == smaller) return false; - return true; + if (kCFCalendarUnitEra == smaller) return false; + if (kCFCalendarUnitYear == smaller) return false; + if (kCFCalendarUnitMonth == smaller) return false; + if (kCFCalendarUnitWeekday == smaller) return false; + return true; case kCFCalendarUnitDay: - if (kCFCalendarUnitHour == smaller) return true; - if (kCFCalendarUnitMinute == smaller) return true; - if (kCFCalendarUnitSecond == smaller) return true; - return false; + if (kCFCalendarUnitHour == smaller) return true; + if (kCFCalendarUnitMinute == smaller) return true; + if (kCFCalendarUnitSecond == smaller) return true; + return false; case kCFCalendarUnitHour: - if (kCFCalendarUnitMinute == smaller) return true; - if (kCFCalendarUnitSecond == smaller) return true; - return false; + if (kCFCalendarUnitMinute == smaller) return true; + if (kCFCalendarUnitSecond == smaller) return true; + return false; case kCFCalendarUnitMinute: - if (kCFCalendarUnitSecond == smaller) return true; - return false; + if (kCFCalendarUnitSecond == smaller) return true; + return false; case kCFCalendarUnitWeek: case kCFCalendarUnitWeekOfMonth: case kCFCalendarUnitWeekOfYear: - if (kCFCalendarUnitWeekday == smaller) return true; - if (kCFCalendarUnitDay == smaller) return true; - if (kCFCalendarUnitHour == smaller) return true; - if (kCFCalendarUnitMinute == smaller) return true; - if (kCFCalendarUnitSecond == smaller) return true; - return false; + if (kCFCalendarUnitWeekday == smaller) return true; + if (kCFCalendarUnitDay == smaller) return true; + if (kCFCalendarUnitHour == smaller) return true; + if (kCFCalendarUnitMinute == smaller) return true; + if (kCFCalendarUnitSecond == smaller) return true; + return false; case kCFCalendarUnitSecond: case kCFCalendarUnitWeekday: case kCFCalendarUnitWeekdayOrdinal: - return false; + return false; } return false; }; @@ -625,8 +625,8 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni CFRange range = {kCFNotFound, kCFNotFound}; if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - switch (smallerUnit) { - case kCFCalendarUnitSecond: + switch (smallerUnit) { + case kCFCalendarUnitSecond: switch (biggerUnit) { case kCFCalendarUnitMinute: case kCFCalendarUnitHour: @@ -636,13 +636,13 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - // goto calculate; + // goto calculate; range.location = 0; range.length = 60; - break; + break; } - break; - case kCFCalendarUnitMinute: + break; + case kCFCalendarUnitMinute: switch (biggerUnit) { case kCFCalendarUnitHour: case kCFCalendarUnitDay: @@ -651,13 +651,13 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - // goto calculate; + // goto calculate; range.location = 0; range.length = 60; - break; + break; } - break; - case kCFCalendarUnitHour: + break; + case kCFCalendarUnitHour: switch (biggerUnit) { case kCFCalendarUnitDay: case kCFCalendarUnitWeekday: @@ -665,68 +665,68 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - // goto calculate; + // goto calculate; range.location = 0; range.length = 24; - break; + break; } - break; - case kCFCalendarUnitDay: + break; + case kCFCalendarUnitDay: switch (biggerUnit) { case kCFCalendarUnitWeek: case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitWeekday: + break; + case kCFCalendarUnitWeekday: switch (biggerUnit) { case kCFCalendarUnitWeek: case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitWeekdayOrdinal: + break; + case kCFCalendarUnitWeekdayOrdinal: switch (biggerUnit) { case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitWeek: + break; + case kCFCalendarUnitWeek: switch (biggerUnit) { case kCFCalendarUnitMonth: case kCFCalendarUnitYear: case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitMonth: + break; + case kCFCalendarUnitMonth: switch (biggerUnit) { case kCFCalendarUnitYear: case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitYear: + break; + case kCFCalendarUnitYear: switch (biggerUnit) { case kCFCalendarUnitEra: - goto calculate; - break; + goto calculate; + break; } - break; - case kCFCalendarUnitEra: - break; - } + break; + case kCFCalendarUnitEra: + break; + } } return range; @@ -753,10 +753,10 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni UErrorCode status = U_ZERO_ERROR; // roll day forward to first 'dow' while (ucal_get(calendar->_cal, (kCFCalendarUnitMonth == biggerUnit) ? UCAL_WEEK_OF_MONTH : UCAL_WEEK_OF_YEAR, &status) != 1) { - ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); + ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); } while (ucal_get(calendar->_cal, UCAL_DAY_OF_WEEK, &status) != dow) { - ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); + ucal_add(calendar->_cal, UCAL_DAY_OF_MONTH, 1, &status); } } int32_t minSmallValue = INT32_MAX; @@ -770,7 +770,7 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni ucal_add(calendar->_cal, fieldToAdd, 1, &status); if (bigValue != ucal_get(calendar->_cal, bigField, &status)) break; if (biggerUnit == kCFCalendarUnitEra && ucal_get(calendar->_cal, yearField, &status) > 10000) break; - // we assume an answer for 10000 years can be extrapolated to 100000 years, to save time + // we assume an answer for 10000 years can be extrapolated to 100000 years, to save time } status = U_ZERO_ERROR; range.location = minSmallValue; @@ -782,7 +782,7 @@ static CFRange __CFCalendarGetRangeOfUnit2(CFCalendarRef calendar, CFCalendarUni } CFRange CFCalendarGetRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) { - return __CFCalendarGetRangeOfUnit2(calendar, smallerUnit, biggerUnit, at); + return __CFCalendarGetRangeOfUnit2(calendar, smallerUnit, biggerUnit, at); } CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at) { @@ -792,52 +792,52 @@ CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit sma __CFGenericValidateType(calendar, CFCalendarGetTypeID()); if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - UErrorCode status = U_ZERO_ERROR; - ucal_clear(calendar->_cal); - if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) { - UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - ucal_setMillis(calendar->_cal, udate, &status); - int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); - return val; - } else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) { - UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - ucal_setMillis(calendar->_cal, udate, &status); - int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status); - return val; - } - UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit); - // Set calendar to first instant of big unit - __CFCalendarSetToFirstInstant(calendar, biggerUnit, at); - UDate curr = ucal_getMillis(calendar->_cal, &status); + UErrorCode status = U_ZERO_ERROR; + ucal_clear(calendar->_cal); + if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitYear == biggerUnit) { + UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + ucal_setMillis(calendar->_cal, udate, &status); + int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_YEAR, &status); + return val; + } else if (kCFCalendarUnitWeek == smallerUnit && kCFCalendarUnitMonth == biggerUnit) { + UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + ucal_setMillis(calendar->_cal, udate, &status); + int32_t val = ucal_get(calendar->_cal, UCAL_WEEK_OF_MONTH, &status); + return val; + } + UCalendarDateFields smallField = __CFCalendarGetICUFieldCode(smallerUnit); + // Set calendar to first instant of big unit + __CFCalendarSetToFirstInstant(calendar, biggerUnit, at); + UDate curr = ucal_getMillis(calendar->_cal, &status); UDate goal = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - result = 1; - const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; - int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]); - Boolean divide = false, alwaysDivide = false; - while (curr < goal) { - ucal_add(calendar->_cal, smallField, multiple, &status); - UDate newcurr = ucal_getMillis(calendar->_cal, &status); - if (curr < newcurr && newcurr <= goal) { - result += multiple; - curr = newcurr; - } else { - // Either newcurr is going backwards, or not making - // progress, or has overshot the goal; reset date - // and try smaller multiples. - ucal_setMillis(calendar->_cal, curr, &status); - divide = true; - // once we start overshooting the goal, the add at - // smaller multiples will succeed at most once for - // each multiple, so we reduce it every time through - // the loop. - if (goal < newcurr) alwaysDivide = true; - } - if (divide) { - multiple = multiple / 2; - if (0 == multiple) break; - divide = alwaysDivide; - } - } + result = 1; + const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; + int multiple = (1 << multiple_table[flsl(smallerUnit) - 1]); + Boolean divide = false, alwaysDivide = false; + while (curr < goal) { + ucal_add(calendar->_cal, smallField, multiple, &status); + UDate newcurr = ucal_getMillis(calendar->_cal, &status); + if (curr < newcurr && newcurr <= goal) { + result += multiple; + curr = newcurr; + } else { + // Either newcurr is going backwards, or not making + // progress, or has overshot the goal; reset date + // and try smaller multiples. + ucal_setMillis(calendar->_cal, curr, &status); + divide = true; + // once we start overshooting the goal, the add at + // smaller multiples will succeed at most once for + // each multiple, so we reduce it every time through + // the loop. + if (goal < newcurr) alwaysDivide = true; + } + if (divide) { + multiple = multiple / 2; + if (0 == multiple) break; + divide = alwaysDivide; + } + } } return result; } @@ -845,41 +845,41 @@ CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit sma Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbsoluteTime *atp, const char *componentDesc, int *vector, int count) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - UErrorCode status = U_ZERO_ERROR; - ucal_clear(calendar->_cal); - ucal_set(calendar->_cal, UCAL_YEAR, 1); - ucal_set(calendar->_cal, UCAL_MONTH, 0); - ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, 1); - ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, 0); - ucal_set(calendar->_cal, UCAL_MINUTE, 0); - ucal_set(calendar->_cal, UCAL_SECOND, 0); - const char *desc = componentDesc; - Boolean doWOY = false; - char ch = *desc; - while (ch) { - UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); - if (UCAL_WEEK_OF_YEAR == field) { - doWOY = true; - } - desc++; - ch = *desc; - } - desc = componentDesc; - ch = *desc; - while (ch) { - UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); - int value = *vector; - if (UCAL_YEAR == field && doWOY) field = UCAL_YEAR_WOY; - if (UCAL_MONTH == field) value--; - ucal_set(calendar->_cal, field, value); - vector++; - desc++; - ch = *desc; - } - UDate udate = ucal_getMillis(calendar->_cal, &status); - CFAbsoluteTime at = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970; + UErrorCode status = U_ZERO_ERROR; + ucal_clear(calendar->_cal); + ucal_set(calendar->_cal, UCAL_YEAR, 1); + ucal_set(calendar->_cal, UCAL_MONTH, 0); + ucal_set(calendar->_cal, UCAL_DAY_OF_MONTH, 1); + ucal_set(calendar->_cal, UCAL_HOUR_OF_DAY, 0); + ucal_set(calendar->_cal, UCAL_MINUTE, 0); + ucal_set(calendar->_cal, UCAL_SECOND, 0); + const char *desc = componentDesc; + Boolean doWOY = false; + char ch = *desc; + while (ch) { + UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); + if (UCAL_WEEK_OF_YEAR == field) { + doWOY = true; + } + desc++; + ch = *desc; + } + desc = componentDesc; + ch = *desc; + while (ch) { + UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); + int value = *vector; + if (UCAL_YEAR == field && doWOY) field = UCAL_YEAR_WOY; + if (UCAL_MONTH == field) value--; + ucal_set(calendar->_cal, field, value); + vector++; + desc++; + ch = *desc; + } + UDate udate = ucal_getMillis(calendar->_cal, &status); + CFAbsoluteTime at = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970; if (atp) *atp = at; - return U_SUCCESS(status) ? true : false; + return U_SUCCESS(status) ? true : false; } return false; } @@ -887,21 +887,21 @@ Boolean _CFCalendarComposeAbsoluteTimeV(CFCalendarRef calendar, /* out */ CFAbso Boolean _CFCalendarDecomposeAbsoluteTimeV(CFCalendarRef calendar, CFAbsoluteTime at, const char *componentDesc, int **vector, int count) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - UErrorCode status = U_ZERO_ERROR; - ucal_clear(calendar->_cal); - UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - ucal_setMillis(calendar->_cal, udate, &status); - char ch = *componentDesc; - while (ch) { - UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); - int value = ucal_get(calendar->_cal, field, &status); - if (UCAL_MONTH == field) value++; - *(*vector) = value; - vector++; - componentDesc++; - ch = *componentDesc; - } - return U_SUCCESS(status) ? true : false; + UErrorCode status = U_ZERO_ERROR; + ucal_clear(calendar->_cal); + UDate udate = floor((at + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + ucal_setMillis(calendar->_cal, udate, &status); + char ch = *componentDesc; + while (ch) { + UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); + int value = ucal_get(calendar->_cal, field, &status); + if (UCAL_MONTH == field) value++; + *(*vector) = value; + vector++; + componentDesc++; + ch = *componentDesc; + } + return U_SUCCESS(status) ? true : false; } return false; } @@ -909,26 +909,26 @@ Boolean _CFCalendarDecomposeAbsoluteTimeV(CFCalendarRef calendar, CFAbsoluteTime Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsoluteTime *atp, CFOptionFlags options, const char *componentDesc, int *vector, int count) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - UErrorCode status = U_ZERO_ERROR; - ucal_clear(calendar->_cal); - UDate udate = floor((*atp + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - ucal_setMillis(calendar->_cal, udate, &status); - char ch = *componentDesc; - while (ch) { - UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); + UErrorCode status = U_ZERO_ERROR; + ucal_clear(calendar->_cal); + UDate udate = floor((*atp + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + ucal_setMillis(calendar->_cal, udate, &status); + char ch = *componentDesc; + while (ch) { + UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); int amount = *vector; - if (options & kCFCalendarComponentsWrap) { - ucal_roll(calendar->_cal, field, amount, &status); - } else { - ucal_add(calendar->_cal, field, amount, &status); - } - vector++; - componentDesc++; - ch = *componentDesc; - } - udate = ucal_getMillis(calendar->_cal, &status); - *atp = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970; - return U_SUCCESS(status) ? true : false; + if (options & kCFCalendarComponentsWrap) { + ucal_roll(calendar->_cal, field, amount, &status); + } else { + ucal_add(calendar->_cal, field, amount, &status); + } + vector++; + componentDesc++; + ch = *componentDesc; + } + udate = ucal_getMillis(calendar->_cal, &status); + *atp = (udate / 1000.0) - kCFAbsoluteTimeIntervalSince1970; + return U_SUCCESS(status) ? true : false; } return false; } @@ -936,49 +936,49 @@ Boolean _CFCalendarAddComponentsV(CFCalendarRef calendar, /* inout */ CFAbsolute Boolean _CFCalendarGetComponentDifferenceV(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, int **vector, int count) { if (!calendar->_cal) __CFCalendarSetupCal(calendar); if (calendar->_cal) { - UErrorCode status = U_ZERO_ERROR; - ucal_clear(calendar->_cal); - UDate curr = floor((startingAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - UDate goal = floor((resultAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); - ucal_setMillis(calendar->_cal, curr, &status); - int direction = (startingAT <= resultAT) ? 1 : -1; - char ch = *componentDesc; - while (ch) { - UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); - const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; - int multiple = direction * (1 << multiple_table[flsl(__CFCalendarGetCalendarUnitFromChar(ch)) - 1]); - Boolean divide = false, alwaysDivide = false; - int result = 0; - while ((direction > 0 && curr < goal) || (direction < 0 && goal < curr)) { - ucal_add(calendar->_cal, field, multiple, &status); - UDate newcurr = ucal_getMillis(calendar->_cal, &status); - if ((direction > 0 && curr < newcurr && newcurr <= goal) || (direction < 0 && newcurr < curr && goal <= newcurr)) { - result += multiple; - curr = newcurr; - } else { - // Either newcurr is going backwards, or not making - // progress, or has overshot the goal; reset date - // and try smaller multiples. - ucal_setMillis(calendar->_cal, curr, &status); - divide = true; - // once we start overshooting the goal, the add at - // smaller multiples will succeed at most once for - // each multiple, so we reduce it every time through - // the loop. - if ((direction > 0 && goal < newcurr) || (direction < 0 && newcurr < goal)) alwaysDivide = true; - } - if (divide) { - multiple = multiple / 2; - if (0 == multiple) break; - divide = alwaysDivide; - } - } - *(*vector) = result; - vector++; - componentDesc++; - ch = *componentDesc; - } - return U_SUCCESS(status) ? true : false; + UErrorCode status = U_ZERO_ERROR; + ucal_clear(calendar->_cal); + UDate curr = floor((startingAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + UDate goal = floor((resultAT + kCFAbsoluteTimeIntervalSince1970) * 1000.0); + ucal_setMillis(calendar->_cal, curr, &status); + int direction = (startingAT <= resultAT) ? 1 : -1; + char ch = *componentDesc; + while (ch) { + UCalendarDateFields field = __CFCalendarGetICUFieldCodeFromChar(ch); + const int multiple_table[] = {0, 0, 16, 19, 24, 26, 24, 28, 14, 14, 14}; + int multiple = direction * (1 << multiple_table[flsl(__CFCalendarGetCalendarUnitFromChar(ch)) - 1]); + Boolean divide = false, alwaysDivide = false; + int result = 0; + while ((direction > 0 && curr < goal) || (direction < 0 && goal < curr)) { + ucal_add(calendar->_cal, field, multiple, &status); + UDate newcurr = ucal_getMillis(calendar->_cal, &status); + if ((direction > 0 && curr < newcurr && newcurr <= goal) || (direction < 0 && newcurr < curr && goal <= newcurr)) { + result += multiple; + curr = newcurr; + } else { + // Either newcurr is going backwards, or not making + // progress, or has overshot the goal; reset date + // and try smaller multiples. + ucal_setMillis(calendar->_cal, curr, &status); + divide = true; + // once we start overshooting the goal, the add at + // smaller multiples will succeed at most once for + // each multiple, so we reduce it every time through + // the loop. + if ((direction > 0 && goal < newcurr) || (direction < 0 && newcurr < goal)) alwaysDivide = true; + } + if (divide) { + multiple = multiple / 2; + if (0 == multiple) break; + divide = alwaysDivide; + } + } + *(*vector) = result; + vector++; + componentDesc++; + ch = *componentDesc; + } + return U_SUCCESS(status) ? true : false; } return false; } @@ -991,8 +991,8 @@ Boolean CFCalendarComposeAbsoluteTime(CFCalendarRef calendar, /* out */ CFAbsolu int idx, cnt = strlen((char *)componentDesc); STACK_BUFFER_DECL(int, vector, cnt); for (idx = 0; idx < cnt; idx++) { - int arg = va_arg(args, int); - vector[idx] = arg; + int arg = va_arg(args, int); + vector[idx] = arg; } va_end(args); return _CFCalendarComposeAbsoluteTimeV(calendar, atp, componentDesc, vector, cnt); @@ -1006,8 +1006,8 @@ Boolean CFCalendarDecomposeAbsoluteTime(CFCalendarRef calendar, CFAbsoluteTime a int idx, cnt = strlen((char *)componentDesc); STACK_BUFFER_DECL(int *, vector, cnt); for (idx = 0; idx < cnt; idx++) { - int *arg = va_arg(args, int *); - vector[idx] = arg; + int *arg = va_arg(args, int *); + vector[idx] = arg; } va_end(args); return _CFCalendarDecomposeAbsoluteTimeV(calendar, at, componentDesc, vector, cnt); @@ -1021,11 +1021,11 @@ Boolean CFCalendarAddComponents(CFCalendarRef calendar, /* inout */ CFAbsoluteTi int idx, cnt = strlen((char *)componentDesc); STACK_BUFFER_DECL(int, vector, cnt); for (idx = 0; idx < cnt; idx++) { - int arg = va_arg(args, int); - vector[idx] = arg; + int arg = va_arg(args, int); + vector[idx] = arg; } va_end(args); - return _CFCalendarAddComponentsV(calendar, atp, options, componentDesc, vector, cnt); + return _CFCalendarAddComponentsV(calendar, atp, options, componentDesc, vector, cnt); } Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime startingAT, CFAbsoluteTime resultAT, CFOptionFlags options, const char *componentDesc, ...) { @@ -1036,8 +1036,8 @@ Boolean CFCalendarGetComponentDifference(CFCalendarRef calendar, CFAbsoluteTime int idx, cnt = strlen((char *)componentDesc); STACK_BUFFER_DECL(int *, vector, cnt); for (idx = 0; idx < cnt; idx++) { - int *arg = va_arg(args, int *); - vector[idx] = arg; + int *arg = va_arg(args, int *); + vector[idx] = arg; } va_end(args); Boolean ret = _CFCalendarGetComponentDifferenceV(calendar, startingAT, resultAT, options, componentDesc, vector, cnt); @@ -1055,22 +1055,22 @@ Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit __CFCalendarSetToFirstInstant(calendar, unit, at); UErrorCode status = U_ZERO_ERROR; UDate start = ucal_getMillis(calendar->_cal, &status); - UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); - ucal_add(calendar->_cal, field, 1, &status); + UCalendarDateFields field = __CFCalendarGetICUFieldCode(unit); + ucal_add(calendar->_cal, field, 1, &status); UDate end = ucal_getMillis(calendar->_cal, &status); - if (end == start && kCFCalendarUnitEra == unit) { + if (end == start && kCFCalendarUnitEra == unit) { // ICU refuses to do the addition, probably because we are // at the limit of UCAL_ERA. Use alternate strategy. CFIndex limit = ucal_getLimit(calendar->_cal, UCAL_YEAR, UCAL_MAXIMUM, &status); if (100000 < limit) limit = 100000; ucal_add(calendar->_cal, UCAL_YEAR, limit, &status); - end = ucal_getMillis(calendar->_cal, &status); - } - if (U_SUCCESS(status)) { - if (startp) *startp = (double)start / 1000.0 - kCFAbsoluteTimeIntervalSince1970; - if (tip) *tip = (double)(end - start) / 1000.0; - return true; - } + end = ucal_getMillis(calendar->_cal, &status); + } + if (U_SUCCESS(status)) { + if (startp) *startp = (double)start / 1000.0 - kCFAbsoluteTimeIntervalSince1970; + if (tip) *tip = (double)(end - start) / 1000.0; + return true; + } } return false; diff --git a/CoreFoundation/Locale.subproj/CFCalendar.h b/CoreFoundation/Locale.subproj/CFCalendar.h index 920701958f..0a27343784 100644 --- a/CoreFoundation/Locale.subproj/CFCalendar.h +++ b/CoreFoundation/Locale.subproj/CFCalendar.h @@ -1,7 +1,7 @@ /* CFCalendar.h - Copyright (c) 2004-2017, Apple Inc. and the Swift project authors + Copyright (c) 2004-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -68,13 +68,13 @@ typedef CF_OPTIONS(CFOptionFlags, CFCalendarUnit) { kCFCalendarUnitHour = (1UL << 5), kCFCalendarUnitMinute = (1UL << 6), kCFCalendarUnitSecond = (1UL << 7), - kCFCalendarUnitWeek API_DEPRECATED("Use kCFCalendarUnitWeekOfYear or kCFCalendarUnitWeekOfMonth instead", macos(10.4,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)) = (1UL << 8), + kCFCalendarUnitWeek CF_ENUM_DEPRECATED(10_4, 10_10, 2_0, 8_0) = (1UL << 8), kCFCalendarUnitWeekday = (1UL << 9), kCFCalendarUnitWeekdayOrdinal = (1UL << 10), - kCFCalendarUnitQuarter API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = (1UL << 11), - kCFCalendarUnitWeekOfMonth API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = (1UL << 12), - kCFCalendarUnitWeekOfYear API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = (1UL << 13), - kCFCalendarUnitYearForWeekOfYear API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)) = (1UL << 14), + 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), }; CF_EXPORT @@ -90,7 +90,7 @@ CF_EXPORT CFIndex CFCalendarGetOrdinalityOfUnit(CFCalendarRef calendar, CFCalendarUnit smallerUnit, CFCalendarUnit biggerUnit, CFAbsoluteTime at); CF_EXPORT -Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at, CFAbsoluteTime *startp, CFTimeInterval *tip) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +Boolean CFCalendarGetTimeRangeOfUnit(CFCalendarRef calendar, CFCalendarUnit unit, CFAbsoluteTime at, CFAbsoluteTime *startp, CFTimeInterval *tip) CF_AVAILABLE(10_5, 2_0); CF_EXPORT Boolean CFCalendarComposeAbsoluteTime(CFCalendarRef calendar, /* out */ CFAbsoluteTime *at, const char *componentDesc, ...); diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter.c b/CoreFoundation/Locale.subproj/CFDateFormatter.c index 260f0a99a1..48ef1e28c6 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter.c +++ b/CoreFoundation/Locale.subproj/CFDateFormatter.c @@ -1,7 +1,7 @@ /* CFDateFormatter.c - Copyright (c) 2002-2017, Apple Inc. and the Swift project authors + Copyright (c) 2002-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -37,7 +37,7 @@ typedef CF_ENUM(CFIndex, CFDateFormatterAmbiguousYearHandling) { extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz); -static CONST_STRING_DECL(kCFDateFormatterFormattingContextKey, "kCFDateFormatterFormattingContextKey"); +PE_CONST_STRING_DECL(kCFDateFormatterFormattingContextKey, "kCFDateFormatterFormattingContextKey"); CF_EXPORT const CFStringRef kCFDateFormatterCalendarIdentifierKey; @@ -890,7 +890,7 @@ static CFDateFormatterRef __SetUpCFDateFormatter(CFAllocatorRef allocator, CFLoc return (CFDateFormatterRef)memory; } -#define FORMAT_STRING_MAX_LENGTH 33 // Length of "yyyy-'W'ww-dd'T'HH:mm:ss.SSSXXXXX" +#define FORMAT_STRING_MAX_LENGTH 29 // Length of "yyyy-'W'ww-dd'T'HH:mm:ssXXXXX" static CFMutableStringRef __createISO8601FormatString(CFISO8601DateFormatOptions options) { CFMutableStringRef resultStr = CFStringCreateMutable(kCFAllocatorSystemDefault, FORMAT_STRING_MAX_LENGTH); @@ -898,10 +898,8 @@ static CFMutableStringRef __createISO8601FormatString(CFISO8601DateFormatOptions BOOL useDashSeparator = (options & kCFISO8601DateFormatWithDashSeparatorInDate) == kCFISO8601DateFormatWithDashSeparatorInDate; BOOL useColonSeparatorInTime = (options & kCFISO8601DateFormatWithColonSeparatorInTime) == kCFISO8601DateFormatWithColonSeparatorInTime; BOOL useColonSeparatorInTimeZone = (options & kCFISO8601DateFormatWithColonSeparatorInTimeZone) == kCFISO8601DateFormatWithColonSeparatorInTimeZone; - BOOL internetDateTime = (options & kCFISO8601DateFormatWithInternetDateTime) == kCFISO8601DateFormatWithInternetDateTime; - BOOL includeFractionalSecs = (options & kCFISO8601DateFormatWithFractionalSeconds) == kCFISO8601DateFormatWithFractionalSeconds; - if (internetDateTime) { + if ((options & kCFISO8601DateFormatWithInternetDateTime) == kCFISO8601DateFormatWithInternetDateTime) { // Check for dashes if (useDashSeparator == NO) { CFStringAppendCString(resultStr, "yyyyMMdd", kCFStringEncodingUTF8); @@ -923,11 +921,6 @@ static CFMutableStringRef __createISO8601FormatString(CFISO8601DateFormatOptions CFStringAppendCString(resultStr, "HH:mm:ss", kCFStringEncodingUTF8); } - // Add support for fracional seconds - if (includeFractionalSecs) { - CFStringAppendCString(resultStr, ".SSS", kCFStringEncodingUTF8); - } - // Check for time zone separator if (useColonSeparatorInTimeZone == NO) { CFStringAppendCString(resultStr, "XXXX", kCFStringEncodingUTF8); // Basic Format (e.g. +080500) @@ -1006,10 +999,6 @@ static CFMutableStringRef __createISO8601FormatString(CFISO8601DateFormatOptions } else { CFStringAppendCString(resultStr, "HH:mm:ss", kCFStringEncodingUTF8); } - // Add support for fracional seconds - if (includeFractionalSecs) { - CFStringAppendCString(resultStr, ".SSS", kCFStringEncodingUTF8); - } } break; case kCFISO8601DateFormatWithTimeZone: @@ -1817,7 +1806,7 @@ Boolean CFDateFormatterGetAbsoluteTimeFromString(CFDateFormatterRef formatter, C } success = true; } - if (calendar_id) CFRelease(calendar_id); + CFRelease(calendar_id); __cficu_udat_close(df2); __cficu_ucal_close(cal2); return success; diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter.h b/CoreFoundation/Locale.subproj/CFDateFormatter.h index dc3942f7db..b98971d590 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter.h +++ b/CoreFoundation/Locale.subproj/CFDateFormatter.h @@ -1,7 +1,7 @@ /* CFDateFormatter.h - Copyright (c) 2003-2017, Apple Inc. and the Swift project authors + Copyright (c) 2003-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -24,7 +24,7 @@ typedef struct CF_BRIDGED_MUTABLE_TYPE(id) __CFDateFormatter *CFDateFormatterRef // CFDateFormatters are not thread-safe. Do not use one from multiple threads! CF_EXPORT -CFStringRef CFDateFormatterCreateDateFormatFromTemplate(CFAllocatorRef allocator, CFStringRef tmplate, CFOptionFlags options, CFLocaleRef locale) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFStringRef CFDateFormatterCreateDateFormatFromTemplate(CFAllocatorRef allocator, CFStringRef tmplate, CFOptionFlags options, CFLocaleRef locale) CF_AVAILABLE(10_6, 4_0); // no options defined, pass 0 for now CF_EXPORT @@ -67,14 +67,13 @@ typedef CF_OPTIONS(CFOptionFlags, CFISO8601DateFormatOptions) { */ kCFISO8601DateFormatWithDay API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 4), - kCFISO8601DateFormatWithTime API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 5), // This uses the format "HHmmss" + kCFISO8601DateFormatWithTime API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 5), // This uses the format "HH:mm:ss" kCFISO8601DateFormatWithTimeZone API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 6), kCFISO8601DateFormatWithSpaceBetweenDateAndTime API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 7), // Use space instead of "T" kCFISO8601DateFormatWithDashSeparatorInDate API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 8), // Add separator for date ("-") kCFISO8601DateFormatWithColonSeparatorInTime API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 9), // Add separator for time (":") kCFISO8601DateFormatWithColonSeparatorInTimeZone API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = (1UL << 10), // Add ":" separator in timezone (eg. +08:00) - kCFISO8601DateFormatWithFractionalSeconds API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)) = (1UL << 11), // Add 3 significant digits of fractional seconds (".SSS") kCFISO8601DateFormatWithFullDate API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = kCFISO8601DateFormatWithYear | kCFISO8601DateFormatWithMonth | kCFISO8601DateFormatWithDay | kCFISO8601DateFormatWithDashSeparatorInDate, kCFISO8601DateFormatWithFullTime API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = kCFISO8601DateFormatWithTime | kCFISO8601DateFormatWithColonSeparatorInTime | kCFISO8601DateFormatWithTimeZone | kCFISO8601DateFormatWithColonSeparatorInTimeZone, @@ -157,21 +156,21 @@ CF_EXPORT const CFDateFormatterKey kCFDateFormatterWeekdaySymbols; // CFArray of CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortWeekdaySymbols; // CFArray of CFString CF_EXPORT const CFDateFormatterKey kCFDateFormatterAMSymbol; // CFString CF_EXPORT const CFDateFormatterKey kCFDateFormatterPMSymbol; // CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterLongEraSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortMonthSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneMonthSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneMonthSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortStandaloneMonthSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortWeekdaySymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneWeekdaySymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneWeekdaySymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortStandaloneWeekdaySymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterQuarterSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortQuarterSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneQuarterSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneQuarterSymbols API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFArray of CFString -CF_EXPORT const CFDateFormatterKey kCFDateFormatterGregorianStartDate API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFDate -CF_EXPORT const CFDateFormatterKey kCFDateFormatterDoesRelativeDateFormattingKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); // CFBoolean +CF_EXPORT const CFDateFormatterKey kCFDateFormatterLongEraSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortMonthSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneMonthSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneMonthSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortStandaloneMonthSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortWeekdaySymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneWeekdaySymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneWeekdaySymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterVeryShortStandaloneWeekdaySymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterQuarterSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortQuarterSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterStandaloneQuarterSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterShortStandaloneQuarterSymbols CF_AVAILABLE(10_5, 2_0); // CFArray of CFString +CF_EXPORT const CFDateFormatterKey kCFDateFormatterGregorianStartDate CF_AVAILABLE(10_5, 2_0); // CFDate +CF_EXPORT const CFDateFormatterKey kCFDateFormatterDoesRelativeDateFormattingKey CF_AVAILABLE(10_6, 4_0); // CFBoolean // See CFLocale.h for these calendar constants: // const CFStringRef kCFGregorianCalendar; diff --git a/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h b/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h index ae2a982734..a986d888ac 100644 --- a/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h +++ b/CoreFoundation/Locale.subproj/CFDateFormatter_Private.h @@ -1,7 +1,7 @@ /* CFDateFormatter_Private.h - Copyright (c) 2015-2017, Apple Inc. and the Swift project authors + Copyright (c) 2015-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -17,12 +17,12 @@ CF_IMPLICIT_BRIDGING_ENABLED CF_EXTERN_C_BEGIN CF_EXPORT -CFAttributedStringRef _CFDateFormatterCreateAttributedStringAndFieldsWithAbsoluteTime(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFAbsoluteTime at) API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CFAttributedStringRef _CFDateFormatterCreateAttributedStringAndFieldsWithAbsoluteTime(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFAbsoluteTime at) CF_AVAILABLE(10_11, 9_0); -CF_EXPORT const CFStringRef kCFDateFormatterPatternCharacterKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFStringRef kCFDateFormatterPatternLiteralKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFStringRef kCFDateFormatterPatternStringKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFStringRef kCFDateFormatterPatternRangeKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFDateFormatterPatternCharacterKey CF_AVAILABLE(10_11, 9_0); +CF_EXPORT const CFStringRef kCFDateFormatterPatternLiteralKey CF_AVAILABLE(10_11, 9_0); +CF_EXPORT const CFStringRef kCFDateFormatterPatternStringKey CF_AVAILABLE(10_11, 9_0); +CF_EXPORT const CFStringRef kCFDateFormatterPatternRangeKey CF_AVAILABLE(10_11, 9_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Locale.subproj/CFICULogging.h b/CoreFoundation/Locale.subproj/CFICULogging.h index fae3e29416..a6ac22817b 100644 --- a/CoreFoundation/Locale.subproj/CFICULogging.h +++ b/CoreFoundation/Locale.subproj/CFICULogging.h @@ -1,8 +1,8 @@ /* CFICULogging.h - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFLocale.c b/CoreFoundation/Locale.subproj/CFLocale.c index 05c64068ec..5afca746d8 100644 --- a/CoreFoundation/Locale.subproj/CFLocale.c +++ b/CoreFoundation/Locale.subproj/CFLocale.c @@ -1,7 +1,7 @@ /* CFLocale.c - Copyright (c) 2002-2017, Apple Inc. and the Swift project authors + Copyright (c) 2002-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -19,7 +19,6 @@ #include #include #include "CFInternal.h" -#include "CFBundle_Internal.h" #include "CFLocaleInternal.h" #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD #include // ICU locales @@ -30,7 +29,6 @@ #include // ICU low-level utilities #include // ICU message formatting #include -#include // ICU numbering systems #include #if U_ICU_VERSION_MAJOR_NUM > 53 && __has_include() #include @@ -62,7 +60,6 @@ CF_PRIVATE CFCalendarRef _CFCalendarCreateCoWWithIdentifier(CFStringRef identifi CONST_STRING_DECL(kCFLocaleCurrentLocaleDidChangeNotification, "kCFLocaleCurrentLocaleDidChangeNotification") - static const char *kCalendarKeyword = "calendar"; static const char *kCollationKeyword = "collation"; #define kMaxICUNameSize 1024 @@ -170,11 +167,11 @@ enum { /* Bits 0-1 */ }; CF_INLINE CFIndex __CFLocaleGetType(CFLocaleRef locale) { - return __CFRuntimeGetValue(locale, 1, 0); + return __CFBitfieldGetValue(((const CFRuntimeBase *)locale)->_cfinfo[CF_INFO_BITS], 1, 0); } CF_INLINE void __CFLocaleSetType(CFLocaleRef locale, CFIndex type) { - __CFRuntimeSetValue(locale, 1, 0, (uint8_t)type); + __CFBitfieldSetValue(((CFRuntimeBase *)locale)->_cfinfo[CF_INFO_BITS], 1, 0, (uint8_t)type); } CF_INLINE void __CFLocaleLockGlobal(void) { @@ -201,7 +198,11 @@ static Boolean __CFLocaleEqual(CFTypeRef cf1, CFTypeRef cf2) { if (__CFLocaleGetType(locale1) != __CFLocaleGetType(locale2)) return false; if (!CFEqual(locale1->_identifier, locale2->_identifier)) return false; if (__kCFLocaleUser == __CFLocaleGetType(locale1)) { - return CFEqual(locale1->_prefs, locale2->_prefs); + if (locale1->_prefs && locale2->_prefs) { + return CFEqual(locale1->_prefs, locale2->_prefs); + } else { + return locale1->_prefs == locale2->_prefs; + } } return true; } @@ -283,20 +284,7 @@ CFLocaleRef CFLocaleGetSystem(void) { extern CFDictionaryRef __CFXPreferencesCopyCurrentApplicationState(void); -static _Atomic(CFLocaleRef) _CFLocaleCurrent_ = NULL; - -CF_INLINE CFLocaleRef _cachedCurrentLocale() { -#if DEPLOYMENT_RUNTIME_SWIFT - CFLocaleRef loc = atomic_load_explicit(&_CFLocaleCurrent_, memory_order_relaxed); - return loc ? CFRetain(loc) : NULL; -#else - return atomic_load_explicit(&_CFLocaleCurrent_, memory_order_relaxed); -#endif -} - -static void _setCachedCurrentLocale(CFLocaleRef newLocale) { - atomic_store(&_CFLocaleCurrent_, newLocale); //no release, cached locales are immortal -} +static CFLocaleRef __CFLocaleCurrent = NULL; #if DEPLOYMENT_TARGET_MACOSX @@ -312,242 +300,7 @@ static void _setCachedCurrentLocale(CFLocaleRef newLocale) { #define FALLBACK_LOCALE_NAME CFSTR("en_US") #endif -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED -static CFStringRef _CFLocaleCopyLocaleIdentifierByAddingLikelySubtags(CFStringRef localeID) -{ - CFStringRef result = NULL; - if (localeID) { - char bufLocaleID[ULOC_FULLNAME_CAPACITY]; - const char *cLocaleID = CFStringGetCStringPtr(localeID, kCFStringEncodingUTF8); - if (NULL == cLocaleID) { - if (CFStringGetCString(localeID, bufLocaleID, ULOC_FULLNAME_CAPACITY, kCFStringEncodingUTF8)) { - cLocaleID = bufLocaleID; - } - } - UErrorCode icuStatus = U_ZERO_ERROR; - char maximizedLocaleID[ULOC_FULLNAME_CAPACITY]; - int32_t bufSize = uloc_addLikelySubtags(cLocaleID, maximizedLocaleID, ULOC_FULLNAME_CAPACITY, &icuStatus); - if ((bufSize != -1) && U_SUCCESS(icuStatus)) { - result = CFStringCreateWithCString(NULL, maximizedLocaleID, kCFStringEncodingUTF8); - } - } - return result ? : CFRetain(localeID); -} - -// For a given locale (e.g. `en_US`, `zh_CN`, etc.) copies the language identifier with an explicit script code (e.g. `en-Latn`, zh-Hans`, etc.) -static CFStringRef _CFLocaleCopyLanguageIdentifierWithScriptCodeForLocaleIdentifier(CFStringRef localeID) -{ - CFStringRef languageID = NULL; - if (localeID) { - CFStringRef maximizedLocaleID = _CFLocaleCopyLocaleIdentifierByAddingLikelySubtags(localeID); - CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, maximizedLocaleID); - CFRelease(maximizedLocaleID); - - CFStringRef languageCode = CFDictionaryGetValue(components, kCFLocaleLanguageCode); - CFStringRef scriptCode = CFDictionaryGetValue(components, kCFLocaleScriptCode); - if (languageCode && scriptCode) { - languageID = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@-%@"), languageCode, scriptCode); - } - CFRelease(components); - } - return languageID; -} - -CFStringRef _CFLocaleCopyNumberingSystemForLocaleIdentifier(CFStringRef localeID) -{ - CFStringRef numberingSystemID = NULL; - if (localeID) { - CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, localeID); - if (components) { - // If the locale has an explicitly defined numbering system, that’s our answer! - numberingSystemID = CFDictionaryGetValue(components, CFSTR("numbers")); - if (numberingSystemID) { - CFRetain(numberingSystemID); - } - // Otherwise, query ICU for what the default numbering system is. - else { - CFMutableDictionaryRef mutableComponents = CFDictionaryCreateMutableCopy(NULL, 0, components); - if (mutableComponents) { - CFDictionarySetValue(mutableComponents, CFSTR("numbers"), CFSTR("default")); - CFStringRef localeIDWithDefaultNumbers = CFLocaleCreateLocaleIdentifierFromComponents(NULL, mutableComponents); - if (localeIDWithDefaultNumbers) { - char bufLocaleIDWithDefaultNumbers[ULOC_FULLNAME_CAPACITY]; - const char *cLocaleIDWithDefaultNumbers = CFStringGetCStringPtr(localeIDWithDefaultNumbers, kCFStringEncodingUTF8); - if (!cLocaleIDWithDefaultNumbers) { - if (CFStringGetCString(localeIDWithDefaultNumbers, bufLocaleIDWithDefaultNumbers, ULOC_FULLNAME_CAPACITY, kCFStringEncodingUTF8)) { - cLocaleIDWithDefaultNumbers = bufLocaleIDWithDefaultNumbers; - } - } - if (cLocaleIDWithDefaultNumbers) { - UErrorCode icuStatus = U_ZERO_ERROR; - UNumberingSystem *numberingSystem = unumsys_open(cLocaleIDWithDefaultNumbers, &icuStatus); - if (numberingSystem) { - const char *cNumberingSystemID = unumsys_getName(numberingSystem); - if (cNumberingSystemID) { - numberingSystemID = CFStringCreateWithCString(NULL, cNumberingSystemID, kCFStringEncodingUTF8); - } - unumsys_close(numberingSystem); - } - } - CFRelease(localeIDWithDefaultNumbers); - } - CFRelease(mutableComponents); - } - } - CFRelease(components); - } - } - return numberingSystemID; -} - -CFArrayRef _CFLocaleCopyValidNumberingSystemsForLocaleIdentifier(CFStringRef localeID) -{ - CFMutableArrayRef numberingSystemIDs = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - if (localeID) { - CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, localeID); - if (components) { - // 1. If there is an explicitly defined override numbering system, add it first to the list. - CFStringRef overrideNumberingSystemID = CFDictionaryGetValue(components, CFSTR("numbers")); - if (overrideNumberingSystemID) { - CFArrayAppendValue(numberingSystemIDs, overrideNumberingSystemID); - } - - // 2. Query ICU for additional supported numbering systems - CFStringRef queryList[4] = { CFSTR("default"), NULL, NULL, NULL }; - CFStringRef languageCode = CFDictionaryGetValue(components, kCFLocaleLanguageCode); - // For Chinese & Thai, although there is a traditional numbering system, it is not one that users will expect to use as a numbering system in the system. (cf. ) - if (!(CFEqual(languageCode, CFSTR("th")) || - CFEqual(languageCode, CFSTR("zh")) || - CFEqual(languageCode, CFSTR("wuu")) || - CFEqual(languageCode, CFSTR("yue")))) { - queryList[1] = CFSTR("native"); - queryList[2] = CFSTR("traditional"); - queryList[3] = CFSTR("finance"); - } - CFMutableDictionaryRef mutableComponents = CFDictionaryCreateMutableCopy(NULL, 0, components); - if (mutableComponents) { - for (CFIndex i = 0, count = sizeof(queryList)/sizeof(CFStringRef); i < count; i++) { - CFStringRef query = queryList[i]; - if (query) { - CFDictionarySetValue(mutableComponents, CFSTR("numbers"), query); - CFStringRef localeIDWithNumbersQuery = CFLocaleCreateLocaleIdentifierFromComponents(NULL, mutableComponents); - if (localeIDWithNumbersQuery) { - char bufLocaleIDWithNumbersQuery[ULOC_FULLNAME_CAPACITY]; - const char *cLocaleIDWithNumbersQuery = CFStringGetCStringPtr(localeIDWithNumbersQuery, kCFStringEncodingUTF8); - if (!cLocaleIDWithNumbersQuery) { - if (CFStringGetCString(localeIDWithNumbersQuery, bufLocaleIDWithNumbersQuery, ULOC_FULLNAME_CAPACITY, kCFStringEncodingUTF8)) { - cLocaleIDWithNumbersQuery = bufLocaleIDWithNumbersQuery; - } - } - if (cLocaleIDWithNumbersQuery) { - UNumberingSystem *numberingSystem = NULL; - UErrorCode icuStatus = U_ZERO_ERROR; - if ((numberingSystem = unumsys_open(cLocaleIDWithNumbersQuery, &icuStatus)) != NULL) { - // There are some really funky numbering systems out there, and we do not support ones that are algorithmic (like the traditional ones for Hebrew, etc.) and ones that are not base 10. - if (!unumsys_isAlgorithmic(numberingSystem) && unumsys_getRadix(numberingSystem) == 10) { - const char *cNumberingSystemID = unumsys_getName(numberingSystem); - if (cNumberingSystemID) { - CFStringRef numberingSystemID = CFStringCreateWithCString(NULL, cNumberingSystemID, kCFStringEncodingUTF8); - if (numberingSystemID) { - if (!CFArrayContainsValue(numberingSystemIDs, CFRangeMake(0, CFArrayGetCount(numberingSystemIDs)), numberingSystemID)) { - CFArrayAppendValue(numberingSystemIDs, numberingSystemID); - } - CFRelease(numberingSystemID); - } - } - } - unumsys_close(numberingSystem); - } - } - CFRelease(localeIDWithNumbersQuery); - } - } - } - CFRelease(mutableComponents); - } - - // 3. Add `latn`, which we support that for all languages. - if (!CFArrayContainsValue(numberingSystemIDs, CFRangeMake(0, CFArrayGetCount(numberingSystemIDs)), CFSTR("latn"))) { - CFArrayAppendValue(numberingSystemIDs, CFSTR("latn")); - } - - CFRelease(components); - } - } - return numberingSystemIDs; -} - -CFStringRef _CFLocaleCreateLocaleIdentiferByReplacingLanguageCodeAndScriptCode(CFStringRef localeIDWithDesiredLangCode, CFStringRef localeIDWithDesiredComponents) { - CFStringRef localeID = NULL; - if (localeIDWithDesiredLangCode && localeIDWithDesiredComponents) { - CFStringRef langIDToUse = _CFLocaleCopyLanguageIdentifierWithScriptCodeForLocaleIdentifier(localeIDWithDesiredLangCode); - if (langIDToUse) { - CFStringRef maximizedLocaleID = _CFLocaleCopyLocaleIdentifierByAddingLikelySubtags(localeIDWithDesiredComponents); - if (maximizedLocaleID) { - CFDictionaryRef localeIDComponents = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, maximizedLocaleID); - CFRelease(maximizedLocaleID); - if (localeIDComponents) { - CFMutableDictionaryRef mutableComps = CFDictionaryCreateMutableCopy(NULL, CFDictionaryGetCount(localeIDComponents), localeIDComponents); - CFRelease(localeIDComponents); - if (mutableComps) { - CFDictionaryRef languageIDComponents = CFLocaleCreateComponentsFromLocaleIdentifier(NULL, langIDToUse); - if (languageIDComponents) { - CFStringRef languageCode = CFDictionaryGetValue(languageIDComponents, kCFLocaleLanguageCode); - CFStringRef scriptCode = CFDictionaryGetValue(languageIDComponents, kCFLocaleScriptCode); - if (languageCode && scriptCode) { - // 1. Language & Script - // Note that both `languageCode` and `scriptCode` should be overridden in `mutableComps`, even for combinations like `en` + `latn`, because the previous language’s script may not be compatible with the new language. This will produce a “maximized” locale identifier, which we will canonicalize (below) to remove superfluous tags. - CFDictionarySetValue(mutableComps, kCFLocaleLanguageCode, languageCode); - CFDictionarySetValue(mutableComps, kCFLocaleScriptCode, scriptCode); - - // 2. Numbering System - CFStringRef numberingSystem = _CFLocaleCopyNumberingSystemForLocaleIdentifier(localeIDWithDesiredComponents); - if (numberingSystem) { - CFArrayRef validNumberingSystems = _CFLocaleCopyValidNumberingSystemsForLocaleIdentifier(localeIDWithDesiredLangCode); - if (validNumberingSystems) { - CFIndex indexOfNumberingSystem = CFArrayGetFirstIndexOfValue(validNumberingSystems, CFRangeMake(0, CFArrayGetCount(validNumberingSystems)), numberingSystem); - // If the numbering system for `localeIDWithDesiredComponents` is not compatible with the constructed locale’s language, then we should discard it, e.g. `ar_AE@numbers=arab` + `en` should get `en_AE`, not `en_AE@numbers=arab`, since `arab` is not valid for `en`. - if (indexOfNumberingSystem == kCFNotFound || indexOfNumberingSystem == 0) { - CFDictionaryRemoveValue(mutableComps, CFSTR("numbers")); - } - // If the numbering system for `localeIDWithDesiredComponents` is compatible with the constructed locale’s language and is not already the default numbering system (index 0), then set it on the new locale, e.g. `hi_IN@numbers=latn` + `ar` shoudl get `ar_IN@numbers=latn`, since `latn` is valid for `ar`. - else if (indexOfNumberingSystem > 0) { - CFDictionarySetValue(mutableComps, CFSTR("numbers"), numberingSystem); - } - CFRelease(validNumberingSystems); - } - CFRelease(numberingSystem); - } - - // 3. Construct & Canonicalize - // The locale constructed from the components will be over-specified for many cases, such as `en_Latn_US`. Before returning it, we should canonicalize it, which will remove any script code that is already implicit in the definition of the locale, yielding `en_US` instead. - CFStringRef maximizedLocaleID = CFLocaleCreateLocaleIdentifierFromComponents(NULL, mutableComps); - if (maximizedLocaleID) { - localeID = CFLocaleCreateCanonicalLocaleIdentifierFromString(NULL, maximizedLocaleID); - CFRelease(maximizedLocaleID); - } - } - CFRelease(languageIDComponents); - } - CFRelease(mutableComps); - } - } - } - CFRelease(langIDToUse); - } - } - return localeID; -} -#endif - -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS -static CFArrayRef _CFLocaleCopyPreferredLanguagesFromPrefs(CFArrayRef languagesArray); -#endif - -static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, CFDictionaryRef overridePrefs, Boolean disableBundleMatching) { - /* - NOTE: calling any CFPreferences function, or any function which calls into a CFPreferences function, *except* for __CFXPreferencesCopyCurrentApplicationState, will deadlock. This is because in apps linked against older SDKs, this function is called from inside CFPreferences, with locks held, via CFPrefsCompatibilitySource. - */ +static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, CFDictionaryRef overridePrefs) { CFStringRef ident = NULL; // We cannot be helpful here, because it causes performance problems, @@ -566,23 +319,23 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, } if (name) CFRelease(name); - // If `disableBundleMatching` is true, caching needs to be turned off, only a single value is cached for the most common case of calling `CFLocaleCopyCurrent`. - if (disableBundleMatching) { - useCache = false; - } - if (useCache) { - CFLocaleRef cached = _cachedCurrentLocale(); - if (ident) { - if (!CFEqual(cached->_identifier, ident)) { - _setCachedCurrentLocale(NULL); - cached = NULL; + CFLocaleRef oldLocale = NULL; + __CFLocaleLockGlobal(); + if (__CFLocaleCurrent) { + if (ident && !CFEqual(__CFLocaleCurrent->_identifier, ident)) { + oldLocale = __CFLocaleCurrent; + __CFLocaleCurrent = NULL; + } else { + CFLocaleRef res = __CFLocaleCurrent; + CFRetain(res); + __CFLocaleUnlockGlobal(); + if (ident) CFRelease(ident); + return res; } - CFRelease(ident); - } - if (cached) { - return cached; } + __CFLocaleUnlockGlobal(); + if (oldLocale) CFRelease(oldLocale); } CFDictionaryRef prefs = NULL; @@ -595,11 +348,6 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, if (ident) CFRelease(ident); return NULL; } -#if !DEPLOYMENT_RUNTIME_SWIFT - if (useCache) { - __CFRuntimeSetRC((CFTypeRef)locale, 0); //make immortal - } -#endif __CFLocaleSetType(locale, __kCFLocaleUser); if (NULL == ident) ident = (CFStringRef)CFRetain(FALLBACK_LOCALE_NAME); locale->_identifier = ident; @@ -609,10 +357,18 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, locale->_nullLocale = false; if (useCache) { - if (NULL == _cachedCurrentLocale()) { - _setCachedCurrentLocale(locale); + CFLocaleRef uselessLocale = NULL; //if we use the global cached locale, we don't need 'locale' anymore, but we want to release it outside the lock + __CFLocaleLockGlobal(); + if (NULL == __CFLocaleCurrent) { + __CFLocaleCurrent = locale; + } else { + uselessLocale = locale; + } + locale = (struct __CFLocale *)CFRetain(__CFLocaleCurrent); + __CFLocaleUnlockGlobal(); + if (uselessLocale) { + CFRelease(uselessLocale); } - locale = (struct __CFLocale *)_cachedCurrentLocale(); } return locale; } @@ -622,7 +378,7 @@ static CFLocaleRef _CFLocaleCopyCurrentGuts(CFStringRef name, Boolean useCache, This returns an instance of CFLocale that's set up exactly like it would be if the user changed the current locale to that identifier, then called CFLocaleCopyCurrent() */ CFLocaleRef _CFLocaleCopyAsIfCurrent(CFStringRef name) { - return _CFLocaleCopyCurrentGuts(name, false, NULL, false); + return _CFLocaleCopyCurrentGuts(name, false, NULL); } /* @@ -630,15 +386,11 @@ CFLocaleRef _CFLocaleCopyAsIfCurrent(CFStringRef name) { This returns an instance of CFLocale that's set up exactly like it would be if the user changed the current locale to that identifier, set the preferences keys in the overrides dictionary, then called CFLocaleCopyCurrent() */ CFLocaleRef _CFLocaleCopyAsIfCurrentWithOverrides(CFStringRef name, CFDictionaryRef overrides) { - return _CFLocaleCopyCurrentGuts(name, false, overrides, false); -} - -CFLocaleRef _CFLocaleCopyPreferred(void) { - return _CFLocaleCopyCurrentGuts(NULL, true, NULL, true); + return _CFLocaleCopyCurrentGuts(name, false, overrides); } CFLocaleRef CFLocaleCopyCurrent(void) { - return _CFLocaleCopyCurrentGuts(NULL, true, NULL, false); + return _CFLocaleCopyCurrentGuts(NULL, true, NULL); } CF_PRIVATE CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale) { @@ -699,6 +451,7 @@ CFLocaleRef CFLocaleCreate(CFAllocatorRef allocator, CFStringRef identifier) { uint32_t size = sizeof(struct __CFLocale) - sizeof(CFRuntimeBase); locale = (struct __CFLocale *)_CFRuntimeCreateInstance(allocator, CFLocaleGetTypeID(), size, NULL); if (NULL == locale) { + __CFUnlock(&__CFLocaleCacheLock); if (localeIdentifier) { CFRelease(localeIdentifier); } return NULL; } @@ -1080,34 +833,25 @@ _CFLocaleCalendarDirection _CFLocaleGetCalendarDirection(void) { #endif } -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS -static CFArrayRef _CFLocaleCopyPreferredLanguagesFromPrefs(CFArrayRef languagesArray) { +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++) { + for (CFIndex idx = 0, cnt = CFArrayGetCount(languagesArray); idx < cnt; idx++) { CFStringRef str = (CFStringRef)CFArrayGetValueAtIndex(languagesArray, idx); - if (str && (CFStringGetTypeID() == CFGetTypeID(str))) { + if (str && (CFStringGetTypeID() == CFGetTypeID(str))) { CFStringRef ident = CFLocaleCreateCanonicalLanguageIdentifierFromString(kCFAllocatorSystemDefault, str); if (ident) { CFArrayAppendValue(newArray, ident); CFRelease(ident); } - } - } + } + } } - return newArray; -} -#endif - -CFArrayRef CFLocaleCopyPreferredLanguages(void) { -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS - CFArrayRef languagesArray = (CFArrayRef)CFPreferencesCopyAppValue(CFSTR("AppleLanguages"), kCFPreferencesCurrentApplication); - CFArrayRef result = _CFLocaleCopyPreferredLanguagesFromPrefs(languagesArray); - if (languagesArray) CFRelease(languagesArray); - return result; -#else - return CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); + if (languagesArray) CFRelease(languagesArray); #endif + return newArray; } // -------- -------- -------- -------- -------- -------- @@ -1426,98 +1170,25 @@ static bool __CFLocaleCopyCollatorID(CFLocaleRef locale, bool user, CFTypeRef *c *cf = canonLocaleCFStr; return canonLocaleCFStr ? true : false; } - -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED -static CONST_STRING_DECL(_metricUnitsKey, "AppleMetricUnits"); -static CONST_STRING_DECL(_measurementUnitsKey, "AppleMeasurementUnits"); -static CONST_STRING_DECL(_measurementUnitsCentimeters, "Centimeters"); -static CONST_STRING_DECL(_measurementUnitsInches, "Inches"); -static CONST_STRING_DECL(_temperatureUnitKey, "AppleTemperatureUnit"); - -static bool __CFLocaleGetMeasurementSystemForPreferences(CFTypeRef metricPref, CFTypeRef measurementPref, UMeasurementSystem *outMeasurementSystem) { - if (metricPref || measurementPref) { - if (metricPref == kCFBooleanTrue && measurementPref && CFEqual(measurementPref, _measurementUnitsInches)) { - *outMeasurementSystem = UMS_UK; - } else if (metricPref == kCFBooleanFalse) { - *outMeasurementSystem = UMS_US; - } else { - *outMeasurementSystem = UMS_SI; - } - return true; - } - return false; -} - -static void __CFLocaleGetPreferencesForMeasurementSystem(UMeasurementSystem measurementSystem, CFTypeRef *outMetricPref, CFTypeRef *outMeasurementPref) { - *outMetricPref = measurementSystem != UMS_US? kCFBooleanTrue: kCFBooleanFalse; - *outMeasurementPref = measurementSystem == UMS_SI? _measurementUnitsCentimeters: _measurementUnitsInches; -} -#endif - -#if (U_ICU_VERSION_MAJOR_NUM > 54 || !defined(CF_OPEN_SOURCE)) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED) -static bool _CFLocaleGetTemperatureUnitForPreferences(CFTypeRef temperaturePref, bool *outCelsius) { - if (temperaturePref) { - if (CFEqual(temperaturePref, kCFLocaleTemperatureUnitCelsius)) { - *outCelsius = true; - return true; - } else if (CFEqual(temperaturePref, kCFLocaleTemperatureUnitFahrenheit)) { - *outCelsius = false; - return true; - } - } - return false; -} -#endif - -#if (U_ICU_VERSION_MAJOR_NUM > 54) || (!defined(CF_OPEN_SOURCE) && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED)) -static CFStringRef _CFLocaleGetTemperatureUnitName(bool celsius) { - return celsius? kCFLocaleTemperatureUnitCelsius: kCFLocaleTemperatureUnitFahrenheit; -} -#endif - -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX -static CFStringRef __CFLocaleGetMeasurementSystemName(UMeasurementSystem measurementSystem) { - switch (measurementSystem) { - case UMS_US: - return kCFLocaleMeasurementSystemUS; -#if U_ICU_VERSION_MAJOR_NUM >= 55 - case UMS_UK: - return kCFLocaleMeasurementSystemUK; -#endif - default: - break; - } - return kCFLocaleMeasurementSystemMetric; -} - -static bool __CFLocaleGetMeasurementSystemForName(CFStringRef name, UMeasurementSystem *outMeasurementSystem) { - if (name) { - if (CFEqual(name, kCFLocaleMeasurementSystemMetric)) { - *outMeasurementSystem = UMS_SI; - return true; - } - if (CFEqual(name, kCFLocaleMeasurementSystemUS)) { - *outMeasurementSystem = UMS_US; - return true; - } - if (CFEqual(name, kCFLocaleMeasurementSystemUK)) { - *outMeasurementSystem = UMS_UK; - return true; - } - } - return false; -} -#endif - + #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX static void __CFLocaleGetMeasurementSystemGuts(CFLocaleRef locale, bool user, UMeasurementSystem *outMeasurementSystem) { UMeasurementSystem output = UMS_SI; // Default is Metric bool done = false; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED - if (user) { - CFTypeRef metricPref = CFDictionaryGetValue(locale->_prefs, _metricUnitsKey); - CFTypeRef measurementPref = CFDictionaryGetValue(locale->_prefs, _measurementUnitsKey); - done = __CFLocaleGetMeasurementSystemForPreferences(metricPref, measurementPref, &output); + if (user && locale->_prefs) { + CFTypeRef metricPref = CFDictionaryGetValue(locale->_prefs, CFSTR("AppleMetricUnits")); + CFTypeRef measurementPref = CFDictionaryGetValue(locale->_prefs, CFSTR("AppleMeasurementUnits")); + if (metricPref || measurementPref) { + if (metricPref == kCFBooleanTrue && measurementPref && CFEqual(measurementPref, CFSTR("Inches"))) { + output = UMS_UK; + } else if (metricPref == kCFBooleanFalse) { + output = UMS_US; + } else { + output = UMS_SI; + } + done = true; + } } #endif if (!done) { @@ -1554,10 +1225,27 @@ static bool __CFLocaleCopyMeasurementSystem(CFLocaleRef locale, bool user, CFTyp #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX UMeasurementSystem system = UMS_SI; __CFLocaleGetMeasurementSystemGuts(locale, user, &system); - *cf = CFRetain(__CFLocaleGetMeasurementSystemName(system)); + switch (system) { + case UMS_US: + *cf = CFSTR("U.S."); + break; +#if U_ICU_VERSION_MAJOR_NUM >= 55 + case UMS_UK: + if ( + true + ) { + *cf = CFSTR("U.K."); + break; + } + //fall through to metric on older OSs +#endif + default: + *cf = CFSTR("Metric"); + break; + } return true; #else - *cf = CFRetain(kCFLocaleMeasurementSystemUS); //historical behavior, probably irrelevant in CF Mini + *cf = CFSTR("U.S."); //historical behavior, probably irrelevant in CF Mini return true; #endif } @@ -1569,9 +1257,17 @@ static bool __CFLocaleCopyTemperatureUnit(CFLocaleRef locale, bool user, CFTypeR bool celsius = true; // Default is Celsius bool done = false; #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED - if (user) { - CFTypeRef temperatureUnitPref = CFDictionaryGetValue(locale->_prefs, _temperatureUnitKey); - done = _CFLocaleGetTemperatureUnitForPreferences(temperatureUnitPref, &celsius); + if (user && locale->_prefs) { + CFTypeRef temperatureUnitPref = CFDictionaryGetValue(locale->_prefs, CFSTR("AppleTemperatureUnit")); + if (temperatureUnitPref) { + if (CFEqual(temperatureUnitPref, kCFLocaleTemperatureUnitFahrenheit)) { + celsius = false; + done = true; + } else if (CFEqual(temperatureUnitPref, kCFLocaleTemperatureUnitCelsius)) { + done = true; + } + // If set to anything else, fall back to locale default + } } #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX @@ -1603,7 +1299,11 @@ static bool __CFLocaleCopyTemperatureUnit(CFLocaleRef locale, bool user, CFTypeR if (!done) { celsius = true; } - *cf = CFRetain(_CFLocaleGetTemperatureUnitName(celsius)); + if (celsius) { + *cf = kCFLocaleTemperatureUnitCelsius; + } else { + *cf = kCFLocaleTemperatureUnitFahrenheit; + } return true; #else return false; @@ -1731,7 +1431,7 @@ static bool __CFLocaleFullName(const char *locale, const char *value, CFStringRe int32_t localSize; UChar localName[kMaxICUNameSize]; localSize = uloc_getDisplayLanguage(value, locale, localName, kMaxICUNameSize, &localStatus); - if (U_FAILURE(localStatus) || size <= 0 || localStatus == U_USING_DEFAULT_WARNING) + if (U_FAILURE(localStatus) || localSize <= 0 || localStatus == U_USING_DEFAULT_WARNING) return false; } diff --git a/CoreFoundation/Locale.subproj/CFLocale.h b/CoreFoundation/Locale.subproj/CFLocale.h index a7d2139c5c..7bf93cc770 100644 --- a/CoreFoundation/Locale.subproj/CFLocale.h +++ b/CoreFoundation/Locale.subproj/CFLocale.h @@ -1,7 +1,7 @@ /* CFLocale.h - Copyright (c) 2002-2017, Apple Inc. and the Swift project authors + Copyright (c) 2002-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -65,12 +65,12 @@ CFArrayRef CFLocaleCopyISOCurrencyCodes(void); // represent other financial instruments. CF_EXPORT -CFArrayRef CFLocaleCopyCommonISOCurrencyCodes(void) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFArrayRef CFLocaleCopyCommonISOCurrencyCodes(void) CF_AVAILABLE(10_5, 2_0); // Returns an array of CFStrings that represents ISO currency codes for // currencies in common use. CF_EXPORT -CFArrayRef CFLocaleCopyPreferredLanguages(void) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFArrayRef CFLocaleCopyPreferredLanguages(void) CF_AVAILABLE(10_5, 2_0); // Returns the array of canonicalized CFString locale IDs that the user prefers. CF_EXPORT @@ -88,11 +88,11 @@ CFLocaleIdentifier CFLocaleCreateCanonicalLocaleIdentifierFromScriptManagerCodes // Map a Mac OS LangCode and RegionCode to the canonical locale identifier. CF_EXPORT -CFLocaleIdentifier CFLocaleCreateLocaleIdentifierFromWindowsLocaleCode(CFAllocatorRef allocator, uint32_t lcid) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFLocaleIdentifier CFLocaleCreateLocaleIdentifierFromWindowsLocaleCode(CFAllocatorRef allocator, uint32_t lcid) CF_AVAILABLE(10_6, 4_0); // Map a Windows LCID to the canonical locale identifier. CF_EXPORT -uint32_t CFLocaleGetWindowsLocaleCodeFromLocaleIdentifier(CFLocaleIdentifier localeIdentifier) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +uint32_t CFLocaleGetWindowsLocaleCodeFromLocaleIdentifier(CFLocaleIdentifier localeIdentifier) CF_AVAILABLE(10_6, 4_0); // Map a locale identifier to a Windows LCID. typedef CF_ENUM(CFIndex, CFLocaleLanguageDirection) { @@ -104,10 +104,10 @@ typedef CF_ENUM(CFIndex, CFLocaleLanguageDirection) { }; CF_EXPORT -CFLocaleLanguageDirection CFLocaleGetLanguageCharacterDirection(CFStringRef isoLangCode) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFLocaleLanguageDirection CFLocaleGetLanguageCharacterDirection(CFStringRef isoLangCode) CF_AVAILABLE(10_6, 4_0); CF_EXPORT -CFLocaleLanguageDirection CFLocaleGetLanguageLineDirection(CFStringRef isoLangCode) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFLocaleLanguageDirection CFLocaleGetLanguageLineDirection(CFStringRef isoLangCode) CF_AVAILABLE(10_6, 4_0); CF_EXPORT CFDictionaryRef CFLocaleCreateComponentsFromLocaleIdentifier(CFAllocatorRef allocator, CFLocaleIdentifier localeID); @@ -154,7 +154,7 @@ CFStringRef CFLocaleCopyDisplayNameForPropertyValue(CFLocaleRef displayLocale, C // not all locale property keys have values with display name values. -CF_EXPORT const CFNotificationName kCFLocaleCurrentLocaleDidChangeNotification API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFNotificationName kCFLocaleCurrentLocaleDidChangeNotification CF_AVAILABLE(10_5, 2_0); // Locale Keys @@ -169,16 +169,16 @@ CF_EXPORT const CFLocaleKey kCFLocaleCalendarIdentifier; CF_EXPORT const CFLocaleKey kCFLocaleCalendar; CF_EXPORT const CFLocaleKey kCFLocaleCollationIdentifier; CF_EXPORT const CFLocaleKey kCFLocaleUsesMetricSystem; -CF_EXPORT const CFLocaleKey kCFLocaleMeasurementSystem; // "Metric", "U.S." or "U.K." +CF_EXPORT const CFLocaleKey kCFLocaleMeasurementSystem; // "Metric" or "U.S." CF_EXPORT const CFLocaleKey kCFLocaleDecimalSeparator; CF_EXPORT const CFLocaleKey kCFLocaleGroupingSeparator; CF_EXPORT const CFLocaleKey kCFLocaleCurrencySymbol; CF_EXPORT const CFLocaleKey kCFLocaleCurrencyCode; // ISO 3-letter currency code -CF_EXPORT const CFLocaleKey kCFLocaleCollatorIdentifier API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFLocaleKey kCFLocaleQuotationBeginDelimiterKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFLocaleKey kCFLocaleQuotationEndDelimiterKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFLocaleKey kCFLocaleAlternateQuotationBeginDelimiterKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFLocaleKey kCFLocaleAlternateQuotationEndDelimiterKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFLocaleKey kCFLocaleCollatorIdentifier CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFLocaleKey kCFLocaleQuotationBeginDelimiterKey CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFLocaleKey kCFLocaleQuotationEndDelimiterKey CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFLocaleKey kCFLocaleAlternateQuotationBeginDelimiterKey CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFLocaleKey kCFLocaleAlternateQuotationEndDelimiterKey CF_AVAILABLE(10_6, 4_0); // Values for kCFLocaleCalendarIdentifier typedef CFStringRef CFCalendarIdentifier CF_STRING_ENUM; @@ -190,12 +190,12 @@ CF_EXPORT const CFCalendarIdentifier kCFHebrewCalendar; CF_EXPORT const CFCalendarIdentifier kCFIslamicCalendar; CF_EXPORT const CFCalendarIdentifier kCFIslamicCivilCalendar; CF_EXPORT const CFCalendarIdentifier kCFJapaneseCalendar; -CF_EXPORT const CFCalendarIdentifier kCFRepublicOfChinaCalendar API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFCalendarIdentifier kCFPersianCalendar API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFCalendarIdentifier kCFIndianCalendar API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFCalendarIdentifier kCFISO8601Calendar API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFCalendarIdentifier kCFIslamicTabularCalendar API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFCalendarIdentifier kCFIslamicUmmAlQuraCalendar API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFCalendarIdentifier kCFRepublicOfChinaCalendar CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFCalendarIdentifier kCFPersianCalendar CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFCalendarIdentifier kCFIndianCalendar CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFCalendarIdentifier kCFISO8601Calendar CF_AVAILABLE(10_6, 4_0); +CF_EXPORT const CFCalendarIdentifier kCFIslamicTabularCalendar CF_AVAILABLE(10_10, 8_0); +CF_EXPORT const CFCalendarIdentifier kCFIslamicUmmAlQuraCalendar CF_AVAILABLE(10_10, 8_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c b/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c index ee41444d17..582d129fcd 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c +++ b/CoreFoundation/Locale.subproj/CFLocaleIdentifier.c @@ -1,8 +1,8 @@ /* CFLocaleIdentifier.c - Copyright (c) 2002-2017, Apple Inc. and the Swift project authors + Copyright (c) 2002-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFLocaleInternal.h b/CoreFoundation/Locale.subproj/CFLocaleInternal.h index ebeffe286c..73d9892a9b 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleInternal.h +++ b/CoreFoundation/Locale.subproj/CFLocaleInternal.h @@ -1,8 +1,8 @@ /* CFLocaleInternal.h - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Locale.subproj/CFLocaleKeys.c b/CoreFoundation/Locale.subproj/CFLocaleKeys.c index d908c8cf2b..180962e853 100644 --- a/CoreFoundation/Locale.subproj/CFLocaleKeys.c +++ b/CoreFoundation/Locale.subproj/CFLocaleKeys.c @@ -1,7 +1,7 @@ /* CFLocaleKeys.c - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -28,9 +28,6 @@ CONST_STRING_DECL(kCFLocaleGroupingSeparatorKey, "kCFLocaleGroupingSeparatorKey" CONST_STRING_DECL(kCFLocaleIdentifierKey, "kCFLocaleIdentifierKey"); CONST_STRING_DECL(kCFLocaleLanguageCodeKey, "kCFLocaleLanguageCodeKey"); CONST_STRING_DECL(kCFLocaleMeasurementSystemKey, "kCFLocaleMeasurementSystemKey"); -CONST_STRING_DECL(kCFLocaleMeasurementSystemMetric, "Metric"); -CONST_STRING_DECL(kCFLocaleMeasurementSystemUS, "U.S."); -CONST_STRING_DECL(kCFLocaleMeasurementSystemUK, "U.K."); CONST_STRING_DECL(kCFLocaleTemperatureUnitKey, "kCFLocaleTemperatureUnitKey"); CONST_STRING_DECL(kCFLocaleTemperatureUnitCelsius, "Celsius"); CONST_STRING_DECL(kCFLocaleTemperatureUnitFahrenheit, "Fahrenheit"); diff --git a/CoreFoundation/Locale.subproj/CFLocale_Private.h b/CoreFoundation/Locale.subproj/CFLocale_Private.h index d449665578..a46457bed8 100644 --- a/CoreFoundation/Locale.subproj/CFLocale_Private.h +++ b/CoreFoundation/Locale.subproj/CFLocale_Private.h @@ -1,7 +1,7 @@ /* CFLocale_Private.h - Copyright (c) 2016-2017, Apple Inc. and the Swift project authors + Copyright (c) 2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -12,9 +12,6 @@ #include -/// Returns the user’s preferred locale as-is, without attempting to match the locale’s language to the main bundle, unlike `CFLocaleCopyCurrent`. -CF_EXPORT CFLocaleRef _CFLocaleCopyPreferred(void) API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - typedef CF_ENUM(CFIndex, _CFLocaleCalendarDirection) { _kCFLocaleCalendarDirectionLeftToRight = 0, _kCFLocaleCalendarDirectionRightToLeft = 1 @@ -22,11 +19,6 @@ typedef CF_ENUM(CFIndex, _CFLocaleCalendarDirection) { CF_EXPORT _CFLocaleCalendarDirection _CFLocaleGetCalendarDirection(void) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); -CF_EXPORT const CFLocaleKey kCFLocaleMeasurementSystem API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); -CF_EXPORT const CFStringRef kCFLocaleMeasurementSystemMetric API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); -CF_EXPORT const CFStringRef kCFLocaleMeasurementSystemUS API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); -CF_EXPORT const CFStringRef kCFLocaleMeasurementSystemUK API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - CF_EXPORT const CFLocaleKey kCFLocaleTemperatureUnit API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); CF_EXPORT const CFStringRef kCFLocaleTemperatureUnitCelsius API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); CF_EXPORT const CFStringRef kCFLocaleTemperatureUnitFahrenheit API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); diff --git a/CoreFoundation/Locale.subproj/CFNumberFormatter.c b/CoreFoundation/Locale.subproj/CFNumberFormatter.c index 8076fbb9d0..fe7fa10ae8 100644 --- a/CoreFoundation/Locale.subproj/CFNumberFormatter.c +++ b/CoreFoundation/Locale.subproj/CFNumberFormatter.c @@ -1,7 +1,7 @@ /* CFNumberFormatter.c - Copyright (c) 2002-2017, Apple Inc. and the Swift project authors + Copyright (c) 2002-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -21,7 +21,7 @@ static void __CFNumberFormatterCustomize(CFNumberFormatterRef formatter); static CFStringRef __CFNumberFormatterCreateCompressedString(CFStringRef inString, Boolean isFormat, CFRange *rangep); static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter, CFStringRef pattern); -static CONST_STRING_DECL(kCFNumberFormatterFormattingContextKey, "kCFNumberFormatterFormattingContextKey"); +CONST_STRING_DECL(kCFNumberFormatterFormattingContextKey, "kCFNumberFormatterFormattingContextKey"); #define BUFFER_SIZE 768 @@ -314,7 +314,7 @@ static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter if (kCFNumberFormatterDurationStyle == formatter->_style) return U_UNSUPPORTED_ERROR; if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style) return U_UNSUPPORTED_ERROR; CFIndex cnt = CFStringGetLength(pattern); - SAFE_STACK_BUFFER_DECL(UChar, ubuffer, cnt, 256); + STACK_BUFFER_DECL(UChar, ubuffer, cnt); const UChar *ustr = (const UChar *)CFStringGetCharactersPtr(pattern); if (NULL == ustr) { CFStringGetCharacters(pattern, CFRangeMake(0, cnt), (UniChar *)ubuffer); @@ -322,7 +322,6 @@ static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter } UErrorCode status = U_ZERO_ERROR; __cficu_unum_applyPattern(formatter->_nf, false, ustr, cnt, NULL, &status); - SAFE_STACK_BUFFER_CLEANUP(ubuffer); // __cficu_unum_applyPattern() may have magically changed other attributes based on // the contents of the format string; we simply expose that ICU behavior, except diff --git a/CoreFoundation/Locale.subproj/CFNumberFormatter.h b/CoreFoundation/Locale.subproj/CFNumberFormatter.h index cca3177200..a69e9eb74e 100644 --- a/CoreFoundation/Locale.subproj/CFNumberFormatter.h +++ b/CoreFoundation/Locale.subproj/CFNumberFormatter.h @@ -1,7 +1,7 @@ /* CFNumberFormatter.h - Copyright (c) 2003-2017, Apple Inc. and the Swift project authors + Copyright (c) 2003-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -33,10 +33,10 @@ typedef CF_ENUM(CFIndex, CFNumberFormatterStyle) { // number format styles kCFNumberFormatterPercentStyle = 3, kCFNumberFormatterScientificStyle = 4, kCFNumberFormatterSpellOutStyle = 5, - kCFNumberFormatterOrdinalStyle API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 6, - kCFNumberFormatterCurrencyISOCodeStyle API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 8, - kCFNumberFormatterCurrencyPluralStyle API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 9, - kCFNumberFormatterCurrencyAccountingStyle API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) = 10, + kCFNumberFormatterOrdinalStyle CF_ENUM_AVAILABLE(10_11, 9_0) = 6, + kCFNumberFormatterCurrencyISOCodeStyle CF_ENUM_AVAILABLE(10_11, 9_0) = 8, + kCFNumberFormatterCurrencyPluralStyle CF_ENUM_AVAILABLE(10_11, 9_0) = 9, + kCFNumberFormatterCurrencyAccountingStyle CF_ENUM_AVAILABLE(10_11, 9_0) = 10, }; @@ -135,11 +135,11 @@ CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterNegativePrefix; // CFStr CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterNegativeSuffix; // CFString CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterPerMillSymbol; // CFString CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterInternationalCurrencySymbol; // CFString -CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterCurrencyGroupingSeparator API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFString -CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterIsLenient API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFBoolean -CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterUseSignificantDigits API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFBoolean -CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterMinSignificantDigits API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFNumber -CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterMaxSignificantDigits API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); // CFNumber +CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterCurrencyGroupingSeparator CF_AVAILABLE(10_5, 2_0); // CFString +CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterIsLenient CF_AVAILABLE(10_5, 2_0); // CFBoolean +CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterUseSignificantDigits CF_AVAILABLE(10_5, 2_0); // CFBoolean +CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterMinSignificantDigits CF_AVAILABLE(10_5, 2_0); // CFNumber +CF_EXPORT const CFNumberFormatterKey kCFNumberFormatterMaxSignificantDigits CF_AVAILABLE(10_5, 2_0); // CFNumber typedef CF_ENUM(CFIndex, CFNumberFormatterRoundingMode) { kCFNumberFormatterRoundCeiling = 0, diff --git a/CoreFoundation/NumberDate.subproj/CFBigNumber.c b/CoreFoundation/NumberDate.subproj/CFBigNumber.c index 453bbbb044..622a4aba4c 100644 --- a/CoreFoundation/NumberDate.subproj/CFBigNumber.c +++ b/CoreFoundation/NumberDate.subproj/CFBigNumber.c @@ -1,7 +1,7 @@ /* CFBigNumber.c - Copyright (c) 2012-2017, Apple Inc. and the Swift project authors + Copyright (c) 2012-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFBigNumber.h b/CoreFoundation/NumberDate.subproj/CFBigNumber.h index 48c4d4dd93..9b8e4c612f 100644 --- a/CoreFoundation/NumberDate.subproj/CFBigNumber.h +++ b/CoreFoundation/NumberDate.subproj/CFBigNumber.h @@ -1,7 +1,7 @@ /* CFBigNumber.h - Copyright (c) 2012-2017, Apple Inc. and the Swift project authors + Copyright (c) 2012-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFDate.c b/CoreFoundation/NumberDate.subproj/CFDate.c index 823e8f7b02..77626bcc4d 100644 --- a/CoreFoundation/NumberDate.subproj/CFDate.c +++ b/CoreFoundation/NumberDate.subproj/CFDate.c @@ -1,7 +1,7 @@ /* CFDate.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -223,12 +223,8 @@ CF_INLINE double __CFDoubleMod(double d, int32_t modulus) { return result; } -#define INVALID_MONTH_RESULT (0xffff) -#define CHECK_BOUNDS(month, array) ((month) >= 0 && (month) < (sizeof(array) / sizeof(*(array)))) -#define ASSERT_VALID_MONTH(month) do { if (!((month) >= 1 && (month) <= 12)) { os_log_error(OS_LOG_DEFAULT, "Month %d is out of bounds", (int)month); /* HALT */ } } while(0) - static const uint8_t daysInMonth[16] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 0, 0, 0}; -static const uint16_t daysBeforeMonth[16] = {INVALID_MONTH_RESULT, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, INVALID_MONTH_RESULT, INVALID_MONTH_RESULT}; +static const uint16_t daysBeforeMonth[16] = {0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365, 0, 0}; static const uint16_t daysAfterMonth[16] = {365, 334, 306, 275, 245, 214, 184, 153, 122, 92, 61, 31, 0, 0, 0, 0}; CF_INLINE bool isleap(int64_t year) { @@ -239,32 +235,17 @@ CF_INLINE bool isleap(int64_t year) { /* year arg is absolute year; Gregorian 2001 == year 0; 2001/1/1 = absolute date 0 */ CF_INLINE uint8_t __CFDaysInMonth(int8_t month, int64_t year, bool leap) { - if (CHECK_BOUNDS(month, daysInMonth)) { - return daysInMonth[month] + (2 == month && leap); - } else { - // All internal usages of this are already audited and should provide valid dates. Make sure it stays that way. - HALT; - } + return daysInMonth[month] + (2 == month && leap); } /* year arg is absolute year; Gregorian 2001 == year 0; 2001/1/1 = absolute date 0 */ CF_INLINE uint16_t __CFDaysBeforeMonth(int8_t month, int64_t year, bool leap) { - if (CHECK_BOUNDS(month, daysBeforeMonth)) { - return daysBeforeMonth[month] + (2 < month && leap); - } else { - // We can't HALT here, as there are various ways for out of range month values to enter here. - return INVALID_MONTH_RESULT; - } + return daysBeforeMonth[month] + (2 < month && leap); } /* year arg is absolute year; Gregorian 2001 == year 0; 2001/1/1 = absolute date 0 */ CF_INLINE uint16_t __CFDaysAfterMonth(int8_t month, int64_t year, bool leap) { - if (CHECK_BOUNDS(month, daysAfterMonth)) { - return daysAfterMonth[month] + (month < 2 && leap); - } else { - // All internal usages of this are already audited and should provide valid dates. Make sure it stays that way. - HALT; - } + return daysAfterMonth[month] + (month < 2 && leap); } /* year arg is absolute year; Gregorian 2001 == year 0; 2001/1/1 = absolute date 0 */ @@ -289,16 +270,9 @@ static void __CFYMDFromAbsolute(int64_t absolute, int64_t *year, int8_t *month, if (month || day) { int8_t m = absolute / 33 + 1; /* search from the approximation */ bool leap = isleap(y); - - // Calculations above should guarantee that 0 <= absolute < 336, meaning 1 <= m <= 11 and that __CFDaysBeforeMonth(m + 1, …) will at some point be > absolute. - ASSERT_VALID_MONTH(m); - ASSERT_VALID_MONTH(m + 1); - while (__CFDaysBeforeMonth(m + 1, y, leap) <= absolute) { - m++; - ASSERT_VALID_MONTH(m + 1); - } - if (month) *month = m; - if (day) *day = absolute - __CFDaysBeforeMonth(m, y, leap) + 1; + while (__CFDaysBeforeMonth(m + 1, y, leap) <= absolute) m++; + if (month) *month = m; + if (day) *day = absolute - __CFDaysBeforeMonth(m, y, leap) + 1; } } @@ -317,11 +291,7 @@ static double __CFAbsoluteFromYMD(int64_t year, int8_t month, int8_t day) { absolute += __CFDaysAfterMonth(0, idx, isleap(idx)); } /* Now add the days into the original year */ - uint16_t const daysBeforeMonth = __CFDaysBeforeMonth(month, year, isleap(year)); - if (daysBeforeMonth != INVALID_MONTH_RESULT) { - absolute += daysBeforeMonth; - } // else, the results of this have always been undefined, since it involves reading off the end of the array, so just "add zero". - absolute += day - 1; + absolute += __CFDaysBeforeMonth(month, year, isleap(year)) + day - 1; return absolute; } @@ -332,10 +302,7 @@ Boolean CFGregorianDateIsValid(CFGregorianDate gdate, CFOptionFlags unitFlags) { if ((unitFlags & kCFGregorianUnitsHours) && (gdate.hour < 0 || 23 < gdate.hour)) return false; if ((unitFlags & kCFGregorianUnitsMinutes) && (gdate.minute < 0 || 59 < gdate.minute)) return false; if ((unitFlags & kCFGregorianUnitsSeconds) && (gdate.second < 0.0 || 60.0 <= gdate.second)) return false; - if ((unitFlags & kCFGregorianUnitsDays) && (unitFlags & kCFGregorianUnitsMonths) && (unitFlags & kCFGregorianUnitsYears)) { - ASSERT_VALID_MONTH(gdate.month); // Checks above should confirm this. - return __CFDaysInMonth(gdate.month, gdate.year - 2001, isleap(gdate.year - 2001)) >= gdate.day; - } + if ((unitFlags & kCFGregorianUnitsDays) && (unitFlags & kCFGregorianUnitsMonths) && (unitFlags & kCFGregorianUnitsYears) && (__CFDaysInMonth(gdate.month, gdate.year - 2001, isleap(gdate.year - 2001)) < gdate.day)) return false; return true; } @@ -435,7 +402,6 @@ CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef working.months += 12; working.years -= 1; } - ASSERT_VALID_MONTH(working.months); monthdays = __CFDaysInMonth(working.months, working.years - 2001, isleap(working.years - 2001)); if (monthdays < working.days) { /* Clamp day to new month */ working.days = monthdays; @@ -448,7 +414,6 @@ CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef working.years += 1; } working.days -= monthdays; - ASSERT_VALID_MONTH(working.months); monthdays = __CFDaysInMonth(working.months, working.years - 2001, isleap(working.years - 2001)); } while (working.days < 1) { @@ -457,7 +422,6 @@ CFAbsoluteTime CFAbsoluteTimeAddGregorianUnits(CFAbsoluteTime at, CFTimeZoneRef working.months += 12; working.years -= 1; } - ASSERT_VALID_MONTH(working.months); monthdays = __CFDaysInMonth(working.months, working.years - 2001, isleap(working.years - 2001)); working.days += monthdays; } @@ -535,7 +499,6 @@ SInt32 CFAbsoluteTimeGetDayOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) { #endif absolute = (int64_t)floor(fixedat / 86400.0); __CFYMDFromAbsolute(absolute, &year, &month, &day); - ASSERT_VALID_MONTH(month); // __CFYMDFromAbsolute always gives valid months return __CFDaysBeforeMonth(month, year, isleap(year)) + day; } @@ -570,7 +533,6 @@ SInt32 CFAbsoluteTimeGetWeekOfYear(CFAbsoluteTime at, CFTimeZoneRef tz) { } } /* Days into year, plus a week-shifting correction, divided by 7. First week is 1. */ - ASSERT_VALID_MONTH(month); // __CFYMDFromAbsolute always gives valid months return (__CFDaysBeforeMonth(month, year, isleap(year)) + day + (dow0101 - 11) % 7 + 2) / 7 + 1; } diff --git a/CoreFoundation/NumberDate.subproj/CFDate.h b/CoreFoundation/NumberDate.subproj/CFDate.h index ba303b65e6..3ab34baa38 100644 --- a/CoreFoundation/NumberDate.subproj/CFDate.h +++ b/CoreFoundation/NumberDate.subproj/CFDate.h @@ -1,7 +1,7 @@ /* CFDate.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/NumberDate.subproj/CFNumber.c b/CoreFoundation/NumberDate.subproj/CFNumber.c index 163a329854..935780eaa3 100644 --- a/CoreFoundation/NumberDate.subproj/CFNumber.c +++ b/CoreFoundation/NumberDate.subproj/CFNumber.c @@ -1,7 +1,7 @@ /* CFNumber.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -15,64 +15,6 @@ #include -enum { - kCFNumberSInt128Type = 17 -}; - -typedef CF_ENUM(uint8_t, _CFNumberCanonicalTypeIndex) { - kCFNumberSInt8CanonicalTypeIndex = 0x0, - kCFNumberSInt16CanonicalTypeIndex = 0x1, - kCFNumberSInt32CanonicalTypeIndex = 0x2, - kCFNumberSInt64CanonicalTypeIndex = 0x3, - kCFNumberFloat32CanonicalTypeIndex = 0x4, - kCFNumberFloat64CanonicalTypeIndex = 0x5, - kCFNumberSInt128CanonicalTypeIndex = 0x6, -}; - -static const CFNumberType __CFNumberCanonicalTypes[] = { - [kCFNumberSInt8CanonicalTypeIndex] = kCFNumberSInt8Type, - [kCFNumberSInt16CanonicalTypeIndex] = kCFNumberSInt16Type, - [kCFNumberSInt32CanonicalTypeIndex] = kCFNumberSInt32Type, - [kCFNumberSInt64CanonicalTypeIndex] = kCFNumberSInt64Type, - [kCFNumberFloat32CanonicalTypeIndex] = kCFNumberFloat32Type, - [kCFNumberFloat64CanonicalTypeIndex] = kCFNumberFloat64Type, - [kCFNumberSInt128CanonicalTypeIndex] = kCFNumberSInt128Type, -}; - -static const uint8_t __CFNumberCanonicalTypeIndex[] = { - [kCFNumberSInt8Type] = kCFNumberSInt8CanonicalTypeIndex, - [kCFNumberSInt16Type] = kCFNumberSInt16CanonicalTypeIndex, - [kCFNumberSInt32Type] = kCFNumberSInt32CanonicalTypeIndex, - [kCFNumberSInt64Type] = kCFNumberSInt64CanonicalTypeIndex, - [kCFNumberFloat32Type] = kCFNumberFloat32CanonicalTypeIndex, - [kCFNumberFloat64Type] = kCFNumberFloat64CanonicalTypeIndex, - [kCFNumberSInt128Type] = kCFNumberSInt128CanonicalTypeIndex, -}; - -/* - ____ ____ ____ ____ ____ ____ ____ ____ - 63 47 32 - ____ ____ ____ ____ ____ ____ __pp fttt - 31 15 0 - - t: The type index of the canonical type - f: A flag to tell if the type is a preserved type or a non preserved type (1 means preserved 0 means not preserved) - p: Bits reserved for reinterpreting both the range of `p` and `t` as a preserved type - _: Bits reserved for the remainder of the CFRuntime field. - -*/ - -// NOTE: Only 6 bits are allowed in the runtime values! -#define __CFRuntimeGetNumberType(num) (__CFNumberCanonicalTypes[__CFRuntimeGetValue((num), 5, 0) & 0x7]) -#define __CFRuntimeGetNumberPreservedType(num) (__CFRuntimeGetValue((num), 5, 0) & 0x3f) - -#define __CFRuntimeSetNumberType(num, type) (__CFRuntimeSetValue((num), 5, 0, (__CFNumberCanonicalTypeIndex[type] & 0x7))) -#define __CFRuntimeSetNumberPreservedType(num, type) (__CFRuntimeSetValue((num), 5, 0, (type & 0x3f))) - -#define __CFRuntimeIsPreservedNumber(num) (__CFRuntimeGetValue((num), 5, 0) & 0x8) - - - #if DEPLOYMENT_TARGET_WINDOWS #define isnan(A) _isnan(A) #define isinf(A) !_finite(A) @@ -140,12 +82,46 @@ CFTypeID CFBooleanGetTypeID(void) { Boolean CFBooleanGetValue(CFBooleanRef boolean) { CF_OBJC_FUNCDISPATCHV(CFBooleanGetTypeID(), Boolean, (NSNumber *)boolean, boolValue); + CF_SWIFT_FUNCDISPATCHV(CFBooleanGetTypeID(), Boolean, (CFSwiftRef)boolean, NSNumber.boolValue); return (boolean == kCFBooleanTrue) ? true : false; } /*** CFNumber ***/ +#define OLD_CRAP_TOO 0 + +#if OLD_CRAP_TOO + +// old implementation, for runtime comparison purposes + +typedef union { + SInt32 valSInt32; + int64_t valSInt64; + Float32 valFloat32; + Float64 valFloat64; +} __CFNumberValue_old; + +struct __CFNumber_old { /* Only as many bytes as necessary are allocated */ + CFRuntimeBase _base; + __CFNumberValue_old value; +}; + +static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2); +static CFHashCode __CFNumberHash_old(CFTypeRef cf); +static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf); +CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf); +static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions); +static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr); +static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number); +static CFIndex CFNumberGetByteSize_old(struct __CFNumber_old * number); +static Boolean CFNumberIsFloatType_old(struct __CFNumber_old * number); +static Boolean CFNumberGetValue_old(struct __CFNumber_old * number, CFNumberType type, void *valuePtr); +static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, struct __CFNumber_old * number2, void *context); + +#endif + + #define __CFAssertIsNumber(cf) __CFGenericValidateType(cf, CFNumberGetTypeID()) #define __CFAssertIsValidNumberType(type) CFAssert2((0 < type && type <= kCFNumberMaxType) || (type == kCFNumberSInt128Type), __kCFLogAssertion, "%s(): bad CFNumber type %ld", __PRETTY_FUNCTION__, type); @@ -198,6 +174,10 @@ typedef struct { // NOTE WELL: these two fields may switch position someday, do uint64_t low; } CFSInt128Struct; +enum { + kCFNumberSInt128Type = 17 +}; + static uint8_t isNeg128(const CFSInt128Struct *in) { return in->high < 0; } @@ -380,6 +360,10 @@ static void cvtFloat64ToSInt128(CFSInt128Struct *out, const Float64 *in) { struct __CFNumber { CFRuntimeBase _base; +#if OLD_CRAP_TOO + struct __CFNumber_old *__old__; + void * __dummy__; +#endif uint64_t _pad; // need this space here for the constant objects /* 0 or 8 more bytes allocated here */ }; @@ -467,7 +451,7 @@ static const struct { }; CF_INLINE CFNumberType __CFNumberGetType(CFNumberRef num) { - return __CFRuntimeGetNumberType(num); + return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0); } #define CVT(SRC_TYPE, DST_TYPE, DST_MIN, DST_MAX) do { \ @@ -847,6 +831,10 @@ static Boolean __CFNumberGetValueCompat(CFNumberRef number, CFNumberType type, v return false; } +#if OLD_CRAP_TOO +static void FAIL(void) {} +#endif + static CFStringRef __CFNumberCopyDescription(CFTypeRef cf) { CFNumberRef number = (CFNumberRef)cf; CFNumberType type = __CFNumberGetType(number); @@ -885,6 +873,17 @@ static CFStringRef __CFNumberCopyDescription(CFTypeRef cf) { } CFStringAppendFormat(mstr, NULL, CFSTR("%s, type = %s}"), buffer, typeName); } +#if OLD_CRAP_TOO +if (! number->__old__) { + +printf("*** Test skipped in __CFNumberCopyDescription for number %p\n", cf); +} else { +CFStringRef test = __CFNumberCopyDescription_old(number->__old__); +if (!CFEqual(test, mstr)) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyDescription: '%@' '%@'"), test, mstr); FAIL(); +} +} +#endif return mstr; } @@ -908,6 +907,17 @@ static CFStringRef __CFNumberCreateFormattingDescriptionAsFloat64(CFAllocatorRef CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64(CFTypeRef cf) { CFStringRef result = __CFNumberCreateFormattingDescriptionAsFloat64(kCFAllocatorSystemDefault, cf); +#if OLD_CRAP_TOO +CFNumberRef number = (CFNumberRef)cf; +if (! number->__old__) { +printf("*** Test skipped in __CFNumberCopyFormattingDescriptionAsFloat64 for number %p\n", cf); +} else { +CFStringRef test = __CFNumberCopyFormattingDescriptionAsFloat64_old(number->__old__); +if (!CFEqual(test, result)) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyFormattingDescriptionAsFloat64: '%@' '%@'"), test, result); FAIL(); +} +} +#endif return result; } @@ -939,12 +949,35 @@ static CFStringRef __CFNumberCopyFormattingDescription_new(CFTypeRef cf, CFDicti CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) { CFStringRef result = __CFNumberCopyFormattingDescription_new(cf, formatOptions); +#if OLD_CRAP_TOO +CFNumberRef number = (CFNumberRef)cf; +if (! number->__old__) { +printf("*** Test skipped in __CFNumberCopyFormattingDescription for number %p\n", cf); +} else { +CFStringRef test = __CFNumberCopyFormattingDescription_old(number->__old__, formatOptions); +if (!CFEqual(test, result)) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyFormattingDescription: '%@' '%@'"), test, result); FAIL(); +} +} +#endif return result; } static Boolean __CFNumberEqual(CFTypeRef cf1, CFTypeRef cf2) { Boolean b = CFNumberCompare((CFNumberRef)cf1, (CFNumberRef)cf2, 0) == kCFCompareEqualTo; +#if OLD_CRAP_TOO +CFNumberRef number1 = (CFNumberRef)cf1; +CFNumberRef number2 = (CFNumberRef)cf2; +if (! number1->__old__ || !number2->__old__) { +printf("*** Test skipped in __CFNumberEqual for numbers %p %p\n", cf1, cf2); +} else { +Boolean b2 = __CFNumberEqual_old(number1->__old__, number2->__old__); +if (b2 != b) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberEqual: '%d' '%d'"), b2, b); FAIL(); +} +} +#endif return b; } @@ -967,6 +1000,17 @@ static CFHashCode __CFNumberHash(CFTypeRef cf) { break; } } +#if OLD_CRAP_TOO +CFNumberRef number1 = (CFNumberRef)cf; +if (! number1->__old__) { +printf("*** Test skipped in __CFNumberHash for number %p\n", cf); +} else { +CFHashCode h2 = __CFNumberHash_old(number1->__old__); +if (h2 != h) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberHash: '%d' '%d'"), h2, h); FAIL(); +} +} +#endif return h; } @@ -994,35 +1038,35 @@ static const CFRuntimeClass __CFNumberClass = { CF_PRIVATE void __CFNumberInitialize(void) { _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFNumberNaN, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberNaN, kCFNumberFloat64Type); + __CFBitfieldSetValue(__kCFNumberNaN._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type); __kCFNumberNaN._pad = BITSFORDOUBLENAN; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberNegativeInfinity, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberNegativeInfinity, kCFNumberFloat64Type); + __CFBitfieldSetValue(__kCFNumberNegativeInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type); __kCFNumberNegativeInfinity._pad = BITSFORDOUBLENEGINF; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberPositiveInfinity, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberPositiveInfinity, kCFNumberFloat64Type); + __CFBitfieldSetValue(__kCFNumberPositiveInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type); __kCFNumberPositiveInfinity._pad = BITSFORDOUBLEPOSINF; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberFloat32Zero, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberFloat32Zero, kCFNumberFloat32Type); + __CFBitfieldSetValue(__kCFNumberFloat32Zero._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat32Type); __kCFNumberFloat32Zero._pad = BITSFORFLOATZERO; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberFloat32One, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberFloat32One, kCFNumberFloat32Type); + __CFBitfieldSetValue(__kCFNumberFloat32One._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat32Type); __kCFNumberFloat32One._pad = BITSFORFLOATONE; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberFloat64Zero, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberFloat64Zero, kCFNumberFloat64Type); + __CFBitfieldSetValue(__kCFNumberFloat64Zero._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type); __kCFNumberFloat64Zero._pad = BITSFORDOUBLEZERO; _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberFloat64One, __kCFNumberTypeID); - __CFRuntimeSetNumberType(&__kCFNumberFloat64One, kCFNumberFloat64Type); + __CFBitfieldSetValue(__kCFNumberFloat64One._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type); __kCFNumberFloat64One._pad = BITSFORDOUBLEONE; #if DEPLOYMENT_RUNTIME_SWIFT - _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanTrue, __kCFBooleanTypeID); - _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanFalse, __kCFBooleanTypeID); + _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFBooleanTrue, __kCFBooleanTypeID); + _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFBooleanFalse, __kCFBooleanTypeID); #endif } @@ -1046,7 +1090,7 @@ CFTypeID CFNumberGetTypeID(void) { #define NotToBeCached (MinCachedInt - 1) static CFNumberRef __CFNumberCache[MaxCachedInt - MinCachedInt + 1] = {NULL}; // Storing CFNumberRefs for range MinCachedInt..MaxCachedInt -static inline void __CFNumberInit(CFNumberRef result, CFNumberType type, const void *valuePtr) { +static inline void _CFNumberInit(CFNumberRef result, CFNumberType type, const void *valuePtr) { __CFAssertIsValidNumberType(type); uint64_t value; @@ -1060,10 +1104,14 @@ static inline void __CFNumberInit(CFNumberRef result, CFNumberType type, const v case kCFNumberFloat32Type: memmove((void *)&result->_pad, valuePtr, 4); break; case kCFNumberFloat64Type: memmove((void *)&result->_pad, valuePtr, 8); break; } + __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)__CFNumberTypeTable[type].canonicalType); } -static inline void _CFNumberInit(CFNumberRef result, CFNumberType type, const void *valuePtr) { - __CFNumberInit(result, type, valuePtr); +void _CFNumberInitInt128(CFNumberRef result, int64_t value) { + CFSInt128Struct int128value; + int128value.high = 0; + int128value.low = value; + _CFNumberInit(result, kCFNumberSInt128Type, &int128value); } void _CFNumberInitBool(CFNumberRef result, Boolean value) { @@ -1075,7 +1123,11 @@ void _CFNumberInitInt8(CFNumberRef result, int8_t value) { } void _CFNumberInitUInt8(CFNumberRef result, uint8_t value) { - _CFNumberInit(result, kCFNumberCharType, &value); + if (value > INT8_MAX) { + _CFNumberInitInt16(result, value); + } else { + _CFNumberInit(result, kCFNumberCharType, &value); + } } void _CFNumberInitInt16(CFNumberRef result, int16_t value) { @@ -1083,7 +1135,11 @@ void _CFNumberInitInt16(CFNumberRef result, int16_t value) { } void _CFNumberInitUInt16(CFNumberRef result, uint16_t value) { - _CFNumberInit(result, kCFNumberShortType, &value); + if (value > INT16_MAX) { + _CFNumberInitInt32(result, value); + } else { + _CFNumberInit(result, kCFNumberShortType, &value); + } } void _CFNumberInitInt32(CFNumberRef result, int32_t value) { @@ -1091,7 +1147,11 @@ void _CFNumberInitInt32(CFNumberRef result, int32_t value) { } void _CFNumberInitUInt32(CFNumberRef result, uint32_t value) { - _CFNumberInit(result, kCFNumberIntType, &value); + if (value > INT32_MAX) { + _CFNumberInitInt64(result, value); + } else { + _CFNumberInit(result, kCFNumberIntType, &value); + } } void _CFNumberInitInt(CFNumberRef result, long value) { @@ -1099,7 +1159,22 @@ void _CFNumberInitInt(CFNumberRef result, long value) { } void _CFNumberInitUInt(CFNumberRef result, unsigned long value) { - _CFNumberInit(result, kCFNumberLongType, &value); + if (value > LONG_MAX) { + switch (sizeof(unsigned long)) { + case 4: + _CFNumberInitInt64(result, value); + break; + + case 8: + _CFNumberInitInt128(result, value); + break; + + default: + CFAssert1(false, __kCFLogAssertion, "Unexpected unsigned long type size: %d", sizeof(unsigned long)); + } + } else { + _CFNumberInit(result, kCFNumberLongType, &value); + } } void _CFNumberInitInt64(CFNumberRef result, int64_t value) { @@ -1107,7 +1182,11 @@ void _CFNumberInitInt64(CFNumberRef result, int64_t value) { } void _CFNumberInitUInt64(CFNumberRef result, uint64_t value) { - _CFNumberInit(result, kCFNumberLongLongType, &value); + if (value > INT64_MAX) { + _CFNumberInitInt128(result, value); + } else { + _CFNumberInit(result, kCFNumberLongLongType, &value); + } } void _CFNumberInitFloat(CFNumberRef result, float value) { @@ -1118,7 +1197,7 @@ void _CFNumberInitDouble(CFNumberRef result, double value) { _CFNumberInit(result, kCFNumberDoubleType, &value); } -static CFNumberRef _CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) { +CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) { __CFAssertIsValidNumberType(type); //printf("+ [%p] CFNumberCreate(%p, %d, %p)\n", pthread_self(), allocator, type, valuePtr); @@ -1132,48 +1211,54 @@ static CFNumberRef _CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, // regardless of allocator, since that is what has always // been done (and now must for compatibility). int64_t valToBeCached = NotToBeCached; + if (__CFNumberTypeTable[type].floatBit) { - CFNumberRef cached = NULL; - if (0 == __CFNumberTypeTable[type].storageBit) { - Float32Bits f = *(Float32Bits *)valuePtr; + CFNumberRef cached = NULL; + if (0 == __CFNumberTypeTable[type].storageBit) { + Float32Bits f = *(Float32Bits *)valuePtr; if (f.bits == BITSFORFLOATZERO) cached = kCFNumberFloat32Zero; else if (f.bits == BITSFORFLOATONE) cached = kCFNumberFloat32One; else if (isnan(f.floatValue)) cached = kCFNumberNaN; - else if (isinf(f.floatValue)) cached = (f.floatValue < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity; + else if (isinf(f.floatValue)) cached = (f.floatValue < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity; - } else { + } else { Float64Bits d = *(Float64Bits *)valuePtr; if (d.bits == BITSFORDOUBLEZERO) cached = kCFNumberFloat64Zero; else if (d.bits == BITSFORDOUBLEONE) cached = kCFNumberFloat64One; - else if (isnan(d.floatValue)) cached = kCFNumberNaN; - else if (isinf(d.floatValue)) cached = (d.floatValue < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity; - } - if (cached) return (CFNumberRef)CFRetain(cached); + else if (isnan(d.floatValue)) cached = kCFNumberNaN; + else if (isinf(d.floatValue)) cached = (d.floatValue < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity; + } + if (cached) return (CFNumberRef)CFRetain(cached); } else if (_CFAllocatorIsSystemDefault(allocator) && (__CFNumberCaching == kCFNumberCachingEnabled)) { - switch (__CFNumberTypeTable[type].canonicalType) { - case kCFNumberSInt8Type: {int8_t val = *(int8_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} - case kCFNumberSInt16Type: {int16_t val = *(int16_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} - case kCFNumberSInt32Type: {int32_t val = *(int32_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} - case kCFNumberSInt64Type: {int64_t val = *(int64_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} - } - if (NotToBeCached != valToBeCached) { - CFNumberRef cached = __CFNumberCache[valToBeCached - MinCachedInt]; // Atomic to access the value in the cache - if (NULL != cached) return (CFNumberRef)CFRetain(cached); - } + switch (__CFNumberTypeTable[type].canonicalType) { + case kCFNumberSInt8Type: {int8_t val = *(int8_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} + case kCFNumberSInt16Type: {int16_t val = *(int16_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} + case kCFNumberSInt32Type: {int32_t val = *(int32_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} + case kCFNumberSInt64Type: {int64_t val = *(int64_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;} + } + if (NotToBeCached != valToBeCached) { + CFNumberRef cached = __CFNumberCache[valToBeCached - MinCachedInt]; // Atomic to access the value in the cache + if (NULL != cached) return (CFNumberRef)CFRetain(cached); + } } - CFIndex size = 8 + ((!__CFNumberTypeTable[type].floatBit && __CFNumberTypeTable[type].storageBit) ? 8 : 0); + CFIndex size = sizeof(struct __CFNumber) - sizeof(CFRuntimeBase); + if (!__CFNumberTypeTable[type].floatBit && __CFNumberTypeTable[type].storageBit) size += 8; +#if OLD_CRAP_TOO + size += 2 * sizeof(void *); +#endif CFNumberRef result = (CFNumberRef)_CFRuntimeCreateInstance(allocator, CFNumberGetTypeID(), size, NULL); if (NULL == result) { return NULL; } - - __CFRuntimeSetNumberType(result, (uint8_t)__CFNumberTypeTable[type].canonicalType); - - - // should be initialized BEFORE ever caching it! - __CFNumberInit(result, type, valuePtr); + __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)__CFNumberTypeTable[type].canonicalType); + +#if OLD_CRAP_TOO + ((struct __CFNumber *)result)->__old__ = CFNumberCreate_old(allocator, type, valuePtr); +CFLog(kCFLogLevelWarning, CFSTR("+++ Create old number '%@'"), __CFNumberCopyDescription_old(result->__old__)); + +#endif // for a value to be cached, we already have the value handy if (NotToBeCached != valToBeCached) { @@ -1186,47 +1271,93 @@ static CFNumberRef _CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, // depend on the order and original type in/with which the numbers are created. // Forcing the type AFTER it was cached would cause a race condition with other // threads pulling the number object out of the cache and using it. - __CFRuntimeSetNumberType(result, (uint8_t)kCFNumberSInt32Type); + __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)kCFNumberSInt32Type); if (OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)result, (void *volatile *)&__CFNumberCache[valToBeCached - MinCachedInt])) { CFRetain(result); } else { // Did not cache the number object, put original type back. - __CFRuntimeSetNumberType(result, origType); + __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)origType); } return result; } + uint64_t value; + switch (__CFNumberTypeTable[type].canonicalType) { + case kCFNumberSInt8Type: value = (uint64_t)(int64_t)*(int8_t *)valuePtr; goto smallVal; + case kCFNumberSInt16Type: value = (uint64_t)(int64_t)*(int16_t *)valuePtr; goto smallVal; + case kCFNumberSInt32Type: value = (uint64_t)(int64_t)*(int32_t *)valuePtr; goto smallVal; + smallVal: memmove((void *)&result->_pad, &value, 8); break; + case kCFNumberSInt64Type: memmove((void *)&result->_pad, valuePtr, 8); break; + case kCFNumberSInt128Type: memmove((void *)&result->_pad, valuePtr, 16); break; + case kCFNumberFloat32Type: memmove((void *)&result->_pad, valuePtr, 4); break; + case kCFNumberFloat64Type: memmove((void *)&result->_pad, valuePtr, 8); break; + } + _CFNumberInit(result, type, valuePtr); +//printf(" => %p\n", result); return result; } -CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) { - return _CFNumberCreate(allocator, type, valuePtr); -} - CFNumberType CFNumberGetType(CFNumberRef number) { +//printf("+ [%p] CFNumberGetType(%p)\n", pthread_self(), number); CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType); CF_SWIFT_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (CFSwiftRef)number, NSNumber._cfNumberGetType); __CFAssertIsNumber(number); CFNumberType type = __CFNumberGetType(number); if (kCFNumberSInt128Type == type) type = kCFNumberSInt64Type; // must hide this type, since it is not public +//printf(" => %d\n", type); +#if OLD_CRAP_TOO +if (! number->__old__) { +printf("*** Test skipped in CFNumberGetType for number %p\n", number); +} else { +CFNumberType t2 = CFNumberGetType_old(number->__old__); +if (t2 != type) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberGetType: '%d' '%d'"), t2, type); FAIL(); +} +} +#endif return type; } CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number) { CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType); + CF_SWIFT_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (CFSwiftRef)number, NSNumber._cfNumberGetType); __CFAssertIsNumber(number); return __CFNumberGetType(number); } CFIndex CFNumberGetByteSize(CFNumberRef number) { +//printf("+ [%p] CFNumberGetByteSize(%p)\n", pthread_self(), number); __CFAssertIsNumber(number); CFIndex r = 1 << __CFNumberTypeTable[CFNumberGetType(number)].lgByteSize; +//printf(" => %d\n", r); +#if OLD_CRAP_TOO +if (! number->__old__) { +printf("*** Test skipped in CFNumberGetByteSize for number %p\n", number); +} else { +CFIndex r2 = CFNumberGetByteSize_old(number->__old__); +if (r2 != r) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberGetByteSize: '%d' '%d'"), r2, r); FAIL(); +} +} +#endif return r; } Boolean CFNumberIsFloatType(CFNumberRef number) { +//printf("+ [%p] CFNumberIsFloatType(%p)\n", pthread_self(), number); __CFAssertIsNumber(number); Boolean r = __CFNumberTypeTable[CFNumberGetType(number)].floatBit; +//printf(" => %d\n", r); +#if OLD_CRAP_TOO +if (! number->__old__) { +printf("*** Test skipped in CFNumberIsFloatType for number %p\n", number); +} else { +Boolean r2 = CFNumberIsFloatType_old(number->__old__); +if (r2 != r) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberIsFloatType: '%d' '%d'"), r2, r); FAIL(); +} +} +#endif return r; } @@ -1239,6 +1370,21 @@ Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) __CFAssertIsValidNumberType(type); uint8_t localMemory[128]; Boolean r = __CFNumberGetValueCompat(number, type, valuePtr ? valuePtr : localMemory); +//printf(" => %d\n", r); +#if OLD_CRAP_TOO +if (! number->__old__) { +printf("*** Test skipped in CFNumberGetValue for number %p\n", number); +} else { + uint8_t localMemory2[128]; +Boolean r2 = CFNumberGetValue_old(number->__old__, type, localMemory2); +if (r2 != r) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL 1 in CFNumberGetValue: '%d' '%d'"), r2, r); FAIL(); +} +if (0 != memcmp(localMemory2, valuePtr, CFNumberGetByteSize(number))) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL 2 in CFNumberGetValue: BYTES NOT SAME")); FAIL(); +} +} +#endif return r; } @@ -1325,10 +1471,372 @@ static CFComparisonResult CFNumberCompare_new(CFNumberRef number1, CFNumberRef n } CFComparisonResult CFNumberCompare(CFNumberRef number1, CFNumberRef number2, void *context) { +//printf("+ [%p] CFNumberCompare(%p, %p, %p)\n", pthread_self(), number1, number2, context); CFComparisonResult r = CFNumberCompare_new(number1, number2, context); +//printf(" => %d\n", r); +#if OLD_CRAP_TOO +if (! number1->__old__ || !number2->__old__) { +printf("*** Test skipped in CFNumberCompare for numbers %p %p\n", number1, number2); +} else { +CFComparisonResult r2 = CFNumberCompare_old(number1->__old__, number2->__old__, context); +if (r2 != r) { +CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberCompare: '%d' '%d'"), r2, r); FAIL(); +} +} +#endif return r; } +#if OLD_CRAP_TOO + +static const unsigned char __CFNumberCanonicalType[kCFNumberMaxType + 1] = { + 0, kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type, + kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type, + kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type +}; + +static const unsigned char __CFNumberStorageType[kCFNumberMaxType + 1] = { + 0, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type, + kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type, + kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type +}; + + + +// Returns the type that is used to store the specified type +static CFNumberType __CFNumberGetStorageTypeForType_old(CFNumberType type) { + return __CFNumberStorageType[type]; +} + +// Returns the canonical type used to represent the specified type +static CFNumberType __CFNumberGetCanonicalTypeForType_old(CFNumberType type) { + return __CFNumberCanonicalType[type]; +} + +// Extracts and returns the type out of the CFNumber +static CFNumberType __CFNumberGetType_old(struct __CFNumber_old * num) { + return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0); +} + +// Returns true if the argument type is float or double +static Boolean __CFNumberTypeIsFloat_old(CFNumberType type) { + return (type == kCFNumberFloat64Type) || (type == kCFNumberFloat32Type) || (type == kCFNumberDoubleType) || (type == kCFNumberFloatType); +} + +// Returns the number of bytes necessary to store the specified type +// Needs to handle all canonical types +static CFIndex __CFNumberSizeOfType_old(CFNumberType type) { + switch (type) { + case kCFNumberSInt8Type: return sizeof(int8_t); + case kCFNumberSInt16Type: return sizeof(int16_t); + case kCFNumberSInt32Type: return sizeof(SInt32); + case kCFNumberSInt64Type: return sizeof(int64_t); + case kCFNumberFloat32Type: return sizeof(Float32); + case kCFNumberFloat64Type: return sizeof(Float64); + default: printf("*** WARNING: 0 size from __CFNumberSizeOfType_old \n"); return 0; + } +} + +// Copies an external value of a given type into the appropriate slot in the union (does no type conversion) +// Needs to handle all canonical types +#define SET_VALUE(valueUnion, type, valuePtr) \ + switch (type) { \ + case kCFNumberSInt8Type: (valueUnion)->valSInt32 = *(int8_t *)(valuePtr); break; \ + case kCFNumberSInt16Type: (valueUnion)->valSInt32 = *(int16_t *)(valuePtr); break; \ + case kCFNumberSInt32Type: (valueUnion)->valSInt32 = *(SInt32 *)(valuePtr); break; \ + case kCFNumberSInt64Type: (valueUnion)->valSInt64 = *(int64_t *)(valuePtr); break; \ + case kCFNumberFloat32Type: (valueUnion)->valFloat32 = *(Float32 *)(valuePtr); break; \ + case kCFNumberFloat64Type: (valueUnion)->valFloat64 = *(Float64 *)(valuePtr); break; \ + default: printf("*** WARNING: default case in SET_VALUE \n"); break; \ + } + +// Casts the specified value into the specified type and copies it into the provided memory +// Needs to handle all canonical types +#define GET_VALUE(value, type, resultPtr) \ + switch (type) { \ + case kCFNumberSInt8Type: *(int8_t *)(resultPtr) = (int8_t)value; break; \ + case kCFNumberSInt16Type: *(int16_t *)(resultPtr) = (int16_t)value; break; \ + case kCFNumberSInt32Type: *(SInt32 *)(resultPtr) = (SInt32)value; break; \ + case kCFNumberSInt64Type: *(int64_t *)(resultPtr) = (int64_t)value; break; \ + case kCFNumberFloat32Type: *(Float32 *)(resultPtr) = (Float32)value; break; \ + case kCFNumberFloat64Type: *(Float64 *)(resultPtr) = (Float64)value; break; \ + default: printf("*** WARNING: default case in GET_VALUE \n"); break; \ + } + +// Extracts the stored type out of the union and copies it in the desired type into the provided memory +// Needs to handle all storage types +static void __CFNumberGetValue_old(const __CFNumberValue_old *value, CFNumberType numberType, CFNumberType typeToGet, void *valuePtr) { + switch (numberType) { + case kCFNumberSInt32Type: GET_VALUE(value->valSInt32, typeToGet, valuePtr); break; + case kCFNumberSInt64Type: GET_VALUE(value->valSInt64, typeToGet, valuePtr); break; + case kCFNumberFloat32Type: GET_VALUE(value->valFloat32, typeToGet, valuePtr); break; + case kCFNumberFloat64Type: GET_VALUE(value->valFloat64, typeToGet, valuePtr); break; + default: printf("*** WARNING: default case in __CFNumberGetValue_old \n"); break; \ + } +} + +// Sees if two value union structs have the same value (will do type conversion) +static Boolean __CFNumberEqualValue_old(const __CFNumberValue_old *value1, CFNumberType type1, const __CFNumberValue_old *value2, CFNumberType type2) { + if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) { + Float64 d1, d2; + __CFNumberGetValue_old(value1, type1, kCFNumberFloat64Type, &d1); + __CFNumberGetValue_old(value2, type2, kCFNumberFloat64Type, &d2); + if (isnan(d1) && isnan(d2)) return true; // Not mathematically sound, but required + return d1 == d2; + } else { + int64_t i1, i2; + __CFNumberGetValue_old(value1, type1, kCFNumberSInt64Type, &i1); + __CFNumberGetValue_old(value2, type2, kCFNumberSInt64Type, &i2); + return i1 == i2; + } +} + +static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2) { + struct __CFNumber_old * number1 = (struct __CFNumber_old *)cf1; + struct __CFNumber_old * number2 = (struct __CFNumber_old *)cf2; + return __CFNumberEqualValue_old(&(number1->value), __CFNumberGetType_old(number1), &(number2->value), __CFNumberGetType_old(number2)); +} + +static CFHashCode __CFNumberHash_old(CFTypeRef cf) { + struct __CFNumber_old * number = (struct __CFNumber_old *)cf; + switch (__CFNumberGetType_old((struct __CFNumber_old *)cf)) { + case kCFNumberSInt32Type: return _CFHashInt(number->value.valSInt32); + case kCFNumberSInt64Type: return _CFHashDouble((double)(number->value.valSInt64)); + case kCFNumberFloat32Type: return _CFHashDouble((double)(number->value.valFloat32)); + case kCFNumberFloat64Type: return _CFHashDouble((double)(number->value.valFloat64)); + default: printf("*** WARNING default case in __CFNumberHash_old\n"); + return 0; + } +} + +#define BUFFER_SIZE 100 +#define emitChar(ch) \ + {if (buf - stackBuf == BUFFER_SIZE) {CFStringAppendCharacters(mstr, stackBuf, BUFFER_SIZE); buf = stackBuf;} *buf++ = ch;} + +static void __CFNumberEmitInt64_old(CFMutableStringRef mstr, int64_t value, int32_t width, UniChar pad, bool explicitPlus) { + UniChar stackBuf[BUFFER_SIZE], *buf = stackBuf; + uint64_t uvalue, factor, tmp; + int32_t w; + bool neg; + + neg = (value < 0) ? true : false; + uvalue = (neg) ? -value : value; + if (neg || explicitPlus) width--; + width--; + factor = 1; + tmp = uvalue; + while (9 < tmp) { + width--; + factor *= 10; + tmp /= 10; + } + for (w = 0; w < width; w++) emitChar(pad); + if (neg) { + emitChar('-'); + } else if (explicitPlus) { + emitChar('+'); + } + while (0 < factor) { + UniChar ch = '0' + (UniChar)(uvalue / factor); + uvalue %= factor; + emitChar(ch); + factor /= 10; + } + if (buf > stackBuf) CFStringAppendCharacters(mstr, stackBuf, buf - stackBuf); +} + +static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf) { + struct __CFNumber_old * number = (struct __CFNumber_old *)cf; + CFMutableStringRef mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); + CFStringAppendFormat(mstr, NULL, CFSTR("{value = "), cf, CFGetAllocator(cf)); + switch (__CFNumberGetType_old(number)) { + case kCFNumberSInt32Type: + __CFNumberEmitInt64_old(mstr, number->value.valSInt32, 0, ' ', true); + CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt32Type}")); + break; + case kCFNumberSInt64Type: + __CFNumberEmitInt64_old(mstr, number->value.valSInt64, 0, ' ', true); + CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt64Type}")); + break; + case kCFNumberFloat32Type: + // debugging formatting is intentionally more verbose and explicit about the value of the number + if (isnan(number->value.valFloat32)) { + CFStringAppend(mstr, CFSTR("nan")); + } else if (isinf(number->value.valFloat32)) { + CFStringAppend(mstr, (0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity")); + } else if (0.0f == number->value.valFloat32) { + CFStringAppend(mstr, (copysign(1.0, number->value.valFloat32) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0")); + } else { + CFStringAppendFormat(mstr, NULL, CFSTR("%+.10f"), number->value.valFloat32); + } + CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat32Type}")); + break; + case kCFNumberFloat64Type: + // debugging formatting is intentionally more verbose and explicit about the value of the number + if (isnan(number->value.valFloat64)) { + CFStringAppend(mstr, CFSTR("nan")); + } else if (isinf(number->value.valFloat64)) { + CFStringAppend(mstr, (0.0 < number->value.valFloat64) ? CFSTR("+infinity") : CFSTR("-infinity")); + } else if (0.0 == number->value.valFloat64) { + CFStringAppend(mstr, (copysign(1.0, number->value.valFloat64) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0")); + } else { + CFStringAppendFormat(mstr, NULL, CFSTR("%+.20f"), number->value.valFloat64); + } + CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat64Type}")); + break; + default: + CFRelease(mstr); + return NULL; + } + return mstr; +} + +// This function separated out from __CFNumberCopyFormattingDescription() so the plist creation can use it as well. + +CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf) { + double d; + CFNumberGetValue_old((struct __CFNumber_old *)cf, kCFNumberFloat64Type, &d); + if (isnan(d)) { + return (CFStringRef)CFRetain(CFSTR("nan")); + } + if (isinf(d)) { + return (CFStringRef)CFRetain((0.0 < d) ? CFSTR("+infinity") : CFSTR("-infinity")); + } + if (0.0 == d) { + return (CFStringRef)CFRetain(CFSTR("0.0")); + } + // if %g is used here, need to use DBL_DIG + 2 on Mac OS X, but %f needs +1 + return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), DBL_DIG + 2, d); +} + +static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions) { + struct __CFNumber_old * number = (struct __CFNumber_old *)cf; + CFMutableStringRef mstr; + int64_t value; + switch (__CFNumberGetType_old(number)) { + case kCFNumberSInt32Type: + case kCFNumberSInt64Type: + value = (__CFNumberGetType_old(number) == kCFNumberSInt32Type) ? number->value.valSInt32 : number->value.valSInt64; + mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); + __CFNumberEmitInt64_old(mstr, value, 0, ' ', false); + return mstr; + case kCFNumberFloat32Type: + if (isnan(number->value.valFloat32)) { + return (CFStringRef)CFRetain(CFSTR("nan")); + } + if (isinf(number->value.valFloat32)) { + return (CFStringRef)CFRetain((0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity")); + } + if (0.0f == number->value.valFloat32) { + return (CFStringRef)CFRetain(CFSTR("0.0")); + } + // if %g is used here, need to use FLT_DIG + 2 on Mac OS X, but %f needs +1 + return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), FLT_DIG + 2, number->value.valFloat32); + case kCFNumberFloat64Type: + return __CFNumberCopyFormattingDescriptionAsFloat64_old(number); + break; + default: + return NULL; + } +} + + + +static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) { + struct __CFNumber_old * num; + CFNumberType equivType, storageType; + +if (type == 17) { +CFSInt128Struct *s = valuePtr; +s->high = (int64_t)s->low; +type = kCFNumberSInt64Type; +} + + + equivType = __CFNumberGetCanonicalTypeForType_old(type); + + storageType = __CFNumberGetStorageTypeForType_old(type); + + num = (struct __CFNumber_old *)_CFRuntimeCreateInstance(allocator, CFNumberGetTypeID(), __CFNumberSizeOfType_old(storageType), NULL); + if (NULL == num) { + return NULL; + } + SET_VALUE((__CFNumberValue_old *)&(num->value), equivType, valuePtr); + __CFBitfieldSetValue(((struct __CFNumber_old *)num)->_base._cfinfo[CF_INFO_BITS], 6, 0, (uint8_t)storageType); + +if (__CFNumberGetType_old(num) == 0) printf("*** ERROR: new number %p type is 0 (%d)\n", num, storageType); + return num; +} + +static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number) { + + return __CFNumberGetType_old(number); +} + +static CFIndex CFNumberGetByteSize_old(struct __CFNumber_old * number) { + return __CFNumberSizeOfType_old(CFNumberGetType_old(number)); +} + +static Boolean CFNumberIsFloatType_old(struct __CFNumber_old * number) { + return __CFNumberTypeIsFloat_old(CFNumberGetType_old(number)); +} + +static Boolean CFNumberGetValue_old(struct __CFNumber_old * number, CFNumberType type, void *valuePtr) { + uint8_t localMemory[sizeof(__CFNumberValue_old)]; + __CFNumberValue_old localValue; + CFNumberType numType; + CFNumberType storageTypeForType; + +if (type == 17) type = kCFNumberSInt64Type; + + storageTypeForType = __CFNumberGetStorageTypeForType_old(type); + type = __CFNumberGetCanonicalTypeForType_old(type); + if (!valuePtr) valuePtr = &localMemory; + + numType = __CFNumberGetType_old(number); + __CFNumberGetValue_old((__CFNumberValue_old *)&(number->value), numType, type, valuePtr); + + // If the types match, then we're fine! + if (numType == storageTypeForType) return true; + + // Test to see if the returned value is intact... + SET_VALUE(&localValue, type, valuePtr); + return __CFNumberEqualValue_old(&localValue, storageTypeForType, &(number->value), numType); +} + +static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, struct __CFNumber_old * number2, void *context) { + CFNumberType type1, type2; + + + type1 = __CFNumberGetType_old(number1); + type2 = __CFNumberGetType_old(number2); + + if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) { + Float64 d1, d2; + double s1, s2; + __CFNumberGetValue_old(&(number1->value), type1, kCFNumberFloat64Type, &d1); + __CFNumberGetValue_old(&(number2->value), type2, kCFNumberFloat64Type, &d2); + s1 = copysign(1.0, d1); + s2 = copysign(1.0, d2); + if (isnan(d1) && isnan(d2)) return kCFCompareEqualTo; + if (isnan(d1)) return (s2 < 0.0) ? kCFCompareGreaterThan : kCFCompareLessThan; + if (isnan(d2)) return (s1 < 0.0) ? kCFCompareLessThan : kCFCompareGreaterThan; + // at this point, we know we don't have any NaNs + if (s1 < s2) return kCFCompareLessThan; + if (s2 < s1) return kCFCompareGreaterThan; + // at this point, we know the signs are the same; do not combine these tests + if (d1 < d2) return kCFCompareLessThan; + if (d2 < d1) return kCFCompareGreaterThan; + return kCFCompareEqualTo; + } else { + int64_t i1, i2; + __CFNumberGetValue_old(&(number1->value), type1, kCFNumberSInt64Type, &i1); + __CFNumberGetValue_old(&(number2->value), type2, kCFNumberSInt64Type, &i2); + return (i1 > i2) ? kCFCompareGreaterThan : ((i1 < i2) ? kCFCompareLessThan : kCFCompareEqualTo); + } +} + +#endif #undef __CFAssertIsBoolean diff --git a/CoreFoundation/NumberDate.subproj/CFNumber.h b/CoreFoundation/NumberDate.subproj/CFNumber.h index 95f7756209..d5e1012c13 100644 --- a/CoreFoundation/NumberDate.subproj/CFNumber.h +++ b/CoreFoundation/NumberDate.subproj/CFNumber.h @@ -1,7 +1,7 @@ /* CFNumber.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -46,8 +46,8 @@ typedef CF_ENUM(CFIndex, CFNumberType) { kCFNumberDoubleType = 13, /* Other */ kCFNumberCFIndexType = 14, - kCFNumberNSIntegerType API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 15, - kCFNumberCGFloatType API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 16, + kCFNumberNSIntegerType CF_ENUM_AVAILABLE(10_5, 2_0) = 15, + kCFNumberCGFloatType CF_ENUM_AVAILABLE(10_5, 2_0) = 16, kCFNumberMaxType = 16 }; diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.c b/CoreFoundation/NumberDate.subproj/CFTimeZone.c index 4ce9654b84..a878e23670 100644 --- a/CoreFoundation/NumberDate.subproj/CFTimeZone.c +++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.c @@ -1,7 +1,7 @@ /* CFTimeZone.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -33,9 +33,12 @@ #endif #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED #include +#define MACOS_TZDIR1 "/usr/share/zoneinfo/" // 10.12 and earlier +#define MACOS_TZDIR2 "/var/db/timezone/zoneinfo/" // 10.13 onwards + #elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD #ifndef TZDIR -#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */ +#define TZDIR "/usr/share/zoneinfo/" /* Time zone object file directory */ #endif /* !defined TZDIR */ #ifndef TZDEFAULT @@ -56,16 +59,9 @@ struct tzhead { #include -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD -#define TZZONELINK TZDEFAULT -#define TZZONEINFO TZDIR "/" -#elif DEPLOYMENT_TARGET_WINDOWS static CFStringRef __tzZoneInfo = NULL; static char *__tzDir = NULL; static void __InitTZStrings(void); -#else -#error Unknown or unspecified DEPLOYMENT_TARGET -#endif CONST_STRING_DECL(kCFTimeZoneSystemTimeZoneDidChangeNotification, "kCFTimeZoneSystemTimeZoneDidChangeNotification") @@ -147,13 +143,9 @@ static CFMutableArrayRef __CFCopyWindowsTimeZoneList() { #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD static CFMutableArrayRef __CFCopyRecursiveDirectoryList() { CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); -#if DEPLOYMENT_TARGET_WINDOWS if (!__tzDir) __InitTZStrings(); if (!__tzDir) return result; int fd = open(__tzDir, O_RDONLY); -#else - int fd = open(TZDIR "/zone.tab", O_RDONLY); -#endif for (; 0 <= fd;) { uint8_t buffer[4096]; @@ -686,7 +678,7 @@ CFTimeZoneRef CFTimeZoneCreateWithWindowsName(CFAllocatorRef allocator, CFString } extern CFStringRef _CFGetWindowsAppleSystemLibraryDirectory(void); -void __InitTZStrings(void) { +static void __InitTZStrings(void) { static CFLock_t __CFTZDirLock = CFLockInit; __CFLock(&__CFTZDirLock); if (!__tzZoneInfo) { @@ -704,6 +696,50 @@ void __InitTZStrings(void) { } __CFUnlock(&__CFTZDirLock); } + +#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED +static void __InitTZStrings(void) { + static dispatch_once_t initOnce = 0; + + dispatch_once(&initOnce, ^{ + unsigned int major = 0, minor = 0, patch = 0; + + CFDictionaryRef dict = _CFCopySystemVersionDictionary(); + if (dict) { + CFStringRef version = CFDictionaryGetValue(dict, _kCFSystemVersionProductVersionKey); + if (version) { + const char *cStr = CFStringGetCStringPtr(version, kCFStringEncodingASCII); + if (cStr) { + if (sscanf(cStr, "%u.%u.%u", &major, &minor, &patch) != 3) { + major = 0; + minor = 0; + patch = 0; + } + } + } + CFRelease(dict); + } + + // Timezone files moved in High Sierra(10.13) + if (major == 10 && minor < 13) { + // older versions + __tzZoneInfo = CFSTR(MACOS_TZDIR1); + __tzDir = MACOS_TZDIR1 "zone.tab"; + } else { + __tzZoneInfo = CFSTR(MACOS_TZDIR2); + __tzDir = MACOS_TZDIR2 "zone.tab"; + } + }); +} + +#elif DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD +static void __InitTZStrings(void) { + __tzZoneInfo = CFSTR(TZDIR); + __tzDir = TZDIR "zone.tab"; +} + +#else +#error Unknown or unspecified DEPLOYMENT_TARGET #endif static CFTimeZoneRef __CFTimeZoneCreateSystem(void) { @@ -748,11 +784,16 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) { CFRelease(name); if (result) return result; } - ret = readlink(TZZONELINK, linkbuf, sizeof(linkbuf)); - if (0 < ret) { + + if (!__tzZoneInfo) __InitTZStrings(); + ret = readlink(TZDEFAULT, linkbuf, sizeof(linkbuf)); + if (__tzZoneInfo && (0 < ret)) { linkbuf[ret] = '\0'; - if (strncmp(linkbuf, TZZONEINFO, sizeof(TZZONEINFO) - 1) == 0) { - name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (uint8_t *)linkbuf + sizeof(TZZONEINFO) - 1, strlen(linkbuf) - sizeof(TZZONEINFO) + 1, kCFStringEncodingUTF8, false); + const char *tzZoneInfo = CFStringGetCStringPtr(__tzZoneInfo, kCFStringEncodingASCII); + size_t zoneInfoDirLen = CFStringGetLength(__tzZoneInfo); + if (strncmp(linkbuf, tzZoneInfo, zoneInfoDirLen) == 0) { + name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (uint8_t *)linkbuf + zoneInfoDirLen, + strlen(linkbuf) - zoneInfoDirLen + 1, kCFStringEncodingUTF8, false); } else { name = CFStringCreateWithBytes(kCFAllocatorSystemDefault, (uint8_t *)linkbuf, strlen(linkbuf), kCFStringEncodingUTF8, false); } @@ -1133,12 +1174,12 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data CFIndex length; Boolean result = false; -#if DEPLOYMENT_TARGET_WINDOWS if (!__tzZoneInfo) __InitTZStrings(); if (!__tzZoneInfo) return NULL; +#if DEPLOYMENT_TARGET_WINDOWS baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, __tzZoneInfo, kCFURLWindowsPathStyle, true); #else - baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR(TZZONEINFO), kCFURLPOSIXPathStyle, true); + baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, __tzZoneInfo, kCFURLPOSIXPathStyle, true); #endif if (tryAbbrev) { CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary(); @@ -1159,15 +1200,9 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data CFStringRef mapping = CFDictionaryGetValue(dict, name); if (mapping) { name = mapping; -#if DEPLOYMENT_TARGET_WINDOWS } else if (CFStringHasPrefix(name, __tzZoneInfo)) { CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, CFStringGetLength(name), name); CFStringDelete(unprefixed, CFRangeMake(0, CFStringGetLength(__tzZoneInfo))); -#else - } else if (CFStringHasPrefix(name, CFSTR(TZZONEINFO))) { - CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, CFStringGetLength(name), name); - CFStringDelete(unprefixed, CFRangeMake(0, sizeof(TZZONEINFO))); -#endif mapping = CFDictionaryGetValue(dict, unprefixed); if (mapping) { name = mapping; @@ -1340,12 +1375,12 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam void *bytes; CFIndex length; -#if DEPLOYMENT_TARGET_WINDOWS if (!__tzZoneInfo) __InitTZStrings(); if (!__tzZoneInfo) return NULL; +#if DEPLOYMENT_TARGET_WINDOWS baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, __tzZoneInfo, kCFURLWindowsPathStyle, true); #else - baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, CFSTR(TZZONEINFO), kCFURLPOSIXPathStyle, true); + baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, __tzZoneInfo, kCFURLPOSIXPathStyle, true); #endif if (tryAbbrev) { CFDictionaryRef abbrevs = CFTimeZoneCopyAbbreviationDictionary(); @@ -1366,15 +1401,9 @@ CFTimeZoneRef CFTimeZoneCreateWithName(CFAllocatorRef allocator, CFStringRef nam CFStringRef mapping = CFDictionaryGetValue(dict, name); if (mapping) { name = mapping; -#if DEPLOYMENT_TARGET_WINDOWS } else if (CFStringHasPrefix(name, __tzZoneInfo)) { CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, CFStringGetLength(name), name); CFStringDelete(unprefixed, CFRangeMake(0, CFStringGetLength(__tzZoneInfo))); -#else - } else if (CFStringHasPrefix(name, CFSTR(TZZONEINFO))) { - CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, CFStringGetLength(name), name); - CFStringDelete(unprefixed, CFRangeMake(0, sizeof(TZZONEINFO))); -#endif mapping = CFDictionaryGetValue(dict, unprefixed); if (mapping) { name = mapping; @@ -1549,6 +1578,4 @@ static CFDictionaryRef __CFTimeZoneCopyCompatibilityDictionary(void) { return dict; } -#undef TZZONEINFO -#undef TZZONELINK diff --git a/CoreFoundation/NumberDate.subproj/CFTimeZone.h b/CoreFoundation/NumberDate.subproj/CFTimeZone.h index 4207f4559e..2548eeeba8 100644 --- a/CoreFoundation/NumberDate.subproj/CFTimeZone.h +++ b/CoreFoundation/NumberDate.subproj/CFTimeZone.h @@ -1,7 +1,7 @@ /* CFTimeZone.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -71,10 +71,10 @@ CF_EXPORT Boolean CFTimeZoneIsDaylightSavingTime(CFTimeZoneRef tz, CFAbsoluteTime at); CF_EXPORT -CFTimeInterval CFTimeZoneGetDaylightSavingTimeOffset(CFTimeZoneRef tz, CFAbsoluteTime at) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFTimeInterval CFTimeZoneGetDaylightSavingTimeOffset(CFTimeZoneRef tz, CFAbsoluteTime at) CF_AVAILABLE(10_5, 2_0); CF_EXPORT -CFAbsoluteTime CFTimeZoneGetNextDaylightSavingTimeTransition(CFTimeZoneRef tz, CFAbsoluteTime at) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFAbsoluteTime CFTimeZoneGetNextDaylightSavingTimeTransition(CFTimeZoneRef tz, CFAbsoluteTime at) CF_AVAILABLE(10_5, 2_0); typedef CF_ENUM(CFIndex, CFTimeZoneNameStyle) { kCFTimeZoneNameStyleStandard, @@ -83,13 +83,13 @@ typedef CF_ENUM(CFIndex, CFTimeZoneNameStyle) { kCFTimeZoneNameStyleShortDaylightSaving, kCFTimeZoneNameStyleGeneric, kCFTimeZoneNameStyleShortGeneric -} API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_5, 2_0); CF_EXPORT -CFStringRef CFTimeZoneCopyLocalizedName(CFTimeZoneRef tz, CFTimeZoneNameStyle style, CFLocaleRef locale) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFStringRef CFTimeZoneCopyLocalizedName(CFTimeZoneRef tz, CFTimeZoneNameStyle style, CFLocaleRef locale) CF_AVAILABLE(10_5, 2_0); CF_EXPORT -const CFNotificationName kCFTimeZoneSystemTimeZoneDidChangeNotification API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +const CFNotificationName kCFTimeZoneSystemTimeZoneDidChangeNotification CF_AVAILABLE(10_5, 2_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Parsing.subproj/CFBinaryPList.c b/CoreFoundation/Parsing.subproj/CFBinaryPList.c index adf3a24e7f..a7b7f7141c 100644 --- a/CoreFoundation/Parsing.subproj/CFBinaryPList.c +++ b/CoreFoundation/Parsing.subproj/CFBinaryPList.c @@ -1,7 +1,7 @@ /* CFBinaryPList.c - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -78,10 +78,6 @@ CF_INLINE uint32_t __check_uint32_mul_unsigned_unsigned(uint32_t x, uint32_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 -CF_INLINE uint64_t _CFBinaryPlistTrailer_objectsRangeEnd(const CFBinaryPlistTrailer *trailer) { - return trailer->_offsetTableOffset - 1; -} - #pragma mark - #pragma mark Keyed Archiver UID @@ -732,7 +728,6 @@ CF_PRIVATE CFDataRef __CFBinaryPlistCreateDataUsingExternalBufferAllocator(CFPro #pragma mark Reading #define FAIL_FALSE do { return false; } while (0) -#define FAIL_NULL do { return NULL; } while (0) CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFAllocatorRef allocator, CFOptionFlags mutabilityOption, CFMutableDictionaryRef objects, CFMutableSetRef set, CFIndex curDepth, CFSetRef keyPaths, CFPropertyListRef *plist); @@ -897,31 +892,12 @@ CF_INLINE Boolean _getOffsetOfRefAt(const uint8_t *databytes, const uint8_t *byt return true; } -CF_INLINE bool __CFBinaryPlist_beginArrayParse(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, const uint8_t **outPtr, uint8_t *outMarker, uint64_t *outObjectsRangeEnd) { - uint64_t objectsRangeStart = 8; - const uint64_t objectsRangeEnd = _CFBinaryPlistTrailer_objectsRangeEnd(trailer); +bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects) { + uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1; if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE; const uint8_t *ptr = databytes + startOffset; uint8_t marker = *ptr; if ((marker & 0xf0) != kCFBinaryPlistMarkerArray) FAIL_FALSE; - - if (outPtr) { *outPtr = ptr; } - if (outMarker) { *outMarker = marker; } - if (outObjectsRangeEnd) { *outObjectsRangeEnd = objectsRangeEnd; } - return true; -} - -bool __CFBinaryPlistIsArray(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer) { - const bool result = __CFBinaryPlist_beginArrayParse(databytes, datalen, startOffset, trailer, NULL, NULL, NULL); - return result; -} - -bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, CFIndex idx, uint64_t *offset, CFMutableDictionaryRef objects) { - const uint8_t *ptr; - uint8_t marker; - uint64_t objectsRangeEnd; - if (!__CFBinaryPlist_beginArrayParse(databytes, datalen, startOffset, trailer, &ptr, &marker, &objectsRangeEnd)) FAIL_FALSE; - int32_t err = CF_NO_ERROR; ptr = check_ptr_add(ptr, 1, &err); if (CF_NO_ERROR != err) FAIL_FALSE; @@ -944,12 +920,25 @@ bool __CFBinaryPlistGetOffsetForValueFromArray2(const uint8_t *databytes, uint64 return true; } -CF_INLINE bool __CFBinaryPList_beginDictionaryParse(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer, uint64_t *outEntryCount, const uint8_t **outPtr, uint8_t *outMarker, const uint8_t **outExtent) { +/* 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. + @param startOffset The offset at which the dictionary starts. + @param trailer A pointer to a filled out trailer structure (use __CFBinaryPlistGetTopLevelInfo). + @param key A string key in the dictionary that should be searched for. + @param koffset Will be filled out with the offset to the key in the data bytes. + @param voffset Will be filled out with the offset to the value in the data bytes. + @param unused Unused parameter. + @param objects Used for caching objects. Should be a valid CFMutableDictionaryRef. + @return True if the key was found, false otherwise. +*/ +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) { - // Require that startOffset is in the range of the object table - uint64_t objectsRangeStart = 8; - const uint64_t objectsRangeEnd = _CFBinaryPlistTrailer_objectsRangeEnd(trailer); + // Require a key that is a plist primitive + if (!key || !_plistIsPrimitive(key)) FAIL_FALSE; + // Require that startOffset is in the range of the object table + uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1; if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE; // ptr is the start of the dictionary we are reading @@ -965,10 +954,10 @@ CF_INLINE bool __CFBinaryPList_beginDictionaryParse(const uint8_t *databytes, ui if (CF_NO_ERROR != err) FAIL_FALSE; uint64_t cnt = (marker & 0x0f); if (0xf == cnt) { - uint64_t bigint = 0; - if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE; - if (LONG_MAX < bigint) FAIL_FALSE; - cnt = bigint; + uint64_t bigint = 0; + if (!_readInt(ptr, databytes + objectsRangeEnd, &bigint, &ptr)) FAIL_FALSE; + if (LONG_MAX < bigint) FAIL_FALSE; + cnt = bigint; } // Total number of objects (keys + values) is cnt * 2 @@ -984,118 +973,6 @@ CF_INLINE bool __CFBinaryPList_beginDictionaryParse(const uint8_t *databytes, ui // Check that we didn't overflow the size of the dictionary if (databytes + objectsRangeEnd < extent) FAIL_FALSE; - if (outEntryCount) { *outEntryCount = cnt; } - if (outPtr) { *outPtr = ptr; } - if (outMarker) { *outMarker = marker; } - if (outExtent) { *outExtent = extent; } - - return true; -} - -CF_PRIVATE bool __CFBinaryPlistIsDictionary(const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer) { - const bool result = __CFBinaryPList_beginDictionaryParse(databytes, datalen, startOffset, trailer, NULL, NULL, NULL, NULL); - return result; -} - -CFSetRef __CFBinaryPlistCopyTopLevelKeys(CFAllocatorRef allocator, const uint8_t *databytes, uint64_t datalen, uint64_t startOffset, const CFBinaryPlistTrailer *trailer) { - uint64_t cnt = 0; - const uint8_t *ptr = NULL; - uint8_t marker = 0; - const uint8_t *extent = NULL; - if (!__CFBinaryPList_beginDictionaryParse(databytes, datalen, startOffset, trailer, &cnt, &ptr, &marker, &extent)) { - FAIL_NULL; - } - - - // Find the object in the dictionary with this key - cnt = cnt / 2; - uint64_t off; - - - // Perform linear accumulation of the keys - size_t buffer_idx = 0; - size_t capacity = 16; - CFStringRef *buffer = malloc(sizeof(CFStringRef) * capacity); - if (buffer == NULL) { - FAIL_NULL; - } - bool bad = false; - for (CFIndex idx = 0; !bad && idx < cnt; idx++) { - if (!_getOffsetOfRefAt(databytes, ptr, trailer, &off)) { - bad = true; - break; - } - marker = *(databytes + off); - - // Unlike in __CFBinaryPlistGetOffsetForValueFromDictionary3, we're accumulating keys, so we go through the CFObjectRef case always. - CFPropertyListRef keyInData = NULL; - if (!(__CFBinaryPlistCreateObjectFiltered(databytes, datalen, off, trailer, allocator, kCFPropertyListImmutable, NULL, NULL, 0, NULL, &keyInData) && - CFGetTypeID(keyInData) == stringtype)) { - bad = true; - if (keyInData) { - // we're not storing keyInData in the buffer, so we need to free it now; buffered keys are cleaned below - CFRelease(keyInData); - } - break; - } - - buffer[buffer_idx] = keyInData; - ++buffer_idx; - if (buffer_idx >= capacity) { - const size_t newCapacity = capacity * 3 / 2; - // NOTE: this code doesn't use __CFSafelyReallocate as it handles its own recovery - CFStringRef *reallocated = realloc(buffer, sizeof(CFStringRef) * newCapacity); - if (reallocated == NULL) { - bad = true; - break; - } else { - buffer = reallocated; - capacity = newCapacity; - } - } - ptr += trailer->_objectRefSize; - } - - CFSetRef result = NULL; - if (!bad) { - result = CFSetCreate(allocator, (const void **)buffer, buffer_idx, &kCFTypeSetCallBacks); - } - - // cleanup any keys stored in the local buffer - for (size_t i = 0; i < buffer_idx; ++i) { - CFStringRef s = buffer[i]; - if (s) { - CFRelease(s); - } - } - free(buffer); - - return result; -} - -/* 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. - @param startOffset The offset at which the dictionary starts. - @param trailer A pointer to a filled out trailer structure (use __CFBinaryPlistGetTopLevelInfo). - @param key A string key in the dictionary that should be searched for. - @param koffset Will be filled out with the offset to the key in the data bytes. - @param voffset Will be filled out with the offset to the value in the data bytes. - @param unused Unused parameter. - @param objects Used for caching objects. Should be a valid CFMutableDictionaryRef. - @return True if the key was found, false otherwise. -*/ -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) { - - // Require a key that is a plist primitive - if (!key || !_plistIsPrimitive(key)) FAIL_FALSE; - - uint64_t cnt = 0; - const uint8_t *ptr = NULL; - uint8_t marker = 0; - const uint8_t *extent = NULL; - if (!__CFBinaryPList_beginDictionaryParse(databytes, datalen, startOffset, trailer, &cnt, &ptr, &marker, &extent)) FAIL_NULL; - // For short keys (15 bytes or less) in ASCII form, we can do a quick comparison check // We get the pointer or copy the buffer here, outside of the loop CFIndex stringKeyLen = -1; @@ -1119,17 +996,13 @@ bool __CFBinaryPlistGetOffsetForValueFromDictionary3(const uint8_t *databytes, u // Since we will only be comparing ASCII strings, we can attempt to get a pointer using MacRoman encoding // (this is cheaper than a copy) if (!(keyBufferPtr = CFStringGetCStringPtr((CFStringRef)key, kCFStringEncodingMacRoman)) && stringKeyLen < KEY_BUFF_SIZE) { - const Boolean converted = CFStringGetCString((CFStringRef)key, keyBuffer, KEY_BUFF_SIZE, kCFStringEncodingMacRoman); - if (converted && strnlen(keyBuffer, KEY_BUFF_SIZE) == stringKeyLen) { - // The pointer should now point to our keyBuffer instead of the original string buffer, since we've copied it - keyBufferPtr = keyBuffer; - } + CFStringGetCString((CFStringRef)key, keyBuffer, KEY_BUFF_SIZE, kCFStringEncodingMacRoman); + // The pointer should now point to our keyBuffer instead of the original string buffer, since we've copied it + keyBufferPtr = keyBuffer; } } // Perform linear search of the keys - int32_t err = CF_NO_ERROR; - const uint64_t objectsRangeEnd = _CFBinaryPlistTrailer_objectsRangeEnd(trailer); for (CFIndex idx = 0; idx < cnt; idx++) { if (!_getOffsetOfRefAt(databytes, ptr, trailer, &off)) { FAIL_FALSE; @@ -1214,8 +1087,7 @@ CF_PRIVATE bool __CFBinaryPlistCreateObjectFiltered(const uint8_t *databytes, ui // databytes is trusted to be at least datalen bytes long // *trailer contents are trusted, even for overflows -- was checked when the trailer was parsed - uint64_t objectsRangeStart = 8; - const uint64_t objectsRangeEnd = _CFBinaryPlistTrailer_objectsRangeEnd(trailer); + uint64_t objectsRangeStart = 8, objectsRangeEnd = trailer->_offsetTableOffset - 1; if (startOffset < objectsRangeStart || objectsRangeEnd < startOffset) FAIL_FALSE; uint64_t off; diff --git a/CoreFoundation/Parsing.subproj/CFOldStylePList.c b/CoreFoundation/Parsing.subproj/CFOldStylePList.c index a3ab78c192..e782489cb1 100644 --- a/CoreFoundation/Parsing.subproj/CFOldStylePList.c +++ b/CoreFoundation/Parsing.subproj/CFOldStylePList.c @@ -1,12 +1,12 @@ /* CFOldStylePList.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker - */ + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors + Licensed under Apache License v2.0 with Runtime Library Exception + See http://swift.org/LICENSE.txt for license information + See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors + Responsibility: Tony Parker +*/ #include #include @@ -35,24 +35,15 @@ typedef struct { CFMutableSetRef stringSet; // set of all strings involved in this parse; allows us to share non-mutable strings in the returned plist } _CFStringsFileParseInfo; -static void parseInfo_setError(_CFStringsFileParseInfo *const pInfo, CFErrorRef const error) { - CFErrorRef oldError = pInfo->error; - if (oldError != error) { - pInfo->error = error; - if (oldError) { CFRelease(oldError); } - } -} - // 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->end && p < pInfo->curr) { + while (p < pInfo->curr) { if (*p == '\r') { count ++; - if (p + 1 < pInfo->end && p + 1 < pInfo->curr && *(p + 1) == '\n') { + if (*(p + 1) == '\n') p ++; - } } else if (*p == '\n') { count ++; } @@ -61,23 +52,20 @@ static UInt32 lineNumberStrings(_CFStringsFileParseInfo *pInfo) { return count; } -static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireObject, const uint32_t depth) CF_RETURNS_RETAINED; +static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireObject) CF_RETURNS_RETAINED; #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 -// AFTER-INVARIANT: pInfo->curr <= pInfo->end -// However result will be false when pInfo->curr == pInfo->end static Boolean advanceToNonSpace(_CFStringsFileParseInfo *pInfo) { UniChar ch2; while (pInfo->curr < pInfo->end) { - ch2 = *(pInfo->curr); + 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 (ch2 == '/') { if (pInfo->curr >= pInfo->end) { - // TODO: this could possibly be made more robust (imagine if pInfo->curr is stomped; pInfo->end - 1 might be safer. Unless its smashed too :-/ // whoops; back up and return pInfo->curr --; return true; @@ -87,22 +75,22 @@ static Boolean advanceToNonSpace(_CFStringsFileParseInfo *pInfo) { UniChar ch3 = *(pInfo->curr); if (ch3 == '\n' || ch3 == '\r' || ch3 == 0x2028 || ch3 == 0x2029) break; pInfo->curr ++; - } - } else if (*(pInfo->curr) == '*') { // handle /* ... */ + } + } else if (*(pInfo->curr) == '*') { // handle /* ... */ pInfo->curr ++; - while (pInfo->curr < pInfo->end) { - ch2 = *(pInfo->curr); + while (pInfo->curr < pInfo->end) { + ch2 = *(pInfo->curr); pInfo->curr ++; - if (ch2 == '*' && pInfo->curr < pInfo->end && *(pInfo->curr) == '/') { + if (ch2 == '*' && pInfo->curr < pInfo->end && *(pInfo->curr) == '/') { pInfo->curr ++; // advance past the '/' break; } } - } else { // this looked like the start of a comment, but wasn't + } else { pInfo->curr --; return true; - } - } else { // this didn't look like a comment, we've found non-whitespace + } + } else { pInfo->curr --; return true; } @@ -111,124 +99,84 @@ static Boolean advanceToNonSpace(_CFStringsFileParseInfo *pInfo) { } static UniChar getSlashedChar(_CFStringsFileParseInfo *pInfo) { - CFAssert(pInfo->curr < pInfo->end, __kCFLogAssertion, "Cannot read character after '\\' if at end."); - UniChar ch = *(pInfo->curr); pInfo->curr ++; switch (ch) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': { + 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; - if (pInfo->curr < pInfo->end) { - /* 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 + /* 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'; - if (pInfo->curr < pInfo->end) { - if ((ch = *(pInfo->curr)) >= '0' && ch <= '7') { - pInfo->curr ++; - num = (num << 3) + ch - '0'; - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid octal while parsing plist"))); - return 0; - } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"))); - return 0; - } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid octal while parsing plist"))); - return 0; - } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"))); - return 0; - } - - const uint32_t conversionResult = CFStringEncodingBytesToUnicode(kCFStringEncodingNextStepLatin, 0, &num, sizeof(uint8_t), NULL, &result, 1, &usedCharLen); - if (conversionResult != kCFStringEncodingConversionSuccess) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert octet-stream while parsing plist"))); - return 0; - } else { - return (usedCharLen == 1) ? result : 0; - } - } break; - case 'U': { - unsigned num = 0, numDigits = 4; /* Parse four digits */ - while (pInfo->curr < pInfo->end && numDigits--) { - if (((ch = *(pInfo->curr)) < 128) && isxdigit(ch)) { + 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; - } break; - 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'; + 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) CF_RETURNS_RETAINED { - if (0 == length) { return (CFStringRef)CFRetain(CFSTR("")); } + if (0 == length) return (CFStringRef)CFRetain(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; - const Boolean use_stack = (length < 2048); + 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); - if (ascii == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate string while parsing plist"))); - return NULL; - } - - BOOL gotString = NO; for (CFIndex idx = 0; idx < length; idx++) { UniChar ch = base[idx]; - if (ch < 0x80) { - ascii[idx] = (uint8_t)ch; + if (ch < 0x80) { + ascii[idx] = (uint8_t)ch; } else { - stringToUnique = CFStringCreateWithCharacters(pInfo->allocator, base, length); - if (stringToUnique == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate pre-unique string while parsing plist"))); - return NULL; - } else { - gotString = YES; - } - break; - } + stringToUnique = CFStringCreateWithCharacters(pInfo->allocator, base, length); + break; + } } - if (!gotString) { + if (!stringToUnique) { ascii[length] = '\0'; stringToUnique = CFStringCreateWithBytes(pInfo->allocator, ascii, length, kCFStringEncodingASCII, false); - if (stringToUnique == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate ascii string while parsing plist"))); - return NULL; - } } - if (ascii != buffer) { CFAllocatorDeallocate(kCFAllocatorSystemDefault, ascii); } + if (ascii != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ascii); CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique); if (!uniqued) { CFSetAddValue(pInfo->stringSet, stringToUnique); - uniqued = stringToUnique; + uniqued = stringToUnique; } - if (stringToUnique) { CFRelease(stringToUnique); } - if (uniqued) { CFRetain(uniqued); } + if (stringToUnique) CFRelease(stringToUnique); + if (uniqued) CFRetain(uniqued); return uniqued; } @@ -236,16 +184,11 @@ static CFStringRef _uniqueStringForString(_CFStringsFileParseInfo *pInfo, CFStri CFStringRef uniqued = (CFStringRef)CFSetGetValue(pInfo->stringSet, stringToUnique); if (!uniqued) { uniqued = (CFStringRef)__CFStringCollectionCopy(pInfo->allocator, stringToUnique); - if (uniqued == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to copy string while parsing plist"))); - return NULL; - } else { - CFSetAddValue(pInfo->stringSet, uniqued); - __CFTypeCollectionRelease(pInfo->allocator, uniqued); - } + CFSetAddValue(pInfo->stringSet, uniqued); + __CFTypeCollectionRelease(pInfo->allocator, uniqued); } if (uniqued) CFRetain(uniqued); - return uniqued; + return uniqued; } static CFStringRef parseQuotedPlistString(_CFStringsFileParseInfo *pInfo, UniChar quote) CF_RETURNS_RETAINED { @@ -253,47 +196,30 @@ static CFStringRef parseQuotedPlistString(_CFStringsFileParseInfo *pInfo, UniCha const UniChar *startMark = pInfo->curr; const UniChar *mark = pInfo->curr; while (pInfo->curr < pInfo->end) { - UniChar ch = *(pInfo->curr); + UniChar ch = *(pInfo->curr); if (ch == quote) break; if (ch == '\\') { - if (!str) { str = CFStringCreateMutable(pInfo->allocator, 0); } - if (str == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate quoted string while parsing plist"))); - return NULL; - } + if (!str) str = CFStringCreateMutable(pInfo->allocator, 0); CFStringAppendCharacters(str, mark, pInfo->curr - mark); pInfo->curr ++; - - if (pInfo->curr == pInfo->end) { - if (str) { CFRelease(str); } - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated backslash sequence on line %d"), lineNumberStrings(pInfo))); - return NULL; - } - ch = getSlashedChar(pInfo); CFStringAppendCharacters(str, &ch, 1); mark = pInfo->curr; - } else { + } 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) { - if (str) { CFRelease(str); } + if (str) CFRelease(str); pInfo->curr = startMark; - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unterminated quoted string starting on line %d"), lineNumberStrings(pInfo))); + 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); - if (str == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate mutable string while parsing plist"))); - return NULL; - } - if (mark != pInfo->curr) { - CFStringAppendCharacters(str, mark, pInfo->curr - mark); - } + CFStringAppendCharacters(str, mark, pInfo->curr - mark); } else { str = (CFMutableStringRef)_uniqueStringForCharacters(pInfo, mark, pInfo->curr-mark); } @@ -308,9 +234,10 @@ static CFStringRef parseQuotedPlistString(_CFStringsFileParseInfo *pInfo, UniCha } } pInfo->curr ++; // Advance past the quote character before returning. - - // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + if (pInfo->error) { + CFRelease(pInfo->error); + pInfo->error = NULL; + } return str; } @@ -328,15 +255,11 @@ static CFStringRef parseUnquotedPlistString(_CFStringsFileParseInfo *pInfo) CF_R return str; } else { CFMutableStringRef str = CFStringCreateMutable(pInfo->allocator, 0); - if (str == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate unquoted string while parsing plist"))); - return NULL; - } CFStringAppendCharacters(str, mark, pInfo->curr - mark); return str; } } - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF"))); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF")); return NULL; } @@ -345,11 +268,10 @@ static CFStringRef parsePlistString(_CFStringsFileParseInfo *pInfo, bool require Boolean foundChar = advanceToNonSpace(pInfo); if (!foundChar) { if (requireObject) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing string"))); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing string")); } return NULL; } - ch = *(pInfo->curr); if (ch == '\'' || ch == '\"') { pInfo->curr ++; @@ -358,63 +280,43 @@ static CFStringRef parsePlistString(_CFStringsFileParseInfo *pInfo, bool require return parseUnquotedPlistString(pInfo); } else { if (requireObject) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid string character at line %d"), lineNumberStrings(pInfo))); - } + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Invalid string character at line %d"), lineNumberStrings(pInfo)); + } return NULL; } } -// when this returns yes, pInfo->error will be set -static BOOL depthIsInvalid(_CFStringsFileParseInfo *pInfo, const uint32_t depth) { - BOOL invalid = NO; -#if __LP64__ -#define MAX_DEPTH 512 -#else -#define MAX_DEPTH 256 -#endif - if (depth > MAX_DEPTH) { - invalid = YES; - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Too many nested arrays or dictionaries at line %d"), lineNumberStrings(pInfo))); - } - return invalid; -} - - -static CFTypeRef parsePlistArray(_CFStringsFileParseInfo *pInfo, uint32_t depth) CF_RETURNS_RETAINED { +static CFTypeRef parsePlistArray(_CFStringsFileParseInfo *pInfo) CF_RETURNS_RETAINED { CFMutableArrayRef array = CFArrayCreateMutable(pInfo->allocator, 0, &kCFTypeArrayCallBacks); - if (array == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate array string while parsing plist"))); - return NULL; - } - CFTypeRef tmp = parsePlistObject(pInfo, false, depth + 1); + CFTypeRef tmp = parsePlistObject(pInfo, false); Boolean foundChar; while (tmp) { CFArrayAppendValue(array, tmp); - if (tmp) { CFRelease(tmp); } + if (tmp) CFRelease(tmp); foundChar = advanceToNonSpace(pInfo); - if (!foundChar) { + if (!foundChar) { if (array) CFRelease(array); - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected ',' for array at line %d"), lineNumberStrings(pInfo))); - return NULL; - } + 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, depth + 1); + tmp = parsePlistObject(pInfo, false); } } foundChar = advanceToNonSpace(pInfo); if (!foundChar || *pInfo->curr != ')') { - if (array) { CFRelease(array); } - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating ')' for array at line %d"), lineNumberStrings(pInfo))); + if (array) CFRelease(array); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating ')' for array at line %d"), lineNumberStrings(pInfo)); return NULL; } - - // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); - - pInfo->curr ++; // consume the ) + if (pInfo->error) { + CFRelease(pInfo->error); + pInfo->error = NULL; + } + pInfo->curr ++; return array; } @@ -426,13 +328,8 @@ __attribute__((noinline)) void _CFPropertyListMissingSemicolonOrValue(UInt32 lin 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."), (unsigned int)line); } -static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo, const uint32_t depth) CF_RETURNS_RETAINED { +static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo) CF_RETURNS_RETAINED { CFMutableDictionaryRef dict = CFDictionaryCreateMutable(pInfo->allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (dict == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate dictionary while parsing plist at line %d"), lineNumberStrings(pInfo))); - return NULL; - } - CFStringRef key = NULL; Boolean failedParse = false; key = parsePlistString(pInfo, false); @@ -443,41 +340,41 @@ static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo, con UInt32 line = lineNumberStrings(pInfo); _CFPropertyListMissingSemicolonOrValue(line); failedParse = true; - parseInfo_setError(pInfo, __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, depth + 1); - if (!value) { - failedParse = true; - break; - } - } else { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected ';' or '=' after key at line %d"), lineNumberStrings(pInfo))); - failedParse = true; + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), line); break; } - CFDictionarySetValue(dict, key, value); + + 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); if (key) CFRelease(key); - key = NULL; + key = NULL; if (value) CFRelease(value); - value = NULL; - foundChar = advanceToNonSpace(pInfo); - if (foundChar && *pInfo->curr == ';') { - pInfo->curr ++; - key = parsePlistString(pInfo, false); - } else { + value = NULL; + foundChar = advanceToNonSpace(pInfo); + if (foundChar && *pInfo->curr == ';') { + pInfo->curr ++; + key = parsePlistString(pInfo, false); + } else { UInt32 line = lineNumberStrings(pInfo); _CFPropertyListMissingSemicolon(line); - failedParse = true; - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), line)); - } + failedParse = true; + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Missing ';' on line %d"), line); + } } if (failedParse) { @@ -485,20 +382,20 @@ static CFDictionaryRef parsePlistDictContent(_CFStringsFileParseInfo *pInfo, con if (dict) CFRelease(dict); return NULL; } - - // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); - + if (pInfo->error) { + CFRelease(pInfo->error); + pInfo->error = NULL; + } return dict; } -static CFTypeRef parsePlistDict(_CFStringsFileParseInfo *pInfo, const uint32_t depth) CF_RETURNS_RETAINED { - CFDictionaryRef dict = parsePlistDictContent(pInfo, depth); - if (!dict) { return NULL; } +static CFTypeRef parsePlistDict(_CFStringsFileParseInfo *pInfo) CF_RETURNS_RETAINED { + CFDictionaryRef dict = parsePlistDictContent(pInfo); + if (!dict) return NULL; Boolean foundChar = advanceToNonSpace(pInfo); if (!foundChar || *pInfo->curr != '}') { - if (dict) { CFRelease(dict); } - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '}' for dictionary at line %d"), lineNumberStrings(pInfo))); + if (dict) CFRelease(dict); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '}' for dictionary at line %d"), lineNumberStrings(pInfo)); return NULL; } pInfo->curr ++; @@ -518,23 +415,23 @@ CF_INLINE unsigned char fromHexDigit(unsigned char ch) { 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 - } + 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 } @@ -542,65 +439,59 @@ static int getDataBytes(_CFStringsFileParseInfo *pInfo, unsigned char *bytes, in #define numBytes 400 static CFTypeRef parsePlistData(_CFStringsFileParseInfo *pInfo) CF_RETURNS_RETAINED { CFMutableDataRef result = CFDataCreateMutable(pInfo->allocator, 0); - if (result == NULL) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to allocate data while parsing property list at line %d"), lineNumberStrings(pInfo))); - return NULL; - } // Read hex bytes and append them to result while (1) { - unsigned char bytes[numBytes]; - int numBytesRead = getDataBytes(pInfo, bytes, numBytes); - if (numBytesRead < 0) { + unsigned char bytes[numBytes]; + int numBytesRead = getDataBytes(pInfo, bytes, numBytes); + if (numBytesRead < 0) { if (result) CFRelease(result); switch (numBytesRead) { - case -2: - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; uneven length"), lineNumberStrings(pInfo))); + case -2: + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; uneven length"), lineNumberStrings(pInfo)); break; - default: - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Malformed data byte group at line %d; invalid hex"), lineNumberStrings(pInfo))); + 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); + return NULL; + } + if (numBytesRead == 0) break; + CFDataAppendBytes(result, bytes, numBytesRead); } - // this is a success path, so clear errors (NOTE: this seems weird, but is historical) - parseInfo_setError(pInfo, NULL); + if (pInfo->error) { + CFRelease(pInfo->error); + pInfo->error = NULL; + } - if (pInfo->curr < pInfo->end && *(pInfo->curr) == '>') { + if (*(pInfo->curr) == '>') { pInfo->curr ++; // Move past '>' return result; } else { if (result) CFRelease(result); - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Expected terminating '>' for data at line %d"), lineNumberStrings(pInfo))); + 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, const uint32_t depth) CF_RETURNS_RETAINED { - if (depthIsInvalid(pInfo, depth)) { - return NULL; - } - +static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireObject) CF_RETURNS_RETAINED { UniChar ch; Boolean foundChar = advanceToNonSpace(pInfo); if (!foundChar) { if (requireObject) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist"))); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected EOF while parsing plist")); } return NULL; } ch = *(pInfo->curr); pInfo->curr ++; if (ch == '{') { - return parsePlistDict(pInfo, depth); + return parsePlistDict(pInfo); } else if (ch == '(') { - return parsePlistArray(pInfo, depth); + return parsePlistArray(pInfo); } else if (ch == '<') { return parsePlistData(pInfo); } else if (ch == '\'' || ch == '\"') { @@ -609,9 +500,9 @@ static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireOb pInfo->curr --; return parseUnquotedPlistString(pInfo); } else { - pInfo->curr --; // Must back off the character we just read + pInfo->curr --; // Must back off the charcter we just read if (requireObject) { - parseInfo_setError(pInfo, __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character '0x%x' at line %d"), ch, lineNumberStrings(pInfo))); + pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unexpected character '0x%x' at line %d"), ch, lineNumberStrings(pInfo)); } return NULL; } @@ -621,68 +512,45 @@ static CFTypeRef parsePlistObject(_CFStringsFileParseInfo *pInfo, bool requireOb CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef allocator, CFDataRef xmlData, CFStringRef originalString, CFStringEncoding guessedEncoding, CFOptionFlags option, CFErrorRef *outError,CFPropertyListFormat *format) { - CFStringRef plistString = NULL; - // Convert the string to UTF16 for parsing old-style if (originalString) { - plistString = CFRetain(originalString); + // Ensure that originalString is not collected while we are using it + CFRetain(originalString); } else { - plistString = CFStringCreateWithBytesNoCopy(kCFAllocatorSystemDefault, CFDataGetBytePtr(xmlData), CFDataGetLength(xmlData), guessedEncoding, false, kCFAllocatorNull); - if (!plistString) { + 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; - const CFIndex length = CFStringGetLength(plistString); + 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(plistString); + 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(plistString, CFRangeMake(0, length), buf); + CFStringGetCharacters(originalString, CFRangeMake(0, length), buf); createdBuffer = true; - CFRelease(plistString); - plistString = NULL; } _CFStringsFileParseInfo stringsPInfo; stringsPInfo.begin = buf; - - CFIndex unused; - if (os_add_overflow((CFIndex)buf, (CFIndex)length, &unused)) { - CRSetCrashLogMessage("Unable to address entirety of CFPropertyList"); - if (createdBuffer) { - CFAllocatorDeallocate(allocator, buf); - } else { - CFRelease(plistString); - } - return NULL; - } stringsPInfo.end = buf+length; stringsPInfo.curr = buf; stringsPInfo.allocator = allocator; stringsPInfo.mutabilityOption = option; stringsPInfo.stringSet = CFSetCreateMutable(allocator, 0, &kCFTypeSetCallBacks); - if (stringsPInfo.stringSet == NULL) { - CRSetCrashLogMessage("CFPropertyList ran out of memory while attempting to allocate temporary storage."); - if (createdBuffer) { - CFAllocatorDeallocate(allocator, buf); - } else { - CFRelease(plistString); - } - return NULL; - } stringsPInfo.error = NULL; const UniChar *begin = stringsPInfo.curr; @@ -692,31 +560,24 @@ CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef // 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, /*depth*/ 0); + result = parsePlistObject(&stringsPInfo, true); if (result) { foundChar = advanceToNonSpace(&stringsPInfo); if (foundChar) { if (CFGetTypeID(result) != CFStringGetTypeID()) { - if (result) { - CFRelease(result); - } + if (result) CFRelease(result); result = NULL; - if (stringsPInfo.error) { - CFRelease(stringsPInfo.error); - } + 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 - if (result) { - CFRelease(result); - } - if (stringsPInfo.error) { - CFRelease(stringsPInfo.error); - stringsPInfo.error = NULL; - } + if (result) CFRelease(result); + 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, 0); + result = parsePlistDictContent(&stringsPInfo); } } } @@ -734,20 +595,14 @@ CF_PRIVATE CFTypeRef __CFCreateOldStylePropertyListOrStringsFile(CFAllocatorRef } else if (stringsPInfo.error) { // Caller doesn't want it, so we need to free it CFRelease(stringsPInfo.error); - stringsPInfo.error = NULL; } } - if (result && format) { - *format = kCFPropertyListOpenStepFormat; - } + if (result && format) *format = kCFPropertyListOpenStepFormat; - if (createdBuffer) { - CFAllocatorDeallocate(allocator, buf); - } else { - CFRelease(plistString); - } - if (stringsPInfo.stringSet) { CFRelease(stringsPInfo.stringSet); } + if (createdBuffer) CFAllocatorDeallocate(allocator, buf); + CFRelease(stringsPInfo.stringSet); + CFRelease(originalString); return result; } diff --git a/CoreFoundation/Parsing.subproj/CFPropertyList.c b/CoreFoundation/Parsing.subproj/CFPropertyList.c index e45afdc3c0..ad2b6bccef 100644 --- a/CoreFoundation/Parsing.subproj/CFPropertyList.c +++ b/CoreFoundation/Parsing.subproj/CFPropertyList.c @@ -1,7 +1,7 @@ /* CFPropertyList.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -9,7 +9,6 @@ */ #include -#include #include #include #include @@ -759,12 +758,11 @@ static Boolean parseXMLElement(_CFXMLPlistParseInfo *pInfo, Boolean *isKey, CFTy static UInt32 lineNumber(_CFXMLPlistParseInfo *pInfo) { const char *p = pInfo->begin; UInt32 count = 1; - while (p < pInfo->end && p < pInfo->curr) { + while (p < pInfo->curr) { if (*p == '\r') { count ++; - if (p + 1 < pInfo->end && p + 1 < pInfo->curr && *(p + 1) == '\n') { + if (*(p + 1) == '\n') p ++; - } } else if (*p == '\n') { count ++; } @@ -1594,8 +1592,7 @@ static Boolean parseDictTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { const char *base = pInfo->curr; - static const unsigned char dataDecodeTableSize = 128; - static const signed char dataDecodeTable[dataDecodeTableSize] = { + 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, @@ -1622,7 +1619,7 @@ static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { int cntr = 0; for (; pInfo->curr < pInfo->end; pInfo->curr++) { - unsigned char c = *(pInfo->curr); + signed char c = *(pInfo->curr); if (c == '<') { break; } @@ -1631,13 +1628,6 @@ static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { } else if (!isspace(c)) { numeq = 0; } - - if (c >= dataDecodeTableSize) { - pInfo->error = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Could not interpret on line %d (invalid character 0x%hhX)"), lineNumber(pInfo), c); - if (tmpbuf) { CFAllocatorDeallocate(pInfo->allocator, tmpbuf); } - return false; - } - if (dataDecodeTable[c] < 0) continue; cntr++; @@ -1654,7 +1644,8 @@ static Boolean parseDataTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { // and really potentially fragment memory tmpbuflen += 256 * 1024; } - tmpbuf = __CFSafelyReallocateWithAllocator(pInfo->allocator, tmpbuf, tmpbuflen, 0, NULL); + 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; @@ -1924,13 +1915,13 @@ static Boolean parseIntegerTag(_CFXMLPlistParseInfo *pInfo, CFTypeRef *out) { GET_CH; if ('0' == ch) { if (pInfo->curr + 1 < pInfo->end && ('x' == *(pInfo->curr + 1) || 'X' == *(pInfo->curr + 1))) { - pInfo->curr++; - isHex = true; - } else { - hadLeadingZero = true; - } - pInfo->curr++; - } + pInfo->curr++; + isHex = true; + } else { + hadLeadingZero = true; + } + pInfo->curr++; + } GET_CH; while ('0' == ch) { hadLeadingZero = true; @@ -2394,69 +2385,50 @@ static Boolean __savePlistData(CFDataRef data, CFOptionFlags opt) { // 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, Boolean doXML, Boolean doOpenStep) { +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(xmlData != NULL, __kCFLogAssertion, "%s(): NULL data not allowed", __PRETTY_FUNCTION__); + CFAssert2(option == kCFPropertyListImmutable || option == kCFPropertyListMutableContainers || option == kCFPropertyListMutableContainersAndLeaves, __kCFLogAssertion, "%s(): Unrecognized option %lu", __PRETTY_FUNCTION__, option); CFIndex length = CFDataGetLength(xmlData); if (!length) { if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Conversion of string failed. The string is empty.")); return false; } - CFTypeRef result = NULL; + _CFXMLPlistParseInfo pInfoBuf; _CFXMLPlistParseInfo *pInfo = &pInfoBuf; + CFTypeRef result; + // 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; pInfo->begin = buf; - CFIndex unused; - if (os_add_overflow((CFIndex)buf, (CFIndex)length, &unused)) { - if (outError) *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to address entirety of CFPropertyList")); - return false; - } - pInfo->end = buf + length - skipBytes; + pInfo->end = buf+length; pInfo->curr = buf; pInfo->allocator = allocator; pInfo->error = NULL; - pInfo->mutabilityOption = option & kCFPropertyListMutabilityMask; + _createStringMap(pInfo); + pInfo->mutabilityOption = option; pInfo->allowNewTypes = allowNewTypes; pInfo->skip = false; + pInfo->keyPaths = createTopLevelKeypaths(allocator, keyPaths); - if (doXML) { - CFRetain(xmlData); - _createStringMap(pInfo); - pInfo->keyPaths = createTopLevelKeypaths(allocator, keyPaths); - - Boolean success = parseXMLPropertyList(pInfo, &result); - if (success && result && format) *format = kCFPropertyListXMLFormat_v1_0; - - _cleanupStringMap(pInfo); - if (pInfo->keyPaths) CFRelease(pInfo->keyPaths); - CFRelease(xmlData); - - if (success) { - *out = result; // caller releases - return true; - } - } + Boolean success = parseXMLPropertyList(pInfo, &result); + if (success && result && format) *format = kCFPropertyListXMLFormat_v1_0; - if (!doOpenStep) { - if (outError) { - if (doXML && pInfo->error) { - *outError = pInfo->error; // caller releases - } else { - // pInfo->error will be nil because we didn't parse XML - *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unsupported property list")); - } - } else if (pInfo->error) { - CFRelease(pInfo->error); - } - return false; + _cleanupStringMap(pInfo); + if (pInfo->keyPaths) CFRelease(pInfo->keyPaths); + CFRelease(xmlData); + + if (success) { + *out = result; // caller releases + return true; } // Try again, old-style @@ -2521,18 +2493,6 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef initStatics(); CFStringEncoding encoding; - // we support the restriction of the kinds of parses we will try - Boolean doOpenStep = (option & kCFPropertyListSupportedFormatOpenStepFormat) != 0; - Boolean doBinary = (option & kCFPropertyListSupportedFormatBinary_v1_0) != 0; - Boolean doXML = (option & kCFPropertyListSupportedFormatXML_v1_0) != 0; - if (!doOpenStep && !doBinary && !doXML) { - // if you ask for nothing the historic behavior is to try everything - doOpenStep = true; - doBinary = true; - doXML = true; - } - - if (!data || CFDataGetLength(data) == 0) { if (outError) { *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Cannot parse a NULL or zero-length data")); @@ -2545,19 +2505,11 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef #endif // Ignore the error from CFTryParseBinaryPlist -- if it doesn't work, we're going to try again anyway using the XML parser - if (doBinary && __CFTryParseBinaryPlist(allocator, data, (option&kCFPropertyListMutabilityMask), out, NULL)) { + if (__CFTryParseBinaryPlist(allocator, data, option, out, NULL)) { if (format) *format = kCFPropertyListBinaryFormat_v1_0; return true; } - // stop working if there is nothing left to do - if (!doXML && !doOpenStep) { - if (outError) { - *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unsupported property list")); - } - return false; - } - // Use our own error variable here so we can check it against NULL later CFErrorRef subError = NULL; CFIndex skip = 0; @@ -2581,7 +2533,7 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef if (encoding == kCFStringEncodingUTF8) { // Use fast path - return _CFPropertyListCreateFromUTF8Data(allocator, data, skip, NULL, encoding, option, outError, allowNewTypes, format, topLevelKeys, out, doXML, doOpenStep); + return _CFPropertyListCreateFromUTF8Data(allocator, data, skip, NULL, encoding, option, outError, allowNewTypes, format, topLevelKeys, out); } // Convert to UTF8 first @@ -2593,7 +2545,7 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef CFDataRef utf8Data = _createUTF8DataFromString(allocator, xmlString); - Boolean result = _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, outError, allowNewTypes, format, topLevelKeys, out, doXML, doOpenStep); + Boolean result = _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, outError, allowNewTypes, format, topLevelKeys, out); if (xmlString) CFRelease(xmlString); if (utf8Data) CFRelease(utf8Data); @@ -2607,11 +2559,10 @@ static Boolean _CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef #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, true, true); + _CFPropertyListCreateFromUTF8Data(allocator, utf8Data, 0, xmlString, 0, option, error, allowNewTypes, format, NULL, &result); if (utf8Data) CFRelease(utf8Data); return result; @@ -2743,24 +2694,13 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, for (CFIndex i = 0; i < keyPathCount; i++) { CFStringRef oneKey = (CFStringRef)CFArrayGetValueAtIndex(keyPathArray, i); - - // Peek into the next level see what the type is - // if it is a dictionary interpret the key as a dictionary key - // if it is an array try to interpret the key as a integer key - // - const bool isDictionary = __CFBinaryPlistIsDictionary(databytes, datalen, valueOffset, &trailer); - if (isDictionary) { + SInt32 intValue = CFStringGetIntValue(oneKey); + 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 success = __CFBinaryPlistGetOffsetForValueFromDictionary3(databytes, datalen, valueOffset, &trailer, (CFTypeRef)oneKey, &keyOffset, &valueOffset, false, objects); } else { - const bool isArray = __CFBinaryPlistIsArray(databytes, datalen, valueOffset, &trailer); - if (isArray) { - // Treat as integer index into an array - const SInt32 intValue = CFStringGetIntValue(oneKey); - if (intValue >= 0 && intValue != INT_MAX) { - success = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, valueOffset, &trailer, intValue, &valueOffset, objects); - } - } + // Treat as integer index into an array + success = __CFBinaryPlistGetOffsetForValueFromArray2(databytes, datalen, valueOffset, &trailer, intValue, &valueOffset, objects); } if (!success) { @@ -2819,73 +2759,6 @@ bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, return success; } -/*! - SPI to return just the keys from the top-level dictionary of a property-list. This can be valuable in cases where you want to check for the presence of a key. - @param allocator allocate to use when creating the array of objects - @param data data to explore - @param option currently unused, should be 0 - @param outError optional out-param error - @return NULL if anything went wrong (`outError` should describe why) - */ -CFSetRef _CFPropertyListCopyTopLevelKeys(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFErrorRef *outError) { - CFSetRef result = NULL; - if (data != NULL) { - const uint8_t *databytes = CFDataGetBytePtr(data); - const uint64_t datalen = CFDataGetLength(data); - - // only try xml if the bplist fails - bool tryXML = true; - - // bplist: - if (8 <= datalen) { - uint8_t marker; - CFBinaryPlistTrailer trailer; - uint64_t offset; - - if (__CFBinaryPlistGetTopLevelInfo(databytes, datalen, &marker, &offset, &trailer)) { - tryXML = false; - result = __CFBinaryPlistCopyTopLevelKeys(allocator, databytes, datalen, offset, &trailer); - } - } - - - if (tryXML) { - // xml: - // This path remains unoptimized; friends don't let friends use XML plists. - const CFPropertyListRef plist = CFPropertyListCreateWithData(allocator, data, option, NULL, outError); - if (plist) { - const CFTypeID type = CFGetTypeID(plist); - if (type != dicttype) { - if (outError) { - *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Cannot copy top-level keys for plist with non-dictionary root object")); - } - } else { - const CFIndex count = CFDictionaryGetCount(plist); - CFTypeRef *keyBuffer = malloc(sizeof(CFTypeRef) * count); - if (keyBuffer == NULL) { - if (outError) { - *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to convert string to correct encoding")); - } - } else { - CFDictionaryGetKeysAndValues(plist, keyBuffer, NULL); - result = CFSetCreate(allocator, keyBuffer, count, &kCFTypeSetCallBacks); - free(keyBuffer); - } - } - CFRelease(plist); - } - } - } - - if (result == NULL && outError) { - *outError = __CFPropertyListCreateError(kCFPropertyListReadCorruptError, CFSTR("Unable to extract top-level keys")); - } - - return result; -} - - - // Legacy CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString, Boolean allowNewTypes, CFPropertyListFormat *format) { initStatics(); @@ -2931,20 +2804,20 @@ CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef p CFDataRef data = NULL; + CFStringRef validErr = NULL; + if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) { + if (error) { + *error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Property list invalid for format: %d (%@)"), format, validErr); + } + if (validErr) CFRelease(validErr); + return NULL; + } + if (format == kCFPropertyListOpenStepFormat) { CFLog(kCFLogLevelError, CFSTR("Property list format kCFPropertyListOpenStepFormat not supported for writing")); return NULL; } else if (format == kCFPropertyListXMLFormat_v1_0) { - CFStringRef validErr = NULL; - if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) { - if (error) { - *error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Property list invalid for format: %d (%@)"), format, validErr); - } - if (validErr) CFRelease(validErr); - return NULL; - } - - data = _CFPropertyListCreateXMLData(allocator, propertyList, false); + data = _CFPropertyListCreateXMLData(allocator, propertyList, true); } else if (format == kCFPropertyListBinaryFormat_v1_0) { // TODO: Is it more efficient to create a stream here or just use a mutable data? CFWriteStreamRef stream = CFWriteStreamCreateWithAllocatedBuffers(kCFAllocatorSystemDefault, allocator); CFWriteStreamOpen(stream); @@ -2973,10 +2846,8 @@ CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef str CFStringRef validErr = NULL; if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) { - if (error) { - *error = __CFPropertyListCreateError(kCFPropertyListWriteStreamError, CFSTR("Property list invalid for format: %d (%@)"), format, validErr); - } - if (validErr) CFRelease(validErr); + CFLog(kCFLogLevelError, CFSTR("Property list invalid for format: %ld (%@)"), format, validErr); + if (validErr) CFRelease(validErr); return 0; } if (format == kCFPropertyListOpenStepFormat) { @@ -3035,6 +2906,12 @@ CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStrea CFErrorRef error = NULL; // For backwards compatibility, we check the format parameter up front since these do not have CFError counterparts in the newer API + CFStringRef validErr = NULL; + if (!_CFPropertyListIsValidWithErrorString(propertyList, format, &validErr)) { + if (errorString) *errorString = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("Property list invalid for format (%@)"), validErr); + if (validErr) CFRelease(validErr); + return 0; + } if (format == kCFPropertyListOpenStepFormat) { if (errorString) *errorString = (CFStringRef)CFRetain(CFSTR("Property list format kCFPropertyListOpenStepFormat not supported for writing")); return 0; @@ -3080,7 +2957,7 @@ static bool __convertReadStreamToBytes(CFReadStreamRef stream, CFIndex max, uint bufsize += 256 * 1024; } if (bufsize < buflen + retlen) bufsize = buflen + retlen; - buf = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, buf, bufsize, 0, NULL); + buf = (uint8_t *)CFAllocatorReallocate(kCFAllocatorSystemDefault, buf, bufsize, 0); if (!buf) HALT; } memmove(buf + buflen, sbuf, retlen); diff --git a/CoreFoundation/Parsing.subproj/CFPropertyList.h b/CoreFoundation/Parsing.subproj/CFPropertyList.h index bd785bd0d4..36248ab792 100644 --- a/CoreFoundation/Parsing.subproj/CFPropertyList.h +++ b/CoreFoundation/Parsing.subproj/CFPropertyList.h @@ -1,7 +1,7 @@ /* CFPropertyList.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -21,12 +21,10 @@ CF_EXTERN_C_BEGIN typedef CF_OPTIONS(CFOptionFlags, CFPropertyListMutabilityOptions) { kCFPropertyListImmutable = 0, - kCFPropertyListMutableContainers = 1 << 0, - kCFPropertyListMutableContainersAndLeaves = 1 << 1, + kCFPropertyListMutableContainers, + kCFPropertyListMutableContainersAndLeaves }; -CF_IMPLICIT_BRIDGING_DISABLED - /* Creates a property list object from its XML description; xmlData should be the raw bytes of that description, possibly the contents of an XML @@ -38,7 +36,7 @@ CF_IMPLICIT_BRIDGING_DISABLED This function is deprecated. See CFPropertyListCreateWithData() for a replacement. */ CF_EXPORT -CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags mutabilityOption, CFStringRef *errorString) API_DEPRECATED("Use CFPropertyListCreateWithData instead.", macos(10.0,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags mutabilityOption, CFStringRef *errorString) CF_DEPRECATED(10_0, 10_10, 2_0, 8_0, "Use CFPropertyListCreateWithData instead."); /* Returns the XML description of the given object; propertyList must @@ -53,9 +51,7 @@ CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDa This function is deprecated. See CFPropertyListCreateData() for a replacement. */ CF_EXPORT -CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList) API_DEPRECATED("Use CFPropertyListCreateData instead.", macos(10.0,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_IMPLICIT_BRIDGING_ENABLED +CFDataRef CFPropertyListCreateXMLData(CFAllocatorRef allocator, CFPropertyListRef propertyList) CF_DEPRECATED(10_0, 10_10, 2_0, 8_0, "Use CFPropertyListCreateData instead."); /* Recursively creates a copy of the given property list (so nested arrays @@ -80,8 +76,6 @@ typedef CF_ENUM(CFIndex, CFPropertyListFormat) { CF_EXPORT Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat format); -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 * a bunch of bytes to the stream. The output plist format can be chosen. @@ -93,7 +87,7 @@ CF_IMPLICIT_BRIDGING_DISABLED * * This function is deprecated. See CFPropertyListWrite() for a replacement. */ CF_EXPORT -CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFStringRef *errorString) API_DEPRECATED("Use CFPropertyListWrite instead.", macos(10.2,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFStringRef *errorString) CF_DEPRECATED(10_2, 10_10, 2_0, 8_0, "Use CFPropertyListWrite instead."); /* Same as current function CFPropertyListCreateFromXMLData() @@ -108,40 +102,34 @@ CFIndex CFPropertyListWriteToStream(CFPropertyListRef propertyList, CFWriteStrea * * This function is deprecated. See CFPropertyListCreateWithStream() for a replacement. */ CF_EXPORT -CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFStringRef *errorString) API_DEPRECATED("Use CFPropertyListCreateWithStream instead.", macos(10.2,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)); - -CF_IMPLICIT_BRIDGING_ENABLED - -CF_IMPLICIT_BRIDGING_DISABLED +CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags mutabilityOption, CFPropertyListFormat *format, CFStringRef *errorString) CF_DEPRECATED(10_2, 10_10, 2_0, 8_0, "Use CFPropertyListCreateWithStream instead."); CF_ENUM(CFIndex) { 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 -} API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +} 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. */ CF_EXPORT -CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* Create and return a property list with a CFReadStream 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. The streamLength parameter specifies the number of bytes to read from the stream. Set streamLength to 0 to read until the end of the stream is detected. 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. */ CF_EXPORT -CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFReadStreamRef stream, CFIndex streamLength, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* Write the bytes of a serialized property list out to a stream. The stream must be opened and configured. The format of the property list can be chosen with the format parameter. The options parameter is currently unused and should be set to 0. The return value is the number of bytes written or 0 in the case of an error. 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. */ CF_EXPORT -CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* Create a CFData with the bytes of a serialized property list. The format of the property list can be chosen with the format parameter. The options parameter is currently unused and should be set to 0. 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 conversion succeeds, the returned value is a reference to the created data. It is the responsibility of the caller to release this value. */ CF_EXPORT -CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); - -CF_IMPLICIT_BRIDGING_ENABLED +CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Parsing.subproj/CFPropertyList_Private.h b/CoreFoundation/Parsing.subproj/CFPropertyList_Private.h deleted file mode 100644 index a5d77addcf..0000000000 --- a/CoreFoundation/Parsing.subproj/CFPropertyList_Private.h +++ /dev/null @@ -1,19 +0,0 @@ -/* CFPropertyList.h - Copyright (c) 2017, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - */ - -#import - -// this is only allowed the first 8 bits -typedef CF_OPTIONS(CFOptionFlags, CFPropertyListSupportedFormats) { - kCFPropertyListSupportedFormatOpenStepFormat = 1 << 8, - kCFPropertyListSupportedFormatBinary_v1_0 = 1 << 9, - kCFPropertyListSupportedFormatXML_v1_0 = 1 << 10, -}; - -#define kCFPropertyListMutabilityMask 0xFF // first 8 bits diff --git a/CoreFoundation/Parsing.subproj/CFXMLInputStream.c b/CoreFoundation/Parsing.subproj/CFXMLInputStream.c index c3c7932790..3b8c89976e 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLInputStream.c +++ b/CoreFoundation/Parsing.subproj/CFXMLInputStream.c @@ -1,7 +1,7 @@ /* CFXMLInputStream.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -205,7 +205,7 @@ static void growCharacterBuffer(_CFXMLInputStream *stream) { CFIndex currCharDelta = stream->currentChar ? stream->currentChar - stream->charBuffer : -1; CFIndex markDelta = stream->mark ? stream->mark - stream->charBuffer: -1; CFIndex parserMarkDelta = stream->parserMark ? stream->parserMark - stream->charBuffer: -1; - UniChar *newBuffer = __CFSafelyReallocateWithAllocator(stream->allocator, stream->charBuffer, stream->bufferCapacity * 2 * sizeof(UniChar), 0, NULL); + UniChar *newBuffer = (UniChar *)CFAllocatorReallocate(stream->allocator, stream->charBuffer, stream->bufferCapacity * 2 * sizeof(UniChar), 0); stream->bufferCapacity *= 2; if (newBuffer != stream->charBuffer) { stream->charBuffer = newBuffer; diff --git a/CoreFoundation/Parsing.subproj/CFXMLInputStream.h b/CoreFoundation/Parsing.subproj/CFXMLInputStream.h index a37d284bd9..c797a0f249 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLInputStream.h +++ b/CoreFoundation/Parsing.subproj/CFXMLInputStream.h @@ -1,7 +1,7 @@ /* CFXMLInputStream.h - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Parsing.subproj/CFXMLNode.c b/CoreFoundation/Parsing.subproj/CFXMLNode.c index 25b33fc6ab..9ee42aea4f 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLNode.c +++ b/CoreFoundation/Parsing.subproj/CFXMLNode.c @@ -1,7 +1,7 @@ /* CFXMLNode.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Parsing.subproj/CFXMLNode.h b/CoreFoundation/Parsing.subproj/CFXMLNode.h index 5e120de807..56e4b5ee60 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLNode.h +++ b/CoreFoundation/Parsing.subproj/CFXMLNode.h @@ -1,7 +1,7 @@ /* CFXMLNode.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -21,8 +21,6 @@ CF_IMPLICIT_BRIDGING_ENABLED CF_EXTERN_C_BEGIN -#define __CFXMLNode_DEPRECATION_MSG "CFXMLNode is deprecated, use NSXMLParser, NSXMLDocument or libxml2 library instead" - CF_ENUM(CFIndex) { kCFXMLNodeCurrentVersion = 1 }; @@ -155,40 +153,38 @@ typedef struct { */ CF_EXPORT -CFTypeID CFXMLNodeGetTypeID(void) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFXMLNodeRef CFXMLNodeCreateCopy(CFAllocatorRef alloc, CFXMLNodeRef origNode) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFXMLNodeTypeCode CFXMLNodeGetTypeCode(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFStringRef CFXMLNodeGetString(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const void *CFXMLNodeGetInfoPtr(CFXMLNodeRef node) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -CFIndex CFXMLNodeGetVersion(CFXMLNodeRef node) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLNode_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFXMLNodeRef CFXMLTreeGetNode(CFXMLTreeRef xmlTree) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); -#undef __CFXMLNode_DEPRECATION_MSG - CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/Parsing.subproj/CFXMLParser.c b/CoreFoundation/Parsing.subproj/CFXMLParser.c index 50e41b6e57..31381cadfe 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLParser.c +++ b/CoreFoundation/Parsing.subproj/CFXMLParser.c @@ -1,5 +1,5 @@ /* CFXMLParser.c - Copyright (c) 1999-2017, Apple Inc. All rights reserved. + Copyright (c) 1999-2016, Apple Inc. All rights reserved. Responsibility: David Smith */ @@ -634,7 +634,7 @@ static Boolean parseAttributeListDeclaration(CFXMLParserRef parser) { if (capacity == attListData.numberOfAttributes) { capacity = 2*capacity; if (attributes != attributeArray) { - attributes = __CFSafelyReallocateWithAllocator(CFGetAllocator(parser), attributes, capacity * sizeof(CFXMLAttributeDeclarationInfo), 0, NULL); + attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorReallocate(CFGetAllocator(parser), attributes, capacity * sizeof(CFXMLAttributeDeclarationInfo), 0); } else { attributes = (CFXMLAttributeDeclarationInfo *)CFAllocatorAllocate(CFGetAllocator(parser), capacity * sizeof(CFXMLAttributeDeclarationInfo), 0); } @@ -1742,7 +1742,7 @@ static Boolean reportNewLeaf(CFXMLParserRef parser) { static void pushXMLNode(CFXMLParserRef parser, void *node) { parser->top ++; if ((unsigned)(parser->top - parser->stack) == parser->capacity) { - parser->stack = __CFSafelyReallocateWithAllocator(CFGetAllocator(parser), parser->stack, 2 * parser->capacity * sizeof(void *), 0, NULL); + parser->stack = (void **)CFAllocatorReallocate(CFGetAllocator(parser), parser->stack, 2 * parser->capacity * sizeof(void *), 0); parser->top = parser->stack + parser->capacity; parser->capacity = 2*parser->capacity; } diff --git a/CoreFoundation/Parsing.subproj/CFXMLParser.h b/CoreFoundation/Parsing.subproj/CFXMLParser.h index e7baa76454..e5483b7c78 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLParser.h +++ b/CoreFoundation/Parsing.subproj/CFXMLParser.h @@ -1,10 +1,9 @@ /* CFXMLParser.h - Copyright (c) 1998-2017, Apple Inc. All rights reserved. + Copyright (c) 1998-2016, Apple Inc. All rights reserved. */ /* CFXMLParser is deprecated as of Mac OS X 10.8. The suggested replacements are the Foundation classes NSXMLParser and NSXMLDocument, or the libxml2 library. */ - #if !defined(__COREFOUNDATION_CFXMLPARSER__) #define __COREFOUNDATION_CFXMLPARSER__ 1 @@ -19,8 +18,6 @@ CF_IMPLICIT_BRIDGING_ENABLED CF_EXTERN_C_BEGIN -#define __CFXMLParser_DEPRECATION_MSG "CFXMLParser is deprecated, use NSXMLParser, NSXMLDocument or libxml2 library instead" - typedef struct __CFXMLParser * CFXMLParserRef; /* These are the various options you can configure the parser with. These are @@ -154,7 +151,7 @@ typedef struct { } CFXMLParserContext; CF_EXPORT -CFTypeID CFXMLParserGetTypeID(void) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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 @@ -164,48 +161,48 @@ CFTypeID CFXMLParserGetTypeID(void) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG 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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +void CFXMLParserGetContext(CFXMLParserRef parser, CFXMLParserContext *context) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +void CFXMLParserGetCallBacks(CFXMLParserRef parser, CFXMLParserCallBacks *callBacks) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -CFURLRef CFXMLParserGetSourceURL(CFXMLParserRef parser) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFXMLParserStatusCode CFXMLParserGetStatusCode(CFXMLParserRef parser) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -CFStringRef CFXMLParserCopyErrorDescription(CFXMLParserRef parser) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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 @@ -213,7 +210,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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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 @@ -222,17 +219,17 @@ Boolean CFXMLParserParse(CFXMLParserRef parser) API_DEPRECATED(__CFXMLParser_DEP /* 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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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 @@ -240,7 +237,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) API_DEPRECATED(__CFXMLParser_DEPRECATION_MSG, macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +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. */ @@ -269,6 +266,6 @@ CF_EXPORT const CFStringRef kCFXMLTreeErrorStatusCode; CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED -#undef __CFXMLParser_DEPRECATION_MSG + #endif /* ! __COREFOUNDATION_CFXMLPARSER__ */ diff --git a/CoreFoundation/Parsing.subproj/CFXMLTree.c b/CoreFoundation/Parsing.subproj/CFXMLTree.c index 405596601d..18f0602cc8 100644 --- a/CoreFoundation/Parsing.subproj/CFXMLTree.c +++ b/CoreFoundation/Parsing.subproj/CFXMLTree.c @@ -1,7 +1,7 @@ /* CFXMLTree.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.c b/CoreFoundation/PlugIn.subproj/CFBundle.c index 2e28f607e4..cf90cae89c 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle.c @@ -1,7 +1,7 @@ /* CFBundle.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -47,7 +47,6 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean alreadyLocked); -static void _CFBundleUnloadScheduledBundles(void); #define LOG_BUNDLE_LOAD 0 @@ -118,6 +117,9 @@ CONST_STRING_DECL(_kCFBundleCFMLoadAsBundleKey, "CFBundleCFMLoadAsBundle") // Keys used by NSBundle for loaded Info plists. CONST_STRING_DECL(_kCFBundlePrincipalClassKey, "NSPrincipalClass") +static char __CFBundleMainID__[1026] = {0}; +CF_PRIVATE char *__CFBundleMainID = __CFBundleMainID__; + static CFTypeID __kCFBundleTypeID = _kCFRuntimeNotATypeID; static pthread_mutex_t CFBundleGlobalDataLock = PTHREAD_MUTEX_INITIALIZER; @@ -128,14 +130,19 @@ static CFMutableArrayRef _allBundles = NULL; static CFMutableSetRef _bundlesToUnload = NULL; static Boolean _scheduledBundlesAreUnloading = false; -static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean doFinalProcessing, Boolean unique, Boolean addToTables); -static void _CFBundleEnsureBundlesUpToDateWithHint(CFStringRef hint); -static void _CFBundleEnsureAllBundlesUpToDate(void); -static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath, Boolean permissive); +static Boolean _initedMainBundle = false; +static CFBundleRef _mainBundle = NULL; + +static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing, Boolean unique); +static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle); +static void _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(CFStringRef hint); +static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void); +static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath); static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths); #pragma mark - + CF_PRIVATE os_log_t _CFBundleResourceLogger(void) { static os_log_t _log; static dispatch_once_t onceToken; @@ -163,15 +170,19 @@ static Boolean _useUnsafeUnretainedTables(void) { } #endif + + + + #pragma mark - #pragma mark Bundle Tables -static void _CFBundleAddToTables(CFBundleRef bundle) { +static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) { if (bundle->_isUnique) return; CFStringRef bundleID = CFBundleGetIdentifier(bundle); - pthread_mutex_lock(&CFBundleGlobalDataLock); + if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock); // Add to the _allBundles list if (!_allBundles) { @@ -226,7 +237,7 @@ static void _CFBundleAddToTables(CFBundleRef bundle) { CFRelease(bundlesWithThisID); } } - pthread_mutex_unlock(&CFBundleGlobalDataLock); + if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock); } static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef bundleID) { @@ -265,9 +276,23 @@ static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CF #endif } -static CFBundleRef _CFBundleGetFromTables(CFStringRef bundleID) { +#pragma mark - + +static CFBundleRef _CFBundleCopyBundleForURL(CFURLRef url, Boolean alreadyLocked) { + CFBundleRef result = NULL; + 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) pthread_mutex_unlock(&CFBundleGlobalDataLock); + return result; +} + +static CFBundleRef _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(CFStringRef bundleID) { CFBundleRef result = NULL, bundle; - pthread_mutex_lock(&CFBundleGlobalDataLock); if (_bundlesByIdentifier && bundleID) { // Note that this array is maintained in descending order by version number CFArrayRef bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID); @@ -284,38 +309,142 @@ static CFBundleRef _CFBundleGetFromTables(CFStringRef bundleID) { } } } - pthread_mutex_unlock(&CFBundleGlobalDataLock); return result; } -static CFBundleRef _CFBundleCopyFromTablesForURL(CFURLRef url) { - /* - If you're curious why this doesn't consult the main bundle URL, consider the case where you have a directory structure like this: - - /S/L/F/Foo.framework/Foo - /S/L/F/Foo.framework/food (a daemon for the Foo framework) - - And the main executable is 'food'. - - This flat structure can happen on iOS, with its more common version 3 bundles. In this scenario, there are theoretically two different bundles that could be returned: one for the framework, one for the daemon. They have the same URL but different bundle identifiers. - - Since the main bundle is not part of the bundle tables, we can support this scenario by having the _bundlesByURL data structure hold the bundle for URL "/S/L/F/Foo.framework/Foo" and _mainBundle (in CFBundle_Main.c) hold the bundle for URL "/S/L/F/Foo.framework/food". - */ - CFBundleRef result = NULL; - pthread_mutex_lock(&CFBundleGlobalDataLock); - if (_bundlesByURL) result = (CFBundleRef)CFDictionaryGetValue(_bundlesByURL, url); - if (result && !result->_url) { - result = NULL; - CFDictionaryRemoveValue(_bundlesByURL, url); +static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) { + //!!! need to handle frameworks, NT; need to integrate with NSBundle - drd + UniChar buff[CFMaxPathSize]; + CFIndex buffLen; + CFURLRef url = NULL; + CFStringRef outstr; + + buffLen = CFStringGetLength(str); + if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize; + CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff); + +#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); + buffLen -= 4; + // If this is an _debug, we should strip that before looking for the bundle + if (buffLen >= 7 && (_wcsnicmp((wchar_t *)&buff[buffLen-6], L"_debug", 6) == 0)) buffLen -= 6; + + if (buffLen + 1 + extensionLength < CFMaxPathSize) { + buff[buffLen] = '.'; + buffLen ++; + CFStringGetCharacters(_CFBundleWindowsResourceDirectoryExtension, CFRangeMake(0, extensionLength), buff + buffLen); + buffLen += extensionLength; + outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull); + url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, outstr, PLATFORM_PATH_STYLE, true); + CFRelease(outstr); + } } - if (result) CFRetain(result); - pthread_mutex_unlock(&CFBundleGlobalDataLock); - return result; +#endif + + if (!url) { + buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); // Remove exe name + + 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); + if (startOfLastDir > 0 && startOfLastDir < buffLen) { + CFStringRef lastDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfLastDir]), buffLen - startOfLastDir); + + if (CFEqual(lastDirName, _CFBundleGetPlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetAlternatePlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetOtherPlatformExecutablesSubdirectoryName()) || CFEqual(lastDirName, _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName())) { + // This is a new bundle. Back off a few more levels + if (buffLen > 0) { + // Remove platform folder + buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); + } + if (buffLen > 0) { + // Remove executables folder (if present) + CFIndex startOfNextDir = _CFStartOfLastPathComponent(buff, buffLen); + if (startOfNextDir > 0 && startOfNextDir < buffLen) { + CFStringRef nextDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfNextDir]), buffLen - startOfNextDir); + if (CFEqual(nextDirName, _CFBundleExecutablesDirectoryName)) buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); + CFRelease(nextDirName); + } + } + if (buffLen > 0) { + // Remove support files folder + buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); + } + } + CFRelease(lastDirName); + } + } + + if (buffLen > 0) { + outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull); + url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, outstr, PLATFORM_PATH_STYLE, true); + CFRelease(outstr); + } + } + return url; +} + +static CFURLRef _CFBundleCopyResolvedURLForExecutableURL(CFURLRef url) { + // this is necessary so that we match any sanitization CFURL may perform on the result of _CFBundleCopyBundleURLForExecutableURL() + CFURLRef absoluteURL, url1, url2, outURL = NULL; + CFStringRef str, str1, str2; + absoluteURL = CFURLCopyAbsoluteURL(url); + str = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE); + if (str) { + UniChar buff[CFMaxPathSize]; + CFIndex buffLen = CFStringGetLength(str), len1; + if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize; + CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff); + len1 = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); + if (len1 > 0 && len1 + 1 < buffLen) { + str1 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff, len1); + CFIndex skipSlashCount = 1; +#if DEPLOYMENT_TARGET_WINDOWS + // On Windows, _CFLengthAfterDeletingLastPathComponent will return a value of 3 if the path is at the root (e.g. C:\). This includes the \, which is not the case for URLs with subdirectories + if (len1 == 3 && buff[1] == ':' && buff[2] == '\\') { + skipSlashCount = 0; + } +#endif + str2 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff + len1 + skipSlashCount, buffLen - len1 - skipSlashCount); + if (str1 && str2) { + url1 = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str1, PLATFORM_PATH_STYLE, true); + if (url1) { + url2 = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, str2, PLATFORM_PATH_STYLE, false, url1); + if (url2) { + outURL = CFURLCopyAbsoluteURL(url2); + CFRelease(url2); + } + CFRelease(url1); + } + } + if (str1) CFRelease(str1); + if (str2) CFRelease(str2); + } + CFRelease(str); + } + if (!outURL) { + outURL = absoluteURL; + } else { + CFRelease(absoluteURL); + } + return outURL; } -#pragma mark - +CFURLRef _CFBundleCopyBundleURLForExecutableURL(CFURLRef url) { + CFURLRef resolvedURL, outurl = NULL; + CFStringRef str; + resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url); + str = CFURLCopyFileSystemPath(resolvedURL, PLATFORM_PATH_STYLE); + if (str) { + outurl = _CFBundleCopyBundleURLForExecutablePath(str); + CFRelease(str); + } + CFRelease(resolvedURL); + return outurl; +} -CF_PRIVATE uint8_t _CFBundleEffectiveLayoutVersion(CFBundleRef bundle) { +static uint8_t _CFBundleEffectiveLayoutVersion(CFBundleRef bundle) { uint8_t localVersion = bundle->_version; // exclude type 0 bundles with no binary (or CFM binary) and no Info.plist, since they give too many false positives if (0 == localVersion) { @@ -381,11 +510,122 @@ Boolean _CFBundleMainBundleInfoDictionaryComesFromResourceFork(void) { return (mainBundle && mainBundle->_resourceData._infoDictionaryFromResourceFork); } -CF_EXPORT CFBundleRef _CFBundleCreateIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) { +CFBundleRef _CFBundleCreateWithExecutableURLIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url) { + CFBundleRef bundle = NULL; + CFURLRef bundleURL = _CFBundleCopyBundleURLForExecutableURL(url), resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url); + if (bundleURL && resolvedURL) { + // We used to call _CFBundleCreateIfLooksLikeBundle here, but switched to the regular CFBundleCreate because we want this to return a result for certain flat bundles as well. + // It is assumed that users of this SPI do not want this bundle to persist forever, so we use the Unique version of CFBundleCreate. + bundle = _CFBundleCreateUnique(allocator, bundleURL); + if (bundle) { + CFURLRef executableURL = _CFBundleCopyExecutableURLIgnoringCache(bundle); + char buff1[CFMaxPathSize], buff2[CFMaxPathSize]; + if (!executableURL || !CFURLGetFileSystemRepresentation(resolvedURL, true, (uint8_t *)buff1, CFMaxPathSize) || !CFURLGetFileSystemRepresentation(executableURL, true, (uint8_t *)buff2, CFMaxPathSize) || 0 != strcmp(buff1, buff2)) { + CFRelease(bundle); + bundle = NULL; + } + if (executableURL) CFRelease(executableURL); + } + } + if (bundleURL) CFRelease(bundleURL); + if (resolvedURL) CFRelease(resolvedURL); + return bundle; +} + +CFBundleRef _CFBundleCreateIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) { // This function is obsolete CFBundleRef bundle = CFBundleCreate(allocator, url); return bundle; } + +CFBundleRef _CFBundleCreateWithExecutableURLIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) { + CFBundleRef result = _CFBundleCreateWithExecutableURLIfLooksLikeBundle(allocator, url); + + // This function applies additional requirements on a bundle to return a result + // The above makes sure that: + // 0. CFBundleCreate must succeed using a URL derived from the executable URL + // 1. The bundle must have an executableURL, and it must match the passed in executable URL + + // This function additionally requires that + // 2. If flat, the bundle must have a non-empty Info.plist. (15663535) + if (result) { + uint8_t localVersion = _CFBundleEffectiveLayoutVersion(result); + if (3 == localVersion || 4 == localVersion) { + CFDictionaryRef infoPlist = CFBundleGetInfoDictionary(result); + if (!infoPlist || (infoPlist && CFDictionaryGetCount(infoPlist) == 0)) { + CFRelease(result); + result = NULL; + } + } + } + return result; +} + +CFURLRef _CFBundleCopyMainBundleExecutableURL(Boolean *looksLikeBundle) { + // This function is for internal use only; _mainBundle is deliberately accessed outside of the lock to get around a reentrancy issue + const char *processPath; + CFStringRef str = NULL; + CFURLRef executableURL = NULL; + processPath = _CFProcessPath(); + if (processPath) { + str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath); + if (str) { + executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false); + CFRelease(str); + } + } + if (looksLikeBundle) { + CFBundleRef mainBundle = _mainBundle; + if (mainBundle && (3 == mainBundle->_version || 4 == mainBundle->_version)) mainBundle = NULL; + *looksLikeBundle = (mainBundle ? true : false); + } + return executableURL; +} + +static void _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(CFStringRef executablePath) { + CFBundleGetInfoDictionary(_mainBundle); + if (!_mainBundle->_infoDict || CFDictionaryGetCount(_mainBundle->_infoDict) == 0) { + // if type 3 bundle and no Info.plist, treat as unbundled, since this gives too many false positives + if (_mainBundle->_version == 3) _mainBundle->_version = 4; + if (_mainBundle->_version == 0) { + // if type 0 bundle and no Info.plist and not main executable for bundle, treat as unbundled, since this gives too many false positives + CFStringRef executableName = _CFBundleCopyExecutableName(_mainBundle, NULL, NULL); + if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) _mainBundle->_version = 4; + if (executableName) CFRelease(executableName); + } +#if defined(BINARY_SUPPORT_DYLD) + if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) { + if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict); + _mainBundle->_infoDict = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable(); + } +#endif /* BINARY_SUPPORT_DYLD */ + } else { +#if defined(BINARY_SUPPORT_DYLD) + if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) { + // if dyld and not main executable for bundle, prefer info dictionary from executable + CFStringRef executableName = _CFBundleCopyExecutableName(_mainBundle, NULL, NULL); + if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) { + CFDictionaryRef infoDictFromExecutable = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable(); + if (infoDictFromExecutable && CFDictionaryGetCount(infoDictFromExecutable) > 0) { + if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict); + _mainBundle->_infoDict = infoDictFromExecutable; + } else if (infoDictFromExecutable) { + CFRelease(infoDictFromExecutable); + } + } + if (executableName) CFRelease(executableName); + } +#endif /* BINARY_SUPPORT_DYLD */ + } + if (!_mainBundle->_infoDict) _mainBundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + if (!_mainBundle->_executablePath && executablePath) _mainBundle->_executablePath = (CFStringRef)CFRetain(executablePath); + CFStringRef bundleID = (CFStringRef)CFDictionaryGetValue(_mainBundle->_infoDict, kCFBundleIdentifierKey); + if (bundleID) { + if (!CFStringGetCString(bundleID, __CFBundleMainID__, sizeof(__CFBundleMainID__) - 2, kCFStringEncodingUTF8)) { + __CFBundleMainID__[0] = '\0'; + } + } +} static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean alreadyLocked) { CFDictionaryRef oldInfoDict = bundle->_infoDict; @@ -416,7 +656,14 @@ static void _CFBundleFlushBundleCachesAlreadyLocked(CFBundleRef bundle, Boolean CFRelease(bundle->_stringTable); bundle->_stringTable = NULL; } - CFBundleGetInfoDictionary(bundle); + if (bundle == _mainBundle) { + CFStringRef executablePath = bundle->_executablePath; + if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock); + _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(executablePath); + if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock); + } else { + CFBundleGetInfoDictionary(bundle); + } if (oldInfoDict) { if (!bundle->_infoDict) bundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); val = CFDictionaryGetValue(oldInfoDict, _kCFBundlePrincipalClassKey); @@ -431,81 +678,111 @@ CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle) { _CFBundleFlushBundleCachesAlreadyLocked(bundle, false); } -CF_PRIVATE void _CFBundleFlushAllBundleCaches(void) { - pthread_mutex_lock(&CFBundleGlobalDataLock); - CFIndex count = CFArrayGetCount(_allBundles); - for (CFIndex idx = 0; idx < count; idx++) { - CFBundleRef bundle = (CFBundleRef)CFArrayGetValueAtIndex(_allBundles, idx); - _CFBundleFlushBundleCachesAlreadyLocked(bundle, true); +static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) { + if (!_initedMainBundle) { + const char *processPath; + CFStringRef str = NULL; + CFURLRef executableURL = NULL, bundleURL = NULL; + _initedMainBundle = true; + processPath = _CFProcessPath(); + if (processPath) { + str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath); + if (!executableURL) executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false); + } + if (executableURL) bundleURL = _CFBundleCopyBundleURLForExecutableURL(executableURL); + if (bundleURL) { + // make sure that main bundle has executable path + //??? what if we are not the main executable in the bundle? + // NB doFinalProcessing must be false here, see below + _mainBundle = _CFBundleCreate(kCFAllocatorSystemDefault, bundleURL, true, false, false); + if (_mainBundle) { + // make sure that the main bundle is listed as loaded, and mark it as executable + _mainBundle->_isLoaded = true; +#if defined(BINARY_SUPPORT_DYLD) + if (_mainBundle->_binaryType == __CFBundleUnknownBinary) { + if (!executableURL) { + _mainBundle->_binaryType = __CFBundleNoBinary; + } else { + _mainBundle->_binaryType = _CFBundleGrokBinaryType(executableURL); + if (_mainBundle->_binaryType != __CFBundleCFMBinary && _mainBundle->_binaryType != __CFBundleUnreadableBinary) _mainBundle->_resourceData._executableLacksResourceFork = true; + } + } +#endif /* BINARY_SUPPORT_DYLD */ + // get cookie for already-loaded main bundle +#if defined(BINARY_SUPPORT_DLFCN) + if (!_mainBundle->_handleCookie) { + _mainBundle->_handleCookie = dlopen(NULL, RTLD_NOLOAD | RTLD_FIRST); +#if LOG_BUNDLE_LOAD + printf("main bundle %p getting handle %p\n", _mainBundle, _mainBundle->_handleCookie); +#endif /* LOG_BUNDLE_LOAD */ + } +#elif defined(BINARY_SUPPORT_DYLD) + if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary && !_mainBundle->_imageCookie) { + _mainBundle->_imageCookie = (void *)_dyld_get_image_header(0); +#if LOG_BUNDLE_LOAD + printf("main bundle %p getting image %p\n", _mainBundle, _mainBundle->_imageCookie); +#endif /* LOG_BUNDLE_LOAD */ + } +#endif /* BINARY_SUPPORT_DLFCN */ + _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(str); + // Perform delayed final processing steps. + // This must be done after _isLoaded has been set, for security reasons (3624341). + if (_CFBundleNeedsInitPlugIn(_mainBundle)) { + pthread_mutex_unlock(&CFBundleGlobalDataLock); + _CFBundleInitPlugIn(_mainBundle); + pthread_mutex_lock(&CFBundleGlobalDataLock); + } + } + } + if (bundleURL) CFRelease(bundleURL); + if (str) CFRelease(str); + if (executableURL) CFRelease(executableURL); } + return _mainBundle; +} + +CFBundleRef CFBundleGetMainBundle(void) { + CFBundleRef mainBundle; + pthread_mutex_lock(&CFBundleGlobalDataLock); + mainBundle = _CFBundleGetMainBundleAlreadyLocked(); pthread_mutex_unlock(&CFBundleGlobalDataLock); + return mainBundle; } CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { CFBundleRef result = NULL; if (bundleID) { - CFBundleRef main = CFBundleGetMainBundle(); - if (main) { - CFDictionaryRef infoDict = CFBundleGetInfoDictionary(main); - if (infoDict) { - CFStringRef mainBundleID = CFDictionaryGetValue(infoDict, kCFBundleIdentifierKey); - if (mainBundleID && CFGetTypeID(mainBundleID) == CFStringGetTypeID() && CFEqual(mainBundleID, bundleID)) { - return main; - } - } - } - - result = _CFBundleGetFromTables(bundleID); + pthread_mutex_lock(&CFBundleGlobalDataLock); + (void)_CFBundleGetMainBundleAlreadyLocked(); + result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); #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); if (p) { CFStringRef imagePath = _CFBundleCopyLoadedImagePathForPointer(p); - // If the pointer is in Foundation, we were called by NSBundle and we should look one more frame up the stack for a hint - if (imagePath && CFStringHasSuffix(imagePath, CFSTR("/Foundation"))) { - CFRelease(imagePath); - // Reset to NULL in case p is null below, that will make us fall back through the right path - imagePath = NULL; - p = __builtin_return_address(1); - if (p) { - imagePath = _CFBundleCopyLoadedImagePathForPointer(p); - } - } - if (imagePath) { - // As this is a fast-path check, we don't want to be aggressive about assuming that the executable URL that we may have received from DYLD via _CFBundleCopyLoadedImagePathForPointer should be turned into a framework URL. If we do, then it is possible that an executable located inside a framework bundle which does not normally link that framework will cause us to load it unintentionally (31165928). - // For example: - // Foo.framework/ - // Resources/ - // HelperTool - // - // With permissive set to 'true', this would make the 'Foo.framework' bundle exist, but there is no reason why HelperTool is required to have loaded Foo.framework. - - _CFBundleEnsureBundleExistsForImagePath(imagePath, false); + _CFBundleEnsureBundleExistsForImagePath(imagePath); CFRelease(imagePath); } - - // Now try again - result = _CFBundleGetFromTables(bundleID); + result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); } } #endif if (!result) { // Try to guess the bundle from the identifier and try again - _CFBundleEnsureBundlesUpToDateWithHint(bundleID); - - // Now try again - result = _CFBundleGetFromTables(bundleID); + _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(bundleID); + result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); } + pthread_mutex_unlock(&CFBundleGlobalDataLock); } if (!result) { + pthread_mutex_lock(&CFBundleGlobalDataLock); // Make sure all bundles have been created and try again. - _CFBundleEnsureAllBundlesUpToDate(); - - // Now try again - result = _CFBundleGetFromTables(bundleID); + _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(); + result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); + pthread_mutex_unlock(&CFBundleGlobalDataLock); } return result; @@ -547,6 +824,11 @@ static CFStringRef __CFBundleCopyDescription(CFTypeRef cf) { return retval; } +static void _CFBundleDeallocateGlue(const void *key, const void *value, void *context) { + CFAllocatorRef allocator = (CFAllocatorRef)context; + if (value) CFAllocatorDeallocate(allocator, (void *)value); +} + static void __CFBundleDeallocate(CFTypeRef cf) { CFBundleRef bundle = (CFBundleRef)cf; CFURLRef bundleURL; @@ -563,12 +845,17 @@ static void __CFBundleDeallocate(CFTypeRef cf) { CFRelease(bundleURL); } if (bundle->_infoDict) CFRelease(bundle->_infoDict); + if (bundle->_modDate) CFRelease(bundle->_modDate); if (bundle->_localInfoDict) CFRelease(bundle->_localInfoDict); if (bundle->_searchLanguages) CFRelease(bundle->_searchLanguages); if (bundle->_executablePath) CFRelease(bundle->_executablePath); if (bundle->_developmentRegion) CFRelease(bundle->_developmentRegion); if (bundle->_infoPlistUrl) CFRelease(bundle->_infoPlistUrl); + if (bundle->_glueDict) { + CFDictionaryApplyFunction(bundle->_glueDict, _CFBundleDeallocateGlue, (void *)CFGetAllocator(bundle)); + CFRelease(bundle->_glueDict); + } if (bundle->_stringTable) CFRelease(bundle->_stringTable); if (bundle->_bundleBasePath) CFRelease(bundle->_bundleBasePath); @@ -612,22 +899,16 @@ CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL) { newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)buff, strlen(buff), true); if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL); - - // First check the main bundle; otherwise fallback to the other tables - CFBundleRef main = CFBundleGetMainBundle(); - if (main->_url && newURL && CFEqual(main->_url, newURL)) { - return main; - } - - bundle = _CFBundleCopyFromTablesForURL(newURL); + bundle = _CFBundleCopyBundleForURL(newURL, false); if (bundle) CFRelease(bundle); CFRelease(newURL); return bundle; } -static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean doFinalProcessing, Boolean unique, Boolean addToTables) { +static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, Boolean alreadyLocked, Boolean doFinalProcessing, Boolean unique) { CFBundleRef bundle = NULL; char buff[CFMaxPathSize]; + CFDateRef modDate = NULL; // do not actually fetch the modDate, since that can cause something like 7609956, unless absolutely found to be necessary in the future Boolean exists = false; SInt32 mode = 0; CFURLRef newURL = NULL; @@ -638,9 +919,8 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, newURL = CFURLCreateFromFileSystemRepresentation(allocator, (uint8_t *)buff, strlen(buff), true); if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL); - // Don't go searching for the URL in the tables if the bundle is unique or the main bundle (addToTables == false) - if (!unique && addToTables) { - bundle = _CFBundleCopyFromTablesForURL(newURL); + if (!unique) { + bundle = _CFBundleCopyBundleForURL(newURL, alreadyLocked); if (bundle) { CFRelease(newURL); return bundle; @@ -653,6 +933,10 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, #if DEPLOYMENT_TARGET_WINDOWS if (!(res == 0 && exists && ((mode & S_IFMT) == S_IFDIR))) { // 2nd chance at finding a bundle path - remove the last path component (e.g., mybundle.resources) and try again + if (modDate) { + CFRelease(modDate); + modDate = NULL; + } CFURLRef shorterPath = CFURLCreateCopyDeletingLastPathComponent(allocator, newURL); CFRelease(newURL); newURL = shorterPath; @@ -661,6 +945,7 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, #endif if (res == 0) { if (!exists || ((mode & S_IFMT) != S_IFDIR)) { + if (modDate) CFRelease(modDate); CFRelease(newURL); return NULL; } @@ -678,6 +963,7 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, bundle->_url = newURL; + bundle->_modDate = modDate; bundle->_version = localVersion; bundle->_infoDict = NULL; bundle->_localInfoDict = NULL; @@ -713,6 +999,8 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, bundle->_imageCookie = NULL; bundle->_moduleCookie = NULL; + bundle->_glueDict = NULL; + bundle->_resourceData._executableLacksResourceFork = false; bundle->_resourceData._infoDictionaryFromResourceFork = false; @@ -722,7 +1010,6 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, bundle->_plugInData._loadOnDemand = false; bundle->_plugInData._isDoingDynamicRegistration = false; bundle->_plugInData._instanceCount = 0; - bundle->_plugInData._registeredFactory = false; bundle->_plugInData._factories = NULL; pthread_mutexattr_t mattr; @@ -754,40 +1041,26 @@ static CFBundleRef _CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL, // Do this so that we can use the dispatch_once on the ivar of this bundle safely OSMemoryBarrier(); - if (addToTables) { - _CFBundleAddToTables(bundle); - } + _CFBundleAddToTables(bundle, alreadyLocked); if (doFinalProcessing) { - _CFBundleInitPlugIn(bundle); + if (_CFBundleNeedsInitPlugIn(bundle)) { + if (alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock); + _CFBundleInitPlugIn(bundle); + if (alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock); + } } return bundle; } CFBundleRef CFBundleCreate(CFAllocatorRef allocator, CFURLRef bundleURL) { - if (NULL == bundleURL) return NULL; - - // _CFBundleCreate doesn't know about the main bundle, so we have to check that first. If the URL passed in is the same as the main bundle, then we'll need to return that bundle first. - // Result will be nil if the bundleURL passed in happened to have been the main bundle. - // As a fallback, check now to see if the main bundle URL is equal to bundleURL. If so, return that bundle instead of nil (32988858). - CFBundleRef main = CFBundleGetMainBundle(); - if (main && main->_url && CFEqual(main->_url, bundleURL)) { - CFRetain(main); - return main; - } - - return _CFBundleCreate(allocator, bundleURL, true, false, true); + return _CFBundleCreate(allocator, bundleURL, false, true, false); } CFBundleRef _CFBundleCreateUnique(CFAllocatorRef allocator, CFURLRef bundleURL) { // This function can never return an existing CFBundleRef object. - return _CFBundleCreate(allocator, bundleURL, true, true, false); -} - -CF_PRIVATE CFBundleRef _CFBundleCreateMain(CFAllocatorRef allocator, CFURLRef mainBundleURL) { - // Do not add the main bundle to tables - return _CFBundleCreate(allocator, mainBundleURL, false, false, false); + return _CFBundleCreate(allocator, bundleURL, false, true, true); } CFArrayRef CFBundleCreateBundlesFromDirectory(CFAllocatorRef alloc, CFURLRef directoryURL, CFStringRef bundleType) { @@ -814,6 +1087,199 @@ CFURLRef CFBundleCopyBundleURL(CFBundleRef bundle) { return bundle->_url; } +#define DEVELOPMENT_STAGE 0x20 +#define ALPHA_STAGE 0x40 +#define BETA_STAGE 0x60 +#define RELEASE_STAGE 0x80 + +#define MAX_VERS_LEN 10 + +CF_INLINE Boolean _isDigit(UniChar aChar) {return ((aChar >= (UniChar)'0' && aChar <= (UniChar)'9') ? true : false);} + +CF_PRIVATE CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef alloc, UInt32 vers) { + CFStringRef result = NULL; + uint8_t major1, major2, minor1, minor2, stage, build; + + major1 = (vers & 0xF0000000) >> 28; + major2 = (vers & 0x0F000000) >> 24; + minor1 = (vers & 0x00F00000) >> 20; + minor2 = (vers & 0x000F0000) >> 16; + stage = (vers & 0x0000FF00) >> 8; + build = (vers & 0x000000FF); + + if (stage == RELEASE_STAGE) { + if (major1 > 0) { + result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d"), major1, major2, minor1, minor2); + } else { + result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d"), major2, minor1, minor2); + } + } else { + if (major1 > 0) { + result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d%d.%d.%d%c%d"), major1, major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build); + } else { + result = CFStringCreateWithFormat(alloc, NULL, CFSTR("%d.%d.%d%c%d"), major2, minor1, minor2, ((stage == DEVELOPMENT_STAGE) ? 'd' : ((stage == ALPHA_STAGE) ? 'a' : 'b')), build); + } + } + return result; +} + +CF_PRIVATE UInt32 _CFVersionNumberFromString(CFStringRef versStr) { + // Parse version number from string. + // String can begin with "." for major version number 0. String can end at any point, but elements within the string cannot be skipped. + UInt32 major1 = 0, major2 = 0, minor1 = 0, minor2 = 0, stage = RELEASE_STAGE, build = 0; + UniChar versChars[MAX_VERS_LEN]; + UniChar *chars = NULL; + CFIndex len; + UInt32 theVers; + Boolean digitsDone = false; + + if (!versStr) return 0; + len = CFStringGetLength(versStr); + if (len <= 0 || len > MAX_VERS_LEN) return 0; + + CFStringGetCharacters(versStr, CFRangeMake(0, len), versChars); + chars = versChars; + + // Get major version number. + major1 = major2 = 0; + if (_isDigit(*chars)) { + major2 = *chars - (UniChar)'0'; + chars++; + len--; + if (len > 0) { + if (_isDigit(*chars)) { + major1 = major2; + major2 = *chars - (UniChar)'0'; + chars++; + len--; + if (len > 0) { + if (*chars == (UniChar)'.') { + chars++; + len--; + } else { + digitsDone = true; + } + } + } else if (*chars == (UniChar)'.') { + chars++; + len--; + } else { + digitsDone = true; + } + } + } else if (*chars == (UniChar)'.') { + chars++; + len--; + } else { + digitsDone = true; + } + + // Now major1 and major2 contain first and second digit of the major version number as ints. + // Now either len is 0 or chars points at the first char beyond the first decimal point. + + // Get the first minor version number. + if (len > 0 && !digitsDone) { + if (_isDigit(*chars)) { + minor1 = *chars - (UniChar)'0'; + chars++; + len--; + if (len > 0) { + if (*chars == (UniChar)'.') { + chars++; + len--; + } else { + digitsDone = true; + } + } + } else { + digitsDone = true; + } + } + + // Now minor1 contains the first minor version number as an int. + // Now either len is 0 or chars points at the first char beyond the second decimal point. + + // Get the second minor version number. + if (len > 0 && !digitsDone) { + if (_isDigit(*chars)) { + minor2 = *chars - (UniChar)'0'; + chars++; + len--; + } else { + digitsDone = true; + } + } + + // Now minor2 contains the second minor version number as an int. + // Now either len is 0 or chars points at the build stage letter. + + // Get the build stage letter. We must find 'd', 'a', 'b', or 'f' next, if there is anything next. + if (len > 0) { + if (*chars == (UniChar)'d') { + stage = DEVELOPMENT_STAGE; + } else if (*chars == (UniChar)'a') { + stage = ALPHA_STAGE; + } else if (*chars == (UniChar)'b') { + stage = BETA_STAGE; + } else if (*chars == (UniChar)'f') { + stage = RELEASE_STAGE; + } else { + return 0; + } + chars++; + len--; + } + + // Now stage contains the release stage. + // Now either len is 0 or chars points at the build number. + + // Get the first digit of the build number. + if (len > 0) { + if (_isDigit(*chars)) { + build = *chars - (UniChar)'0'; + chars++; + len--; + } else { + return 0; + } + } + // Get the second digit of the build number. + if (len > 0) { + if (_isDigit(*chars)) { + build *= 10; + build += *chars - (UniChar)'0'; + chars++; + len--; + } else { + return 0; + } + } + // Get the third digit of the build number. + if (len > 0) { + if (_isDigit(*chars)) { + build *= 10; + build += *chars - (UniChar)'0'; + chars++; + len--; + } else { + return 0; + } + } + + // Range check the build number and make sure we exhausted the string. + if (build > 0xFF || len > 0) return 0; + + // Build the number + theVers = major1 << 28; + theVers += major2 << 24; + theVers += minor1 << 20; + theVers += minor2 << 16; + theVers += stage << 8; + theVers += build; + + return theVers; +} + UInt32 CFBundleGetVersionNumber(CFBundleRef bundle) { CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle); CFNumberRef versionValue = (CFNumberRef)CFDictionaryGetValue(infoDict, _kCFBundleNumericVersionKey); @@ -841,8 +1307,24 @@ CFStringRef CFBundleGetDevelopmentRegion(CFBundleRef bundle) { } Boolean _CFBundleGetHasChanged(CFBundleRef bundle) { - // This SPI isn't very useful, so now we just return true (30211007) - return true; + CFDateRef modDate; + Boolean result = false; + Boolean exists = false; + SInt32 mode = 0; + + if (_CFGetFileProperties(CFGetAllocator(bundle), bundle->_url, &exists, &mode, NULL, &modDate, NULL, NULL) == 0) { + // If the bundle no longer exists or is not a folder, it must have "changed" + if (!exists || ((mode & S_IFMT) != S_IFDIR)) result = true; + } else { + // Something is wrong. The stat failed. + result = true; + } + if (bundle->_modDate && !CFEqual(bundle->_modDate, modDate)) { + // mod date is different from when we created. + result = true; + } + CFRelease(modDate); + return result; } void _CFBundleSetStringsFilesShared(CFBundleRef bundle, Boolean flag) { @@ -853,9 +1335,30 @@ Boolean _CFBundleGetStringsFilesShared(CFBundleRef bundle) { return bundle->_sharesStringsFiles; } -CF_EXPORT CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle) { - CFURLRef bundleURL = bundle->_url; - uint8_t version = bundle->_version; +static Boolean _urlExists(CFURLRef url) { + Boolean exists; + return url && (0 == _CFGetFileProperties(kCFAllocatorSystemDefault, url, &exists, NULL, NULL, NULL, NULL, NULL)) && exists; +} + +// This is here because on iPhoneOS with the dyld shared cache, we remove binaries from their +// original locations on disk, so checking whether a binary's path exists is no longer sufficient. +// For performance reasons, we only call dlopen_preflight() after we've verified that the binary +// does not exist at its original path with _urlExists(). +// See +static Boolean _binaryLoadable(CFURLRef url) { + Boolean loadable = _urlExists(url); +#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + if (!loadable) { + uint8_t path[PATH_MAX]; + if (url && CFURLGetFileSystemRepresentation(url, true, path, sizeof(path))) { + loadable = dlopen_preflight((char *)path); + } + } +#endif + return loadable; +} + +CF_PRIVATE CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) { CFURLRef result = NULL; if (bundleURL) { if (1 == version) { @@ -869,6 +1372,10 @@ CF_EXPORT CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle) { return result; } +CF_EXPORT CFURLRef CFBundleCopySupportFilesDirectoryURL(CFBundleRef bundle) { + return _CFBundleCopySupportFilesDirectoryURLInDirectory(bundle->_url, bundle->_version); +} + CF_PRIVATE CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, uint8_t version) { CFURLRef result = NULL; if (bundleURL) { @@ -907,6 +1414,83 @@ CFURLRef _CFBundleCopyAppStoreReceiptURL(CFBundleRef bundle) { return _CFBundleCopyAppStoreReceiptURLInDirectory(bundle->_url, bundle->_version); } +static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeName) { + // Given an url to a folder and a name, this returns the url to the executable in that folder with that name, if it exists, and NULL otherwise. This function deals with appending the ".exe" or ".dll" on Windows. + CFURLRef executableURL = NULL; + if (!urlPath || !exeName) return NULL; + +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + const uint8_t *image_suffix = (uint8_t *)__CFgetenvIfNotRestricted("DYLD_IMAGE_SUFFIX"); + + if (image_suffix) { + CFStringRef newExeName, imageSuffix; + imageSuffix = CFStringCreateWithCString(kCFAllocatorSystemDefault, (char *)image_suffix, kCFStringEncodingUTF8); + if (CFStringHasSuffix(exeName, CFSTR(".dylib"))) { + CFStringRef bareExeName = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, exeName, CFRangeMake(0, CFStringGetLength(exeName)-6)); + newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@.dylib"), exeName, imageSuffix); + CFRelease(bareExeName); + } else { + newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, imageSuffix); + } + executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, newExeName, kCFURLPOSIXPathStyle, false, urlPath); + if (executableURL && !_binaryLoadable(executableURL)) { + CFRelease(executableURL); + executableURL = NULL; + } + CFRelease(newExeName); + CFRelease(imageSuffix); + } + if (!executableURL) { + executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, exeName, kCFURLPOSIXPathStyle, false, urlPath); + if (executableURL && !_binaryLoadable(executableURL)) { + CFRelease(executableURL); + executableURL = NULL; + } + } +#elif DEPLOYMENT_TARGET_WINDOWS + if (!executableURL) { + executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, exeName, kCFURLWindowsPathStyle, false, urlPath); + if (executableURL && !_urlExists(executableURL)) { + CFRelease(executableURL); + executableURL = NULL; + } + } + if (!executableURL) { + if (!CFStringFindWithOptions(exeName, CFSTR(".dll"), CFRangeMake(0, CFStringGetLength(exeName)), kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL)) { +#if defined(DEBUG) + CFStringRef extension = CFSTR("_debug.dll"); +#else + CFStringRef extension = CFSTR(".dll"); +#endif + CFStringRef newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, extension); + executableURL = CFURLCreateWithString(kCFAllocatorSystemDefault, newExeName, urlPath); + if (executableURL && !_binaryLoadable(executableURL)) { + CFRelease(executableURL); + executableURL = NULL; + } + CFRelease(newExeName); + } + } + if (!executableURL) { + if (!CFStringFindWithOptions(exeName, CFSTR(".exe"), CFRangeMake(0, CFStringGetLength(exeName)), kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL)) { +#if defined(DEBUG) + CFStringRef extension = CFSTR("_debug.exe"); +#else + CFStringRef extension = CFSTR(".exe"); +#endif + CFStringRef newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, extension); + executableURL = CFURLCreateWithString(kCFAllocatorSystemDefault, newExeName, urlPath); + if (executableURL && !_binaryLoadable(executableURL)) { + CFRelease(executableURL); + executableURL = NULL; + } + CFRelease(newExeName); + } + } +#endif + return executableURL; +} + CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict) { CFStringRef executableName = NULL; @@ -945,6 +1529,152 @@ CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef return executableName; } +static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURLRef url, CFStringRef executableName, Boolean ignoreCache, Boolean useOtherPlatform) { + uint8_t version = 0; + CFDictionaryRef infoDict = NULL; + CFStringRef executablePath = NULL; + CFURLRef executableURL = NULL; + Boolean foundIt = false; + Boolean lookupMainExe = (executableName ? false : true); + + if (bundle) { + infoDict = CFBundleGetInfoDictionary(bundle); + version = bundle->_version; + } else { + infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, &version); + } + + // If we have a bundle instance and an info dict, see if we have already cached the path + if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && bundle->_executablePath) { + __CFLock(&bundle->_lock); + executablePath = bundle->_executablePath; + if (executablePath) CFRetain(executablePath); + __CFUnlock(&bundle->_lock); + if (executablePath) { +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLPOSIXPathStyle, false); +#elif DEPLOYMENT_TARGET_WINDOWS + executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLWindowsPathStyle, false); +#endif + if (executableURL) { + foundIt = true; + } + CFRelease(executablePath); + } + } + + if (!foundIt) { + if (lookupMainExe) executableName = _CFBundleCopyExecutableName(bundle, url, infoDict); + if (executableName) { +#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 = NULL; + CFURLRef exeSubdirURL; + + if (1 == version) { + exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase1, url); + } else if (2 == version) { + exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase2, url); + } else { +#if DEPLOYMENT_TARGET_WINDOWS + // On Windows, if the bundle URL is foo.resources, then the executable is at the same level as the .resources directory + CFStringRef extension = CFURLCopyPathExtension(url); + if (extension && CFEqual(extension, _CFBundleWindowsResourceDirectoryExtension)) { + exeDirURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorSystemDefault, url); + } else { + exeDirURL = (CFURLRef)CFRetain(url); + } +#else + exeDirURL = (CFURLRef)CFRetain(url); +#endif + } + CFStringRef platformSubDir = useOtherPlatform ? _CFBundleGetOtherPlatformExecutablesSubdirectoryName() : _CFBundleGetPlatformExecutablesSubdirectoryName(); + exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL); + executableURL = _CFBundleCopyExecutableURLRaw(exeSubdirURL, executableName); + if (!executableURL) { + CFRelease(exeSubdirURL); + platformSubDir = useOtherPlatform ? _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName() : _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(); + exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL); + executableURL = _CFBundleCopyExecutableURLRaw(exeSubdirURL, executableName); + } + if (!executableURL) { + CFRelease(exeSubdirURL); + platformSubDir = useOtherPlatform ? _CFBundleGetPlatformExecutablesSubdirectoryName() : _CFBundleGetOtherPlatformExecutablesSubdirectoryName(); + exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL); + executableURL = _CFBundleCopyExecutableURLRaw(exeSubdirURL, executableName); + } + if (!executableURL) { + CFRelease(exeSubdirURL); + platformSubDir = useOtherPlatform ? _CFBundleGetAlternatePlatformExecutablesSubdirectoryName() : _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(); + exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, platformSubDir, kCFURLPOSIXPathStyle, true, exeDirURL); + executableURL = _CFBundleCopyExecutableURLRaw(exeSubdirURL, executableName); + } + if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(exeDirURL, executableName); + CFRelease(exeDirURL); + CFRelease(exeSubdirURL); + } + + // If this was an old bundle, or we did not find the executable in the Executables subdirectory, look directly in the bundle wrapper. + if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(url, executableName); + +#if DEPLOYMENT_TARGET_WINDOWS + // Windows only: If we still haven't found the exe, look in the Executables folder. + // But only for the main bundle exe + if (lookupMainExe && !executableURL) { + CFURLRef exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, CFSTR("../../Executables"), url); + executableURL = _CFBundleCopyExecutableURLRaw(exeDirURL, executableName); + CFRelease(exeDirURL); + } +#endif + + if (lookupMainExe && !ignoreCache && !useOtherPlatform && bundle && executableURL) { + // We found it. Cache the path. + CFURLRef absURL = CFURLCopyAbsoluteURL(executableURL); +#if DEPLOYMENT_TARGET_WINDOWS + executablePath = CFURLCopyFileSystemPath(absURL, kCFURLWindowsPathStyle); +#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + executablePath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); +#endif + CFRelease(absURL); + __CFLock(&bundle->_lock); + bundle->_executablePath = (CFStringRef)CFRetain(executablePath); + __CFUnlock(&bundle->_lock); + CFRelease(executablePath); + } + if (lookupMainExe && !useOtherPlatform && bundle && !executableURL) bundle->_binaryType = __CFBundleNoBinary; + if (lookupMainExe) CFRelease(executableName); + } + } + if (!bundle && infoDict) CFRelease(infoDict); + return executableURL; +} + + +CFURLRef _CFBundleCopyExecutableURLInDirectory(CFURLRef url) { + return _CFBundleCopyExecutableURLInDirectory2(NULL, url, NULL, true, false); +} + +CFURLRef _CFBundleCopyOtherExecutableURLInDirectory(CFURLRef url) { + return _CFBundleCopyExecutableURLInDirectory2(NULL, url, NULL, true, true); +} + +CFURLRef CFBundleCopyExecutableURL(CFBundleRef bundle) { + return _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, NULL, false, false); +} + +static CFURLRef _CFBundleCopyExecutableURLIgnoringCache(CFBundleRef bundle) { + return _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, NULL, true, false); +} + +CFURLRef CFBundleCopyAuxiliaryExecutableURL(CFBundleRef bundle, CFStringRef executableName) { + return _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, executableName, true, false); +} + Boolean CFBundleIsExecutableLoaded(CFBundleRef bundle) { return bundle->_isLoaded; } @@ -1337,6 +2067,11 @@ void CFBundleUnloadExecutable(CFBundleRef bundle) { #endif /* BINARY_SUPPORT_DLFCN */ break; } + if (!bundle->_isLoaded && bundle->_glueDict) { + CFDictionaryApplyFunction(bundle->_glueDict, _CFBundleDeallocateGlue, (void *)CFGetAllocator(bundle)); + CFRelease(bundle->_glueDict); + bundle->_glueDict = NULL; + } } CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle) { @@ -1357,7 +2092,7 @@ CF_PRIVATE void _CFBundleUnscheduleForUnloading(CFBundleRef bundle) { pthread_mutex_unlock(&CFBundleGlobalDataLock); } -static void _CFBundleUnloadScheduledBundles(void) { +CF_PRIVATE void _CFBundleUnloadScheduledBundles(void) { pthread_mutex_lock(&CFBundleGlobalDataLock); if (_bundlesToUnload) { CFIndex i, c = CFSetGetCount(_bundlesToUnload); @@ -1503,16 +2238,21 @@ CFURLRef _CFBundleCopyFrameworkURLForExecutablePath(CFStringRef executablePath) return __CFBundleCopyFrameworkURLForExecutablePath(executablePath, false); } -static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath, Boolean permissive) { +static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath) { // This finds the bundle for the given path. // If an image path corresponds to a bundle, we see if there is already a bundle instance. If there is and it is NOT in the _dynamicBundles array, it is added to the staticBundles. Do not add the main bundle to the list here. CFBundleRef bundle; - CFURLRef curURL = __CFBundleCopyFrameworkURLForExecutablePath(imagePath, permissive); + CFURLRef curURL = __CFBundleCopyFrameworkURLForExecutablePath(imagePath, true); + Boolean createdBundle = false; if (curURL) { - // Ensure bundle exists by creating it if necessary. This will check the tables as a first step. - // NB doFinalProcessing must be false here, see below - bundle = _CFBundleCreate(kCFAllocatorSystemDefault, curURL, false, false, true); + bundle = _CFBundleCopyBundleForURL(curURL, true); + if (!bundle) { + // Ensure bundle exists by creating it if necessary + // NB doFinalProcessing must be false here, see below + bundle = _CFBundleCreate(kCFAllocatorSystemDefault, curURL, true, false, false); + createdBundle = true; + } if (bundle) { pthread_mutex_lock(&(bundle->_bundleLoadingLock)); if (!bundle->_isLoaded) { @@ -1532,9 +2272,18 @@ static void _CFBundleEnsureBundleExistsForImagePath(CFStringRef imagePath, Boole bundle->_isLoaded = true; } pthread_mutex_unlock(&(bundle->_bundleLoadingLock)); - // Perform delayed final processing steps. - // This must be done after _isLoaded has been set, for security reasons (3624341). - _CFBundleInitPlugIn(bundle); + if (createdBundle) { + // Perform delayed final processing steps. + // This must be done after _isLoaded has been set, for security reasons (3624341). + if (_CFBundleNeedsInitPlugIn(bundle)) { + pthread_mutex_unlock(&CFBundleGlobalDataLock); + _CFBundleInitPlugIn(bundle); + pthread_mutex_lock(&CFBundleGlobalDataLock); + } + } else { + // Release the bundle if we did not create it here + CFRelease(bundle); + } } CFRelease(curURL); } @@ -1544,13 +2293,13 @@ static void _CFBundleEnsureBundlesExistForImagePaths(CFArrayRef imagePaths) { // This finds the bundles for the given paths. // If an image path corresponds to a bundle, we see if there is already a bundle instance. If there is and it is NOT in the _dynamicBundles array, it is added to the staticBundles. Do not add the main bundle to the list here (even if it appears in imagePaths). CFIndex i, imagePathCount = CFArrayGetCount(imagePaths); - for (i = 0; i < imagePathCount; i++) _CFBundleEnsureBundleExistsForImagePath((CFStringRef)CFArrayGetValueAtIndex(imagePaths, i), true); + for (i = 0; i < imagePathCount; i++) _CFBundleEnsureBundleExistsForImagePath((CFStringRef)CFArrayGetValueAtIndex(imagePaths, i)); } -static void _CFBundleEnsureBundlesUpToDateWithHint(CFStringRef hint) { +static void _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(CFStringRef hint) { CFArrayRef imagePaths = NULL; // Tickle the main bundle into existence - (void)CFBundleGetMainBundle(); + (void)_CFBundleGetMainBundleAlreadyLocked(); #if defined(BINARY_SUPPORT_DYLD) imagePaths = _CFBundleDYLDCopyLoadedImagePathsForHint(hint); #endif /* BINARY_SUPPORT_DYLD */ @@ -1560,11 +2309,11 @@ static void _CFBundleEnsureBundlesUpToDateWithHint(CFStringRef hint) { } } -static void _CFBundleEnsureAllBundlesUpToDate(void) { +static void _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(void) { // This method returns all the statically linked bundles. This includes the main bundle as well as any frameworks that the process was linked against at launch time. It does not include frameworks or opther bundles that were loaded dynamically. CFArrayRef imagePaths = NULL; // Tickle the main bundle into existence - (void)CFBundleGetMainBundle(); + (void)_CFBundleGetMainBundleAlreadyLocked(); #if defined(BINARY_SUPPORT_DLL) // Dont know how to find static bundles for DLLs @@ -1580,45 +2329,21 @@ static void _CFBundleEnsureAllBundlesUpToDate(void) { } CFArrayRef CFBundleGetAllBundles(void) { - // This API is fundamentally broken from a thread safety point of view. To mitigate the issues, we keep around the last list we handed out. If the list of allBundles changed, we leak the last one and return a new copy. If no bundle loading is done this list would be static. - // Fortunately this method is rarely used. - CFArrayRef result = NULL; + // To answer this properly, we have to have created the static bundles! + CFArrayRef bundles; pthread_mutex_lock(&CFBundleGlobalDataLock); - static CFArrayRef _lastBundleList = NULL; - if (!_lastBundleList) { - // This is the first time we've been asked for a list of all bundles - // Unlock the global lock. CopyAllBundles will use it. - pthread_mutex_unlock(&CFBundleGlobalDataLock); - result = _CFBundleCopyAllBundles(); - pthread_mutex_lock(&CFBundleGlobalDataLock); - if (_lastBundleList) { - // Another thread beat us here - CFRelease(result); - } else { - _lastBundleList = result; - } - } else if (!CFEqual(_lastBundleList, _allBundles)) { - // Check if the list of bundles has changed - pthread_mutex_unlock(&CFBundleGlobalDataLock); - result = _CFBundleCopyAllBundles(); - pthread_mutex_lock(&CFBundleGlobalDataLock); - // note: intentionally leak the last value in _lastBundleList, due to API contract of 'get' - _lastBundleList = result; - } - result = _lastBundleList; + _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(); + bundles = _allBundles; pthread_mutex_unlock(&CFBundleGlobalDataLock); - return result; + return bundles; } CF_EXPORT CFArrayRef _CFBundleCopyAllBundles(void) { // To answer this properly, we have to have created the static bundles! - _CFBundleEnsureAllBundlesUpToDate(); - CFBundleRef main = CFBundleGetMainBundle(); pthread_mutex_lock(&CFBundleGlobalDataLock); - // _allBundles does not include the main bundle, so insert it here. - CFMutableArrayRef bundles = CFArrayCreateMutableCopy(kCFAllocatorSystemDefault, CFArrayGetCount(_allBundles) + 1, _allBundles); + _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(); + CFArrayRef bundles = CFArrayCreateCopy(kCFAllocatorSystemDefault, _allBundles); pthread_mutex_unlock(&CFBundleGlobalDataLock); - CFArrayInsertValueAtIndex(bundles, 0, main); return bundles; } @@ -1692,7 +2417,7 @@ CF_EXPORT CFURLRef CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle) { } else { result = CFURLCreateWithString(alloc, _CFBundleBuiltInPlugInsURLFromBase0, bundle->_url); } - if (!result || !_CFURLExists(result)) { + if (!result || !_urlExists(result)) { if (1 == bundle->_version) { alternateResult = CFURLCreateWithString(alloc, _CFBundleAlternateBuiltInPlugInsURLFromBase1, bundle->_url); } else if (2 == bundle->_version) { @@ -1700,7 +2425,7 @@ CF_EXPORT CFURLRef CFBundleCopyBuiltInPlugInsURL(CFBundleRef bundle) { } else { alternateResult = CFURLCreateWithString(alloc, _CFBundleAlternateBuiltInPlugInsURLFromBase0, bundle->_url); } - if (alternateResult && _CFURLExists(alternateResult)) { + if (alternateResult && _urlExists(alternateResult)) { if (result) CFRelease(result); result = alternateResult; } else { diff --git a/CoreFoundation/PlugIn.subproj/CFBundle.h b/CoreFoundation/PlugIn.subproj/CFBundle.h index a7af6bab63..b1be87c716 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle.h @@ -1,5 +1,5 @@ /* CFBundle.h - Copyright (c) 1999-2017, Apple Inc. All rights reserved. + Copyright (c) 1999-2016, Apple Inc. All rights reserved. */ #if !defined(__COREFOUNDATION_CFBUNDLE__) @@ -214,17 +214,19 @@ CF_EXPORT CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url); /* For a directory URL, this is equivalent to CFBundleCopyInfoDictionaryInDirectory(). */ /* For a plain file URL representing an unbundled executable, this will attempt to read */ - /* an info dictionary from the (__TEXT, __info_plist) section, if it is a Mach-o file. */ + /* an info dictionary from the (__TEXT, __info_plist) section, if it is a Mach-o file, */ + /* or from a 'plst' resource. */ CF_EXPORT CFArrayRef CFBundleCopyLocalizationsForURL(CFURLRef url); /* For a directory URL, this is equivalent to calling CFBundleCopyBundleLocalizations() */ /* on the corresponding bundle. For a plain file URL representing an unbundled executable, */ /* this will attempt to determine its localizations using the CFBundleLocalizations and */ - /* CFBundleDevelopmentRegion keys in the dictionary returned by CFBundleCopyInfoDictionaryForURL. */ + /* CFBundleDevelopmentRegion keys in the dictionary returned by CFBundleCopyInfoDictionaryForURL,*/ + /* or from a 'vers' resource if those are not present. */ CF_EXPORT -CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) CF_AVAILABLE(10_5, 2_0); /* For a directory URL, this is equivalent to calling CFBundleCopyExecutableArchitectures() */ /* on the corresponding bundle. For a plain file URL representing an unbundled executable, */ /* this will return the architectures it provides, if it is a Mach-o file, or NULL otherwise. */ @@ -242,17 +244,17 @@ enum { kCFBundleExecutableArchitecturePPC = 0x00000012, kCFBundleExecutableArchitectureX86_64 = 0x01000007, kCFBundleExecutableArchitecturePPC64 = 0x01000012 -} API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_5, 2_0); CF_EXPORT -CFArrayRef CFBundleCopyExecutableArchitectures(CFBundleRef bundle) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFArrayRef CFBundleCopyExecutableArchitectures(CFBundleRef bundle) CF_AVAILABLE(10_5, 2_0); /* If the bundle's executable exists and is a Mach-o file, this function will return an array */ /* of CFNumbers whose values are integers representing the architectures the file provides. */ /* The values currently in use are those listed in the enum above, but others may be added */ /* in the future. If the executable is not a Mach-o file, this function returns NULL. */ CF_EXPORT -Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) CF_AVAILABLE(10_5, 2_0); /* This function will return true if the bundle is loaded, or if the bundle appears to be */ /* loadable upon inspection. This does not mean that the bundle is definitively loadable, */ /* since it may fail to load due to link errors or other problems not readily detectable. */ @@ -260,7 +262,7 @@ Boolean CFBundlePreflightExecutable(CFBundleRef bundle, CFErrorRef *error) API_A /* It is the responsibility of the caller to release the CFError. */ CF_EXPORT -Boolean CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, CFErrorRef *error) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +Boolean CFBundleLoadExecutableAndReturnError(CFBundleRef bundle, CFErrorRef *error) CF_AVAILABLE(10_5, 2_0); /* If the bundle is already loaded, this function will return true. Otherwise, it will attempt */ /* to load the bundle, and it will return true if that attempt succeeds. If the bundle fails */ /* to load, this function will return false, and it will return a CFError by reference. */ diff --git a/CoreFoundation/PlugIn.subproj/CFBundlePriv.h b/CoreFoundation/PlugIn.subproj/CFBundlePriv.h index 1cb1b12a0d..c0549463a5 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundlePriv.h +++ b/CoreFoundation/PlugIn.subproj/CFBundlePriv.h @@ -1,7 +1,7 @@ /* CFBundlePriv.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -137,13 +137,13 @@ CFStringRef _CFBundleGetCurrentPlatform(void); /* This function will return a bundle object that is not from the existing caches, and will never be part of the result of any method that checks the caches (e.g., get all bundles). The bundle object itself may keep a cache, but you can just use this function to create another instance if you want to get a fresh cache. Note that any NSBundle-level API has yet another cache, which is not considered here. */ CF_EXPORT -CFBundleRef _CFBundleCreateUnique(CFAllocatorRef allocator, CFURLRef bundleURL) API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CFBundleRef _CFBundleCreateUnique(CFAllocatorRef allocator, CFURLRef bundleURL) CF_AVAILABLE(10_11, 9_0); /* For Code Signing */ // This function is obsolete. Use CFBundleCreate instead. CF_EXPORT -CFBundleRef _CFBundleCreateIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) API_DEPRECATED("Use CFBundleCreate instead", macos(10.6,10.10), ios(2.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFBundleRef _CFBundleCreateIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) CF_DEPRECATED(10_6, 10_10, 2_0, 8_0); // This function is for code signing only. Do not use this function. CF_EXPORT @@ -153,7 +153,7 @@ CFBundleRef _CFBundleCreateWithExecutableURLIfMightBeBundle(CFAllocatorRef alloc /* Functions for examining the structure of a bundle */ CF_EXPORT -CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle) API_AVAILABLE(macos(10.0)) API_UNAVAILABLE(ios, watchos, tvos); +CFURLRef _CFBundleCopyResourceForkURL(CFBundleRef bundle) CF_AVAILABLE_MAC(10_0); CF_EXPORT CFURLRef _CFBundleCopyInfoPlistURL(CFBundleRef bundle); @@ -191,7 +191,7 @@ CFStringRef CFBundleCopyLocalizationForLocalizationInfo(SInt32 languageCode, SIn /* 0xFFFF for stringEncoding, if you do not wish to specify one of these. */ // Get a localized string for a specific localization (including processing as strings dict file). This skips the usual cache for localized strings. -CF_EXPORT CFStringRef CFBundleCopyLocalizedStringForLocalization(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName, CFStringRef localizationName) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT CFStringRef CFBundleCopyLocalizedStringForLocalization(CFBundleRef bundle, CFStringRef key, CFStringRef value, CFStringRef tableName, CFStringRef localizationName) CF_AVAILABLE(10_10, 8_0); CF_EXPORT void _CFBundleSetDefaultLocalization(CFStringRef localizationName); @@ -217,15 +217,14 @@ CFStringRef _CFBundleCopyFileTypeForFileURL(CFURLRef url); CF_EXPORT CFStringRef _CFBundleCopyFileTypeForFileData(CFDataRef data); -// This function will always return true. CF_EXPORT -Boolean _CFBundleGetHasChanged(CFBundleRef bundle) API_DEPRECATED("Function no longer supported", macos(10.0,10.13), ios(2.0,11.0), watchos(2.0,4.0), tvos(9.0,11.0)); +Boolean _CFBundleGetHasChanged(CFBundleRef bundle); CF_EXPORT -void _CFBundleFlushCaches(void) API_DEPRECATED("Function no longer supported", macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +void _CFBundleFlushCaches(void) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT -void _CFBundleFlushCachesForURL(CFURLRef url) API_DEPRECATED("Function no longer supported", macos(10.0,10.8), ios(2.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +void _CFBundleFlushCachesForURL(CFURLRef url) CF_DEPRECATED(10_0, 10_8, 2_0, 6_0); CF_EXPORT void _CFBundleFlushBundleCaches(CFBundleRef bundle); // The previous two functions flush cached resource paths; this one also flushes bundle-specific caches such as the info dictionary and strings files @@ -245,25 +244,9 @@ CFURLRef _CFBundleCopyFrameworkURLForExecutablePath(CFStringRef executablePath); #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) #include CF_EXPORT -void _CFBundleSetupXPCBootstrap(xpc_object_t bootstrap) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +void _CFBundleSetupXPCBootstrap(xpc_object_t bootstrap) CF_AVAILABLE(10_10, 8_0); #endif - -/* CFString & Localization Debug Utilities */ - -CF_EXPORT -CFStringRef _CFDoubledStringCreate(CFStringRef theString) API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - -CF_EXPORT -CFStringRef _CFAccentuatedStringCreate(CFStringRef theString) API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - -CF_EXPORT -CFStringRef _CFAffixedStringCreate(CFStringRef theString, CFStringRef prefix, CFStringRef suffix) API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - -CF_EXPORT -CFStringRef _CFRLORightToLeftStringCreate(CFStringRef theString) API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - - /* Functions deprecated as SPI */ CF_EXPORT diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c b/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c index 2cd602dac7..0329d8a8c0 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Binary.c @@ -1,7 +1,7 @@ /* CFBundle_Binary.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -678,6 +678,7 @@ static void *_CFBundleDlfcnGetSymbolByNameWithSearch(CFBundleRef bundle, CFStrin } #if !defined(BINARY_SUPPORT_DYLD) + #if TARGET_OS_CYGWIN static CFStringRef _CFBundleDlfcnCopyLoadedImagePathForPointer(void *p) { // Cygwin does not support dladdr() @@ -693,7 +694,8 @@ static CFStringRef _CFBundleDlfcnCopyLoadedImagePathForPointer(void *p) { #endif /* LOG_BUNDLE_LOAD */ return result; } -#endif /* TARGET_OS_CYGWIN */ +#endif + #endif /* !BINARY_SUPPORT_DYLD */ #endif /* BINARY_SUPPORT_DLFCN */ diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h b/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h index 5465f2f7a9..716ff52f29 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle_BinaryTypes.h @@ -1,7 +1,7 @@ /* CFBundle_BinaryTypes.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_DebugStrings.c b/CoreFoundation/PlugIn.subproj/CFBundle_DebugStrings.c deleted file mode 100644 index 064e2a51bf..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFBundle_DebugStrings.c +++ /dev/null @@ -1,125 +0,0 @@ -/* CFBundle_DebugStrings.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Sean Stewart - */ - -#include -#include "CFBundle_Internal.h" - -// Directionality formatting codepoints -#define UTF16_RIGHT_TO_LEFT_OVERRIDE 0x202e -#define UTF16_POP_DIRECTIONAL_FORMATTING 0x202c - -// Combining accent codepoints -#define UTF16_COMBINING_GRAVE_ACCENT 0x0300 -#define UTF16_COMBINING_CEDILLA 0x0327 -#define UTF16_COMBINING_TILDE 0x0303 -#define UTF16_COMBINING_RING_BELOW 0x0325 -#define UTF16_COMBINING_RING_ABOVE 0x030A -#define UTF16_COMBINING_DIAERESIS 0x0308 - -CF_EXPORT CFStringRef _CFDoubledStringCreate(CFStringRef theString) { - CFMutableStringRef _Nonnull doubledString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); - CFStringAppend(doubledString, theString); - // Prevent doubling any format string specifiers that may be present - CFStringFindAndReplace(doubledString, CFSTR("%"), CFSTR(""), CFRangeMake(0, CFStringGetLength(doubledString)), 0); - CFStringAppendFormat(doubledString, NULL, CFSTR(" %@"), theString); - return (CFStringRef)doubledString; -} - -static CFStringRef __CFAccentuatedStringCreateWithAcceptableAccentChars(CFStringRef inString, UniChar const *acceptableAccentChars, CFIndex acceptableCharLength) { - // Copy the incoming string - CFMutableStringRef _Nonnull workingString = CFStringCreateMutableCopy(kCFAllocatorDefault, CFStringGetLength(inString), inString); - - // Create UniChar (UTF-16) buffer from original string - CFIndex const workingStringLength = CFStringGetLength(workingString); - CFStringInlineBuffer originalStringInlineBuffer; - CFStringInitInlineBuffer(workingString, &originalStringInlineBuffer, CFRangeMake(0, workingStringLength)); - - // Create new double-length UniChar (UTF-16) buffer for the new string - // We will trim the size later, but worst case is that there will be no skipped whitespace characters - UniChar *_Nonnull const accentedStringBuffer = malloc((workingStringLength * 2 + 1) * sizeof(UniChar)); // +1 for null char - CFIndex accentedStringCursor = 0; - - // Create CFCharacterSets that contain characters we wish to skip over during the accentuation loop - static CFCharacterSetRef _Nullable charsToSkip = NULL; - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - CFMutableCharacterSetRef _Nonnull charsToSkipMutable = CFCharacterSetCreateMutable(kCFAllocatorDefault); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetControl)); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetWhitespaceAndNewline)); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetPunctuation)); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetSymbol)); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit)); - CFCharacterSetUnion(charsToSkipMutable, CFCharacterSetGetPredefined(kCFCharacterSetNonBase)); - charsToSkip = CFCharacterSetCreateCopy(kCFAllocatorDefault, charsToSkipMutable); - CFRelease(charsToSkipMutable); - }); - - // For each non-skipped character, add a combining accent after the codepoint - for (CFIndex i = 0; i < workingStringLength;) { // inner loop increments i - CFRange const composedCharRange = CFStringGetRangeOfComposedCharactersAtIndex(workingString, i); // range length will always be >=1 - UniChar c; - // Enqueue the characters within the composedCharRange - for (CFIndex j = 0; j < composedCharRange.length; j++) { - c = CFStringGetCharacterFromInlineBuffer(&originalStringInlineBuffer, i++); - // Defend against CFStringGetCharacterFromInlineBuffer edge case listed in documentation - if (c == 0) assert("UniChar at specified index could not be accessed as it is outside the original range specified when initializing the CFStringInlineBuffer"); - accentedStringBuffer[accentedStringCursor++] = c; - } - // Don't sprinkle accents onto composed char sequences and characters belonging to certain ranges - // The goal here is to _never_ ever accentuate composed char sequences (like emoji) - if ((composedCharRange.length == 1) && !CFCharacterSetIsCharacterMember(charsToSkip, c)) { - // Deterministically pair a combining accent - CFIndex const combiningAccentIndex = c % acceptableCharLength; - UniChar const accentChar = acceptableAccentChars[combiningAccentIndex]; - accentedStringBuffer[accentedStringCursor++] = accentChar; - } - } - // Terminate the UniChar buffer with a null char - accentedStringBuffer[accentedStringCursor] = (UniChar)0x0; - - // Create a mutable string ref from the new char buffer (dealloc using kCFAllocatorNull and free the char buffer later ourselves) - CFMutableStringRef _Nonnull const accentedStringFromCharBuffer = CFStringCreateMutableWithExternalCharactersNoCopy(NULL, accentedStringBuffer, accentedStringCursor, accentedStringCursor, kCFAllocatorNull); - - // Make a copy of the string so that CFString can optimize itself - // CFStrings bound to client-owned buffers do not benefit from CFString-internal optimizations - CFStringRef _Nonnull accentedString = CFStringCreateCopy(kCFAllocatorDefault, accentedStringFromCharBuffer); - - // Cleanup - CFRelease(workingString); - CFRelease(accentedStringFromCharBuffer); - free(accentedStringBuffer); - return (CFStringRef)accentedString; -} - -CF_EXPORT CFStringRef _CFAccentuatedStringCreate(CFStringRef theString) { - /* Default set of "acceptable" Unicode combining accent codepoints - * These are hand-selected from the superset of combining accents because this subset is commonly used on Latin characters - * Additionally they're visually obvious and all look unique (that's why we choose to use only the GRAVE and not GRAVE & ACUTE accents due to similarity) - */ - static UniChar const acceptableAccentChars[] = { - UTF16_COMBINING_GRAVE_ACCENT, - UTF16_COMBINING_CEDILLA, - UTF16_COMBINING_TILDE, - UTF16_COMBINING_RING_BELOW, - UTF16_COMBINING_RING_ABOVE, - UTF16_COMBINING_DIAERESIS - }; - static CFIndex const len = sizeof(acceptableAccentChars)/sizeof(UniChar); - return __CFAccentuatedStringCreateWithAcceptableAccentChars(theString, acceptableAccentChars, len); -} - -CF_EXPORT CFStringRef _CFAffixedStringCreate(CFStringRef theString, CFStringRef prefix, CFStringRef suffix) { - return CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%@%@%@"), prefix, theString, suffix); -} - -CF_EXPORT CFStringRef _CFRLORightToLeftStringCreate(CFStringRef theString) { - CFStringRef rtlString = CFStringCreateWithFormat(kCFAllocatorDefault, NULL, CFSTR("%C%@%C"), UTF16_RIGHT_TO_LEFT_OVERRIDE, theString, UTF16_POP_DIRECTIONAL_FORMATTING); - return rtlString; -} diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c b/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c deleted file mode 100644 index 12c510e130..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Executable.c +++ /dev/null @@ -1,416 +0,0 @@ -/* CFBundle_Executable.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker -*/ - -#include -#include "CFBundle_Internal.h" - -#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -#include -#endif - -// This is here because on iPhoneOS with the dyld shared cache, we remove binaries from their -// original locations on disk, so checking whether a binary's path exists is no longer sufficient. -// For performance reasons, we only call dlopen_preflight() after we've verified that the binary -// does not exist at its original path with _CFURLExists(). -// See -static Boolean _binaryLoadable(CFURLRef url) { - Boolean loadable = _CFURLExists(url); -#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - if (!loadable) { - uint8_t path[PATH_MAX]; - if (url && CFURLGetFileSystemRepresentation(url, true, path, sizeof(path))) { - loadable = dlopen_preflight((char *)path); - } - } -#endif - return loadable; -} - -static CFURLRef _CFBundleCopyExecutableURLRaw(CFURLRef urlPath, CFStringRef exeName) { - // Given an url to a folder and a name, this returns the url to the executable in that folder with that name, if it exists, and NULL otherwise. This function deals with appending the ".exe" or ".dll" on Windows. - CFURLRef executableURL = NULL; - if (!urlPath || !exeName) return NULL; - -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - const uint8_t *image_suffix = (uint8_t *)__CFgetenvIfNotRestricted("DYLD_IMAGE_SUFFIX"); - - if (image_suffix) { - CFStringRef newExeName, imageSuffix; - imageSuffix = CFStringCreateWithCString(kCFAllocatorSystemDefault, (char *)image_suffix, kCFStringEncodingUTF8); - if (CFStringHasSuffix(exeName, CFSTR(".dylib"))) { - CFStringRef bareExeName = CFStringCreateWithSubstring(kCFAllocatorSystemDefault, exeName, CFRangeMake(0, CFStringGetLength(exeName)-6)); - newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@.dylib"), exeName, imageSuffix); - CFRelease(bareExeName); - } else { - newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, imageSuffix); - } - executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, newExeName, kCFURLPOSIXPathStyle, false, urlPath); - if (executableURL && !_binaryLoadable(executableURL)) { - CFRelease(executableURL); - executableURL = NULL; - } - CFRelease(newExeName); - CFRelease(imageSuffix); - } - if (!executableURL) { - executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, exeName, kCFURLPOSIXPathStyle, false, urlPath); - if (executableURL && !_binaryLoadable(executableURL)) { - CFRelease(executableURL); - executableURL = NULL; - } - } -#elif DEPLOYMENT_TARGET_WINDOWS - if (!executableURL) { - executableURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, exeName, kCFURLWindowsPathStyle, false, urlPath); - if (executableURL && !_urlExists(executableURL)) { - CFRelease(executableURL); - executableURL = NULL; - } - } - if (!executableURL) { - if (!CFStringFindWithOptions(exeName, CFSTR(".dll"), CFRangeMake(0, CFStringGetLength(exeName)), kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL)) { -#if defined(DEBUG) - CFStringRef extension = CFSTR("_debug.dll"); -#else - CFStringRef extension = CFSTR(".dll"); -#endif - CFStringRef newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, extension); - executableURL = CFURLCreateWithString(kCFAllocatorSystemDefault, newExeName, urlPath); - if (executableURL && !_binaryLoadable(executableURL)) { - CFRelease(executableURL); - executableURL = NULL; - } - CFRelease(newExeName); - } - } - if (!executableURL) { - if (!CFStringFindWithOptions(exeName, CFSTR(".exe"), CFRangeMake(0, CFStringGetLength(exeName)), kCFCompareAnchored|kCFCompareBackwards|kCFCompareCaseInsensitive, NULL)) { -#if defined(DEBUG) - CFStringRef extension = CFSTR("_debug.exe"); -#else - CFStringRef extension = CFSTR(".exe"); -#endif - CFStringRef newExeName = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%@%@"), exeName, extension); - executableURL = CFURLCreateWithString(kCFAllocatorSystemDefault, newExeName, urlPath); - if (executableURL && !_binaryLoadable(executableURL)) { - CFRelease(executableURL); - executableURL = NULL; - } - CFRelease(newExeName); - } - } -#endif - return executableURL; -} - -static CFURLRef _CFBundleCopyExecutableURLInDirectory2(CFBundleRef bundle, CFURLRef url, CFStringRef executableName, Boolean ignoreCache) { - uint8_t version = 0; - CFDictionaryRef infoDict = NULL; - CFStringRef executablePath = NULL; - CFURLRef executableURL = NULL; - Boolean foundIt = false; - Boolean lookupMainExe = (executableName ? false : true); - - if (bundle) { - infoDict = CFBundleGetInfoDictionary(bundle); - version = bundle->_version; - } else { - infoDict = _CFBundleCopyInfoDictionaryInDirectory(kCFAllocatorSystemDefault, url, &version); - } - - // If we have a bundle instance and an info dict, see if we have already cached the path - if (lookupMainExe && !ignoreCache && bundle && bundle->_executablePath) { - __CFLock(&bundle->_lock); - executablePath = bundle->_executablePath; - if (executablePath) CFRetain(executablePath); - __CFUnlock(&bundle->_lock); - if (executablePath) { -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLPOSIXPathStyle, false); -#elif DEPLOYMENT_TARGET_WINDOWS - executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, executablePath, kCFURLWindowsPathStyle, false); -#endif - if (executableURL) { - foundIt = true; - } - CFRelease(executablePath); - } - } - - if (!foundIt) { - if (lookupMainExe) executableName = _CFBundleCopyExecutableName(bundle, url, infoDict); - if (executableName) { -#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 = NULL; - - if (1 == version) { - exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase1, url); - } else if (2 == version) { - exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, _CFBundleExecutablesURLFromBase2, url); - } else { -#if DEPLOYMENT_TARGET_WINDOWS - // On Windows, if the bundle URL is foo.resources, then the executable is at the same level as the .resources directory - CFStringRef extension = CFURLCopyPathExtension(url); - if (extension && CFEqual(extension, _CFBundleWindowsResourceDirectoryExtension)) { - exeDirURL = CFURLCreateCopyDeletingLastPathComponent(kCFAllocatorSystemDefault, url); - } else { - exeDirURL = (CFURLRef)CFRetain(url); - } -#else - exeDirURL = (CFURLRef)CFRetain(url); -#endif - } - - // Historical note: This used to search the directories "Mac OS X", "MacOSClassic", then "MacOS8". As of 10.13 we only look in "MacOS". - CFURLRef exeSubdirURL = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, _CFBundleGetPlatformExecutablesSubdirectoryName(), kCFURLPOSIXPathStyle, true, exeDirURL); - executableURL = _CFBundleCopyExecutableURLRaw(exeSubdirURL, executableName); - CFRelease(exeSubdirURL); - - if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(exeDirURL, executableName); - CFRelease(exeDirURL); - } - - // If this was an old bundle, or we did not find the executable in the Executables subdirectory, look directly in the bundle wrapper. - if (!executableURL) executableURL = _CFBundleCopyExecutableURLRaw(url, executableName); - -#if DEPLOYMENT_TARGET_WINDOWS - // Windows only: If we still haven't found the exe, look in the Executables folder. - // But only for the main bundle exe - if (lookupMainExe && !executableURL) { - CFURLRef exeDirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, CFSTR("../../Executables"), url); - executableURL = _CFBundleCopyExecutableURLRaw(exeDirURL, executableName); - CFRelease(exeDirURL); - } -#endif - - if (lookupMainExe && !ignoreCache && bundle && executableURL) { - // We found it. Cache the path. - CFURLRef absURL = CFURLCopyAbsoluteURL(executableURL); -#if DEPLOYMENT_TARGET_WINDOWS - executablePath = CFURLCopyFileSystemPath(absURL, kCFURLWindowsPathStyle); -#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - executablePath = CFURLCopyFileSystemPath(absURL, kCFURLPOSIXPathStyle); -#endif - CFRelease(absURL); - __CFLock(&bundle->_lock); - bundle->_executablePath = (CFStringRef)CFRetain(executablePath); - __CFUnlock(&bundle->_lock); - CFRelease(executablePath); - } - if (lookupMainExe && bundle && !executableURL) bundle->_binaryType = __CFBundleNoBinary; - if (lookupMainExe) CFRelease(executableName); - } - } - if (!bundle && infoDict) CFRelease(infoDict); - return executableURL; -} - -static CFURLRef _CFBundleCopyBundleURLForExecutablePath(CFStringRef str) { - //!!! need to handle frameworks, NT; need to integrate with NSBundle - drd - UniChar buff[CFMaxPathSize]; - CFIndex buffLen; - CFURLRef url = NULL; - CFStringRef outstr; - - buffLen = CFStringGetLength(str); - if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize; - CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff); - -#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); - buffLen -= 4; - // If this is an _debug, we should strip that before looking for the bundle - if (buffLen >= 7 && (_wcsnicmp((wchar_t *)&buff[buffLen-6], L"_debug", 6) == 0)) buffLen -= 6; - - if (buffLen + 1 + extensionLength < CFMaxPathSize) { - buff[buffLen] = '.'; - buffLen ++; - CFStringGetCharacters(_CFBundleWindowsResourceDirectoryExtension, CFRangeMake(0, extensionLength), buff + buffLen); - buffLen += extensionLength; - outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull); - url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, outstr, PLATFORM_PATH_STYLE, true); - CFRelease(outstr); - } - } -#endif - - if (!url) { - buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); // Remove exe name - - 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); - if (startOfLastDir > 0 && startOfLastDir < buffLen) { - CFStringRef lastDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfLastDir]), buffLen - startOfLastDir); - - if (CFEqual(lastDirName, _CFBundleGetPlatformExecutablesSubdirectoryName())) { - // This is a new bundle. Back off a few more levels - if (buffLen > 0) { - // Remove platform folder - buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); - } - if (buffLen > 0) { - // Remove executables folder (if present) - CFIndex startOfNextDir = _CFStartOfLastPathComponent(buff, buffLen); - if (startOfNextDir > 0 && startOfNextDir < buffLen) { - CFStringRef nextDirName = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, &(buff[startOfNextDir]), buffLen - startOfNextDir); - if (CFEqual(nextDirName, _CFBundleExecutablesDirectoryName)) buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); - CFRelease(nextDirName); - } - } - if (buffLen > 0) { - // Remove support files folder - buffLen = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); - } - } - CFRelease(lastDirName); - } - } - - if (buffLen > 0) { - outstr = CFStringCreateWithCharactersNoCopy(kCFAllocatorSystemDefault, buff, buffLen, kCFAllocatorNull); - url = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, outstr, PLATFORM_PATH_STYLE, true); - CFRelease(outstr); - } - } - return url; -} - -static CFURLRef _CFBundleCopyResolvedURLForExecutableURL(CFURLRef url) { - // this is necessary so that we match any sanitization CFURL may perform on the result of _CFBundleCopyBundleURLForExecutableURL() - CFURLRef absoluteURL, url1, url2, outURL = NULL; - CFStringRef str, str1, str2; - absoluteURL = CFURLCopyAbsoluteURL(url); - str = CFURLCopyFileSystemPath(absoluteURL, PLATFORM_PATH_STYLE); - if (str) { - UniChar buff[CFMaxPathSize]; - CFIndex buffLen = CFStringGetLength(str), len1; - if (buffLen > CFMaxPathSize) buffLen = CFMaxPathSize; - CFStringGetCharacters(str, CFRangeMake(0, buffLen), buff); - len1 = _CFLengthAfterDeletingLastPathComponent(buff, buffLen); - if (len1 > 0 && len1 + 1 < buffLen) { - str1 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff, len1); - CFIndex skipSlashCount = 1; -#if DEPLOYMENT_TARGET_WINDOWS - // On Windows, _CFLengthAfterDeletingLastPathComponent will return a value of 3 if the path is at the root (e.g. C:\). This includes the \, which is not the case for URLs with subdirectories - if (len1 == 3 && buff[1] == ':' && buff[2] == '\\') { - skipSlashCount = 0; - } -#endif - str2 = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, buff + len1 + skipSlashCount, buffLen - len1 - skipSlashCount); - if (str1 && str2) { - url1 = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str1, PLATFORM_PATH_STYLE, true); - if (url1) { - url2 = CFURLCreateWithFileSystemPathRelativeToBase(kCFAllocatorSystemDefault, str2, PLATFORM_PATH_STYLE, false, url1); - if (url2) { - outURL = CFURLCopyAbsoluteURL(url2); - CFRelease(url2); - } - CFRelease(url1); - } - } - if (str1) CFRelease(str1); - if (str2) CFRelease(str2); - } - CFRelease(str); - } - if (!outURL) { - outURL = absoluteURL; - } else { - CFRelease(absoluteURL); - } - return outURL; -} - -// MARK: - Exported Functions - -CF_EXPORT CFURLRef _CFBundleCopyExecutableURLInDirectory(CFURLRef url) { - return _CFBundleCopyExecutableURLInDirectory2(NULL, url, NULL, true); -} - -CF_EXPORT CFURLRef _CFBundleCopyOtherExecutableURLInDirectory(CFURLRef url) { - // As of 10.13, there does not appear to be anyone actually invoking this function (either in the OS or other apps). The search list is also pretty far out of date. - // Therefore we will just return the same result as _CFBundleCopyExecutableURLInDirectory. - return _CFBundleCopyExecutableURLInDirectory(url); -} - -CF_EXPORT CFURLRef CFBundleCopyExecutableURL(CFBundleRef bundle) { - return _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, NULL, false); -} - -CF_EXPORT CFURLRef CFBundleCopyAuxiliaryExecutableURL(CFBundleRef bundle, CFStringRef executableName) { - return _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, executableName, true); -} - -CF_EXPORT CFURLRef _CFBundleCopyBundleURLForExecutableURL(CFURLRef url) { - CFURLRef resolvedURL, outurl = NULL; - CFStringRef str; - resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url); - str = CFURLCopyFileSystemPath(resolvedURL, PLATFORM_PATH_STYLE); - if (str) { - outurl = _CFBundleCopyBundleURLForExecutablePath(str); - CFRelease(str); - } - CFRelease(resolvedURL); - return outurl; -} - -CF_EXPORT CFBundleRef _CFBundleCreateWithExecutableURLIfLooksLikeBundle(CFAllocatorRef allocator, CFURLRef url) { - CFBundleRef bundle = NULL; - CFURLRef bundleURL = _CFBundleCopyBundleURLForExecutableURL(url), resolvedURL = _CFBundleCopyResolvedURLForExecutableURL(url); - if (bundleURL && resolvedURL) { - // We used to call _CFBundleCreateIfLooksLikeBundle here, but switched to the regular CFBundleCreate because we want this to return a result for certain flat bundles as well. - // It is assumed that users of this SPI do not want this bundle to persist forever, so we use the Unique version of CFBundleCreate. - bundle = _CFBundleCreateUnique(allocator, bundleURL); - if (bundle) { - CFURLRef executableURL = _CFBundleCopyExecutableURLInDirectory2(bundle, bundle->_url, NULL, true); - char buff1[CFMaxPathSize], buff2[CFMaxPathSize]; - if (!executableURL || !CFURLGetFileSystemRepresentation(resolvedURL, true, (uint8_t *)buff1, CFMaxPathSize) || !CFURLGetFileSystemRepresentation(executableURL, true, (uint8_t *)buff2, CFMaxPathSize) || 0 != strcmp(buff1, buff2)) { - CFRelease(bundle); - bundle = NULL; - } - if (executableURL) CFRelease(executableURL); - } - } - if (bundleURL) CFRelease(bundleURL); - if (resolvedURL) CFRelease(resolvedURL); - return bundle; -} - -CF_EXPORT CFBundleRef _CFBundleCreateWithExecutableURLIfMightBeBundle(CFAllocatorRef allocator, CFURLRef url) { - CFBundleRef result = _CFBundleCreateWithExecutableURLIfLooksLikeBundle(allocator, url); - - // This function applies additional requirements on a bundle to return a result - // The above makes sure that: - // 0. CFBundleCreate must succeed using a URL derived from the executable URL - // 1. The bundle must have an executableURL, and it must match the passed in executable URL - - // This function additionally requires that - // 2. If flat, the bundle must have a non-empty Info.plist. (15663535) - if (result) { - uint8_t localVersion = _CFBundleEffectiveLayoutVersion(result); - if (3 == localVersion || 4 == localVersion) { - CFDictionaryRef infoPlist = CFBundleGetInfoDictionary(result); - if (!infoPlist || (infoPlist && CFDictionaryGetCount(infoPlist) == 0)) { - CFRelease(result); - result = NULL; - } - } - } - return result; -} diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c b/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c index 77485b5996..4c4fec2bfe 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Grok.c @@ -1,7 +1,7 @@ /* CFBundle_Grok.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -935,24 +935,6 @@ CFStringRef _CFBundleCopyFileTypeForFileData(CFDataRef data) { return extension; } -CF_EXPORT CFDictionaryRef _CFBundleCopyInfoDictionaryForExecutableFileData(CFDataRef data, bool *canContainInfoPlist) { - CFDictionaryRef result = NULL; - UInt32 machtype = 0; - (void)_CFBundleGrokFileType(NULL, data, NULL, &machtype, NULL, &result, NULL, NULL, NULL); - if (canContainInfoPlist) { -#if TARGET_OS_MAC - if (machtype == MH_EXECUTE || machtype == MH_DYLIB) { - *canContainInfoPlist = true; - } else { - *canContainInfoPlist = false; - } -#else - *canContainInfoPlist = false; -#endif - } - return result; -} - CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url) { CFDictionaryRef result = NULL; (void)_CFBundleGrokFileType(url, NULL, NULL, NULL, NULL, &result, NULL, NULL, NULL); diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c b/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c index dd14abc4fe..e566377110 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_InfoPlist.c @@ -1,7 +1,7 @@ /* CFBundle_InfoPlist.c - Copyright (c) 2012-2017, Apple Inc. and the Swift project authors + Copyright (c) 2012-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -26,7 +26,6 @@ #endif #endif - // The following strings are initialized 'later' (i.e., not at static initialization time) because static init time is too early for CFSTR to work, on platforms without constant CF strings #if !__CONSTANT_STRINGS__ @@ -75,20 +74,10 @@ CF_PRIVATE void _CFBundleResourcesInitialize() { } #pragma mark Product and Platform Getters - Exported static CFStringRef _cfBundlePlatform = NULL; -#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -static CFStringRef _cfBundlePlatformSuffix = NULL; -CF_PRIVATE CFStringRef _CFBundleGetProductNameSuffix(void); -#endif CF_EXPORT void _CFSetProductName(CFStringRef str) { // TODO: This should be removed. The "CLASSIC" check below removes the need to set the product name manually. if (str) CFRetain(str); _cfBundlePlatform = str; - -#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - // Reset the suffix version too - _cfBundlePlatformSuffix = NULL; - (void)_CFBundleGetProductNameSuffix(); -#endif // Note that the previous value is leaked, which is fine normally // because the initial values would tend to be the constant strings // below. That is required for thread-safety value due to the Get @@ -140,43 +129,6 @@ CF_EXPORT CFStringRef _CFGetProductName(void) { return CFSTR(""); } -CF_PRIVATE CFStringRef _CFBundleGetProductNameSuffix(void) { -#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - // Not dispatch once, because this can be reset (by a rare API call). If a race happens, it just leaks one string. - if (!_cfBundlePlatformSuffix) { - CFStringRef productName = _CFGetProductName(); - if (CFEqual(productName, CFSTR("ipod"))) { - productName = CFSTR("iphone"); - } - _cfBundlePlatformSuffix = CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("~%@"), productName); - } - return _cfBundlePlatformSuffix; -#else - // Pedantically correct - _CFGetProductName returns an empty string on non-embedded platforms. - return CFSTR("~"); -#endif -} - -CF_PRIVATE CFStringRef _CFBundleGetPlatformNameSuffix(void) { -#if DEPLOYMENT_TARGET_MACOSX - return _CFBundleMacOSXPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI - return _CFBundleiPhoneOSPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_WINDOWS - return _CFBundleWindowsPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_SOLARIS - return _CFBundleSolarisPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_HPUX - return _CFBundleHPUXPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_LINUX - return _CFBundleLinuxPlatformNameSuffix; -#elif DEPLOYMENT_TARGET_FREEBSD - return _CFBundleFreeBSDPlatformNameSuffix; -#else -#error Unknown or unspecified DEPLOYMENT_TARGET -#endif -} - // All new-style bundles will have these extensions. CF_EXPORT CFStringRef _CFGetPlatformName(void) { #if DEPLOYMENT_TARGET_MACOSX @@ -193,7 +145,7 @@ CF_EXPORT CFStringRef _CFGetPlatformName(void) { #if TARGET_OS_CYGWIN return _CFBundleCygwinPlatformName; #else - return _CFBundleLinuxPlatformName; + return _CFBundleLinuxPlatformName; #endif #elif DEPLOYMENT_TARGET_FREEBSD return _CFBundleFreeBSDPlatformName; @@ -213,7 +165,7 @@ CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void) { #if TARGET_OS_CYGWIN return CFSTR("Cygwin"); #else - return CFSTR("Linux"); + return CFSTR("Linux"); #endif #elif DEPLOYMENT_TARGET_FREEBSD return CFSTR("FreeBSD"); @@ -464,178 +416,28 @@ CF_PRIVATE void _CFBundleInfoPlistProcessInfoDictionary(CFMutableDictionaryRef d } #pragma mark - +#pragma mark Info Plist Functions -#define DEVELOPMENT_STAGE 0x20 -#define ALPHA_STAGE 0x40 -#define BETA_STAGE 0x60 -#define RELEASE_STAGE 0x80 - -#define MAX_VERS_LEN 10 - -CF_INLINE Boolean _isDigit(UniChar aChar) {return ((aChar >= (UniChar)'0' && aChar <= (UniChar)'9') ? true : false);} - -static UInt32 _CFVersionNumberFromString(CFStringRef versStr) { - // Parse version number from string. - // String can begin with "." for major version number 0. String can end at any point, but elements within the string cannot be skipped. - UInt32 major1 = 0, major2 = 0, minor1 = 0, minor2 = 0, stage = RELEASE_STAGE, build = 0; - UniChar versChars[MAX_VERS_LEN]; - UniChar *chars = NULL; - CFIndex len; - UInt32 theVers; - Boolean digitsDone = false; - - if (!versStr) return 0; - len = CFStringGetLength(versStr); - if (len <= 0 || len > MAX_VERS_LEN) return 0; - - CFStringGetCharacters(versStr, CFRangeMake(0, len), versChars); - chars = versChars; - - // Get major version number. - major1 = major2 = 0; - if (_isDigit(*chars)) { - major2 = *chars - (UniChar)'0'; - chars++; - len--; - if (len > 0) { - if (_isDigit(*chars)) { - major1 = major2; - major2 = *chars - (UniChar)'0'; - chars++; - len--; - if (len > 0) { - if (*chars == (UniChar)'.') { - chars++; - len--; - } else { - digitsDone = true; - } - } - } else if (*chars == (UniChar)'.') { - chars++; - len--; - } else { - digitsDone = true; - } - } - } else if (*chars == (UniChar)'.') { - chars++; - len--; - } else { - digitsDone = true; - } - - // Now major1 and major2 contain first and second digit of the major version number as ints. - // Now either len is 0 or chars points at the first char beyond the first decimal point. - - // Get the first minor version number. - if (len > 0 && !digitsDone) { - if (_isDigit(*chars)) { - minor1 = *chars - (UniChar)'0'; - chars++; - len--; - if (len > 0) { - if (*chars == (UniChar)'.') { - chars++; - len--; - } else { - digitsDone = true; - } - } - } else { - digitsDone = true; - } - } - - // Now minor1 contains the first minor version number as an int. - // Now either len is 0 or chars points at the first char beyond the second decimal point. - - // Get the second minor version number. - if (len > 0 && !digitsDone) { - if (_isDigit(*chars)) { - minor2 = *chars - (UniChar)'0'; - chars++; - len--; - } else { - digitsDone = true; - } - } - - // Now minor2 contains the second minor version number as an int. - // Now either len is 0 or chars points at the build stage letter. - - // Get the build stage letter. We must find 'd', 'a', 'b', or 'f' next, if there is anything next. - if (len > 0) { - if (*chars == (UniChar)'d') { - stage = DEVELOPMENT_STAGE; - } else if (*chars == (UniChar)'a') { - stage = ALPHA_STAGE; - } else if (*chars == (UniChar)'b') { - stage = BETA_STAGE; - } else if (*chars == (UniChar)'f') { - stage = RELEASE_STAGE; - } else { - return 0; - } - chars++; - len--; - } - - // Now stage contains the release stage. - // Now either len is 0 or chars points at the build number. +CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) { + CFDictionaryRef dict = NULL; + unsigned char buff[CFMaxPathSize]; + uint8_t localVersion = 0; - // Get the first digit of the build number. - if (len > 0) { - if (_isDigit(*chars)) { - build = *chars - (UniChar)'0'; - chars++; - len--; - } else { - return 0; - } - } - // Get the second digit of the build number. - if (len > 0) { - if (_isDigit(*chars)) { - build *= 10; - build += *chars - (UniChar)'0'; - chars++; - len--; - } else { - return 0; - } - } - // Get the third digit of the build number. - if (len > 0) { - if (_isDigit(*chars)) { - build *= 10; - build += *chars - (UniChar)'0'; - chars++; - len--; - } else { - return 0; - } + if (CFURLGetFileSystemRepresentation(url, true, buff, CFMaxPathSize)) { + CFURLRef newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true); + if (!newURL) newURL = (CFURLRef)CFRetain(url); + + localVersion = _CFBundleGetBundleVersionForURL(newURL); + + dict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(alloc, newURL, NULL, localVersion); + CFRelease(newURL); } - - // Range check the build number and make sure we exhausted the string. - if (build > 0xFF || len > 0) return 0; - - // Build the number - theVers = major1 << 28; - theVers += major2 << 24; - theVers += minor1 << 20; - theVers += minor2 << 16; - theVers += stage << 8; - theVers += build; - - return theVers; + if (version) *version = localVersion; + return dict; } -#pragma mark - -#pragma mark Info Plist Functions - // If infoPlistUrl is passed as non-null it will return retained as the out parameter; callers are responsible for releasing. -static CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, CFURLRef * infoPlistUrl, uint8_t version) { +CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, CFURLRef * infoPlistUrl, uint8_t version) { // We only return NULL for a bad URL, otherwise we create a dummy dictionary if (!url) return NULL; @@ -777,24 +579,6 @@ static CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAlloc return result; } -CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, uint8_t *version) { - CFDictionaryRef dict = NULL; - unsigned char buff[CFMaxPathSize]; - uint8_t localVersion = 0; - - if (CFURLGetFileSystemRepresentation(url, true, buff, CFMaxPathSize)) { - CFURLRef newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, buff, strlen((char *)buff), true); - if (!newURL) newURL = (CFURLRef)CFRetain(url); - - localVersion = _CFBundleGetBundleVersionForURL(newURL); - - dict = _CFBundleCopyInfoDictionaryInDirectoryWithVersion(alloc, newURL, NULL, localVersion); - CFRelease(newURL); - } - if (version) *version = localVersion; - return dict; -} - CF_EXPORT CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url) { CFDictionaryRef result = NULL; Boolean isDir = false; @@ -805,6 +589,7 @@ CF_EXPORT CFDictionaryRef CFBundleCopyInfoDictionaryForURL(CFURLRef url) { result = _CFBundleCopyInfoDictionaryInExecutable(url); } } + if (result && (0)) CFRetain(result); // conditionally put on a retain for a Copy function return result; } diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h index db74fb4ceb..04918f60d5 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Internal.h @@ -1,7 +1,7 @@ /* CFBundle_Internal.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -52,7 +52,7 @@ typedef struct __CFPlugInData { Boolean _isPlugIn; Boolean _loadOnDemand; Boolean _isDoingDynamicRegistration; - Boolean _registeredFactory; + Boolean _unused1; UInt32 _instanceCount; CFMutableArrayRef _factories; } _CFPlugInData; @@ -61,6 +61,7 @@ struct __CFBundle { CFRuntimeBase _base; CFURLRef _url; + CFDateRef _modDate; CFDictionaryRef _infoDict; CFDictionaryRef _localInfoDict; @@ -82,6 +83,9 @@ struct __CFBundle { /* dlfcn goop */ void *_handleCookie; + /* CFM<->DYLD glue */ + CFMutableDictionaryRef _glueDict; + /* Resource fork goop */ _CFResourceData _resourceData; @@ -135,13 +139,12 @@ CF_EXPORT CFStringRef _CFGetPlatformName(void); CF_EXPORT CFStringRef _CFGetAlternatePlatformName(void); CF_PRIVATE void _CFBundleFlushQueryTableCache(CFBundleRef bundle); -CF_PRIVATE void _CFBundleFlushAllBundleCaches(void); CF_PRIVATE SInt32 _CFBundleCurrentArchitecture(void); CF_PRIVATE Boolean _CFBundleGetObjCImageInfo(CFBundleRef bundle, uint32_t *objcVersion, uint32_t *objcFlags); #if defined(BINARY_SUPPORT_DYLD) -CF_PRIVATE CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable(); +CF_PRIVATE CFMutableDictionaryRef _CFBundleCreateInfoDictFromMainExecutable(void); CF_PRIVATE Boolean _CFBundleGrokObjCImageInfoFromMainExecutable(uint32_t *objcVersion, uint32_t *objcFlags); #endif @@ -156,32 +159,39 @@ CF_PRIVATE Boolean CFBundleAllowMixedLocalizations(void); // Misc -CF_PRIVATE Boolean _CFIsResourceAtURL(CFURLRef url, Boolean *isDir); -CF_PRIVATE Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir); +extern Boolean _CFIsResourceAtURL(CFURLRef url, Boolean *isDir); +extern Boolean _CFIsResourceAtPath(CFStringRef path, Boolean *isDir); CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url); -CF_PRIVATE CFBundleRef _CFBundleCreateMain(CFAllocatorRef allocator, CFURLRef mainBundleURL); - -CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt8 *version); -CF_PRIVATE CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, UInt8 version); +extern CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectory(CFAllocatorRef alloc, CFURLRef url, UInt8 *version); +extern CFDictionaryRef _CFBundleCopyInfoDictionaryInDirectoryWithVersion(CFAllocatorRef alloc, CFURLRef url, CFURLRef *infoPlistUrl, UInt8 version); +extern CFURLRef _CFBundleCopySupportFilesDirectoryURLInDirectory(CFURLRef bundleURL, UInt8 version); +extern CFURLRef _CFBundleCopyResourcesDirectoryURLInDirectory(CFURLRef bundleURL, UInt8 version); -CF_PRIVATE Boolean _CFBundleCouldBeBundle(CFURLRef url); -CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInResourceForkWithAllocator(CFAllocatorRef alloc, CFURLRef url); +extern Boolean _CFBundleCouldBeBundle(CFURLRef url); +extern CFDictionaryRef _CFBundleCopyInfoDictionaryInResourceForkWithAllocator(CFAllocatorRef alloc, CFURLRef url); CF_PRIVATE CFStringRef _CFBundleCopyExecutableName(CFBundleRef bundle, CFURLRef url, CFDictionaryRef infoDict); #if DEPLOYMENT_TARGET_MACOSX CF_PRIVATE CFStringRef _CFBundleCopyBundleDevelopmentRegionFromVersResource(CFBundleRef bundle); #endif -CF_PRIVATE CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url); -CF_PRIVATE CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url); +extern CFDictionaryRef _CFBundleCopyInfoDictionaryInExecutable(CFURLRef url); +extern CFArrayRef _CFBundleCopyArchitecturesForExecutable(CFURLRef url); -CF_PRIVATE CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void); +extern CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void); +extern CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void); +extern CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void); +extern CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(void); -CF_PRIVATE void _CFBundleScheduleForUnloading(CFBundleRef bundle); -CF_PRIVATE void _CFBundleUnscheduleForUnloading(CFBundleRef bundle); +extern CFStringRef _CFCreateStringFromVersionNumber(CFAllocatorRef alloc, UInt32 vers); +extern UInt32 _CFVersionNumberFromString(CFStringRef versStr); -CF_PRIVATE UInt8 _CFBundleLayoutVersion(CFBundleRef bundle); -CF_PRIVATE uint8_t _CFBundleEffectiveLayoutVersion(CFBundleRef bundle); +extern void _CFBundleScheduleForUnloading(CFBundleRef bundle); +extern void _CFBundleUnscheduleForUnloading(CFBundleRef bundle); +extern void _CFBundleUnloadScheduledBundles(void); +CF_PRIVATE void _CFBundleAppendResourceDir(CFMutableStringRef path, uint8_t version); + +CF_PRIVATE UInt8 _CFBundleLayoutVersion(CFBundleRef bundle); #if defined(BINARY_SUPPORT_DYLD) // DYLD API @@ -216,6 +226,7 @@ extern void *_CFBundleDLLGetSymbolByName(CFBundleRef bundle, CFStringRef symbolN /* Private PlugIn-related CFBundle API */ +extern Boolean _CFBundleNeedsInitPlugIn(CFBundleRef bundle); extern void _CFBundleInitPlugIn(CFBundleRef bundle); extern void _CFBundlePlugInLoaded(CFBundleRef bundle); extern void _CFBundleDeallocatePlugIn(CFBundleRef bundle); @@ -322,22 +333,14 @@ extern void _CFPlugInRemoveFactory(CFPlugInRef plugIn, _CFPFactoryRef factory); #define _CFBundleMacOSXPlatformName CFSTR("macos") #define _CFBundleAlternateMacOSXPlatformName CFSTR("macosx") #define _CFBundleiPhoneOSPlatformName CFSTR("iphoneos") +#define _CFBundleMacOS8PlatformName CFSTR("macosclassic") +#define _CFBundleAlternateMacOS8PlatformName CFSTR("macos8") #define _CFBundleWindowsPlatformName CFSTR("windows") #define _CFBundleHPUXPlatformName CFSTR("hpux") #define _CFBundleSolarisPlatformName CFSTR("solaris") #define _CFBundleLinuxPlatformName CFSTR("linux") #define _CFBundleFreeBSDPlatformName CFSTR("freebsd") -#define _CFBundleMacOSXPlatformNameSuffix CFSTR("-macos") -#define _CFBundleAlternateMacOSXPlatformNameSuffix CFSTR("-macosx") -#define _CFBundleiPhoneOSPlatformNameSuffix CFSTR("-iphoneos") -#define _CFBundleWindowsPlatformNameSuffix CFSTR("-windows") -#define _CFBundleHPUXPlatformNameSuffix CFSTR("-hpux") -#define _CFBundleSolarisPlatformNameSuffix CFSTR("-solaris") -#define _CFBundleLinuxPlatformNameSuffix CFSTR("-linux") -#define _CFBundleFreeBSDPlatformNameSuffix CFSTR("-freebsd") - -CF_PRIVATE CFStringRef _CFBundleGetProductNameSuffix(void); -CF_PRIVATE CFStringRef _CFBundleGetPlatformNameSuffix(void); +#define _CFBundleCygwinPlatformName CFSTR("cygwin") #define _CFBundleDefaultStringTableName CFSTR("Localizable") #define _CFBundleStringTableType CFSTR("strings") diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c b/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c index 021cf1fdd5..6e3d7567ea 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Locale.c @@ -1,7 +1,7 @@ /* CFBundle_Locale.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -10,7 +10,6 @@ #include "CFBundle_Internal.h" - #include #if __HAS_APPLE_ICU__ diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Main.c b/CoreFoundation/PlugIn.subproj/CFBundle_Main.c deleted file mode 100644 index a980d30888..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Main.c +++ /dev/null @@ -1,170 +0,0 @@ -/* CFBundle_Main.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker - */ - -#include -#include "CFBundle_Internal.h" - - - -#if defined(BINARY_SUPPORT_DLFCN) -#include -#ifndef RTLD_FIRST -#define RTLD_FIRST 0 -#endif -#endif /* BINARY_SUPPORT_DLFCN */ - -static Boolean _initedMainBundle = false; -static CFBundleRef _mainBundle = NULL; -static char __CFBundleMainID__[1026] = {0}; -CF_PRIVATE char *__CFBundleMainID = __CFBundleMainID__; -static pthread_mutex_t _mainBundleLock = PTHREAD_MUTEX_INITIALIZER; - -#pragma mark - - -static void _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(CFStringRef executablePath) { - CFBundleGetInfoDictionary(_mainBundle); - if (!_mainBundle->_infoDict || CFDictionaryGetCount(_mainBundle->_infoDict) == 0) { - // if type 3 bundle and no Info.plist, treat as unbundled, since this gives too many false positives - if (_mainBundle->_version == 3) _mainBundle->_version = 4; - if (_mainBundle->_version == 0) { - // if type 0 bundle and no Info.plist and not main executable for bundle, treat as unbundled, since this gives too many false positives - CFStringRef executableName = _CFBundleCopyExecutableName(_mainBundle, NULL, NULL); - if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) _mainBundle->_version = 4; - if (executableName) CFRelease(executableName); - } -#if defined(BINARY_SUPPORT_DYLD) - if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) { - if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict); - _mainBundle->_infoDict = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable(); - } -#endif /* BINARY_SUPPORT_DYLD */ - } else { -#if defined(BINARY_SUPPORT_DYLD) - if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary) { - // if dyld and not main executable for bundle, prefer info dictionary from executable - CFStringRef executableName = _CFBundleCopyExecutableName(_mainBundle, NULL, NULL); - if (!executableName || !executablePath || !CFStringHasSuffix(executablePath, executableName)) { - CFDictionaryRef infoDictFromExecutable = (CFDictionaryRef)_CFBundleCreateInfoDictFromMainExecutable(); - if (infoDictFromExecutable && CFDictionaryGetCount(infoDictFromExecutable) > 0) { - if (_mainBundle->_infoDict) CFRelease(_mainBundle->_infoDict); - _mainBundle->_infoDict = infoDictFromExecutable; - } else if (infoDictFromExecutable) { - CFRelease(infoDictFromExecutable); - } - } - if (executableName) CFRelease(executableName); - } -#endif /* BINARY_SUPPORT_DYLD */ - } - if (!_mainBundle->_infoDict) _mainBundle->_infoDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - if (!_mainBundle->_executablePath && executablePath) _mainBundle->_executablePath = (CFStringRef)CFRetain(executablePath); - CFStringRef bundleID = (CFStringRef)CFDictionaryGetValue(_mainBundle->_infoDict, kCFBundleIdentifierKey); - if (bundleID) { - if (!CFStringGetCString(bundleID, __CFBundleMainID__, sizeof(__CFBundleMainID__) - 2, kCFStringEncodingUTF8)) { - __CFBundleMainID__[0] = '\0'; - } - } -} - -static CFBundleRef _CFBundleGetMainBundleAlreadyLocked(void) { - if (!_initedMainBundle) { - const char *processPath; - CFStringRef str = NULL; - CFURLRef executableURL = NULL, bundleURL = NULL; - _initedMainBundle = true; - processPath = _CFProcessPath(); - if (processPath) { - str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath); - if (!executableURL) executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false); - } - if (executableURL) bundleURL = _CFBundleCopyBundleURLForExecutableURL(executableURL); - if (bundleURL) { - // make sure that main bundle has executable path - //??? what if we are not the main executable in the bundle? - // NB doFinalProcessing must be false here, see below - _mainBundle = _CFBundleCreateMain(kCFAllocatorSystemDefault, bundleURL); - if (_mainBundle) { - // make sure that the main bundle is listed as loaded, and mark it as executable - _mainBundle->_isLoaded = true; -#if defined(BINARY_SUPPORT_DYLD) - if (_mainBundle->_binaryType == __CFBundleUnknownBinary) { - if (!executableURL) { - _mainBundle->_binaryType = __CFBundleNoBinary; - } else { - _mainBundle->_binaryType = _CFBundleGrokBinaryType(executableURL); - if (_mainBundle->_binaryType != __CFBundleCFMBinary && _mainBundle->_binaryType != __CFBundleUnreadableBinary) _mainBundle->_resourceData._executableLacksResourceFork = true; - } - } -#endif /* BINARY_SUPPORT_DYLD */ - // get cookie for already-loaded main bundle -#if defined(BINARY_SUPPORT_DLFCN) - if (!_mainBundle->_handleCookie) { - _mainBundle->_handleCookie = dlopen(NULL, RTLD_NOLOAD | RTLD_FIRST); -#if LOG_BUNDLE_LOAD - printf("main bundle %p getting handle %p\n", _mainBundle, _mainBundle->_handleCookie); -#endif /* LOG_BUNDLE_LOAD */ - } -#elif defined(BINARY_SUPPORT_DYLD) - if (_mainBundle->_binaryType == __CFBundleDYLDExecutableBinary && !_mainBundle->_imageCookie) { - _mainBundle->_imageCookie = (void *)_dyld_get_image_header(0); -#if LOG_BUNDLE_LOAD - printf("main bundle %p getting image %p\n", _mainBundle, _mainBundle->_imageCookie); -#endif /* LOG_BUNDLE_LOAD */ - } -#endif /* BINARY_SUPPORT_DLFCN */ - _CFBundleInitializeMainBundleInfoDictionaryAlreadyLocked(str); - // Perform delayed final processing steps. - // This must be done after _isLoaded has been set, for security reasons (3624341). - // It is safe to unlock and re-lock here because we don't really do anything under the lock after we are done. It is just re-locked to satisfy the 'already locked' contract. - pthread_mutex_unlock(&_mainBundleLock); - _CFBundleInitPlugIn(_mainBundle); - pthread_mutex_lock(&_mainBundleLock); - } - } - if (bundleURL) CFRelease(bundleURL); - if (str) CFRelease(str); - if (executableURL) CFRelease(executableURL); - - } - return _mainBundle; -} - -#pragma mark - -#pragma mark Exported Functions - -CF_EXPORT CFURLRef _CFBundleCopyMainBundleExecutableURL(Boolean *looksLikeBundle) { - // This function is for internal use only; _mainBundle is deliberately accessed outside of the lock to get around a reentrancy issue - const char *processPath; - CFStringRef str = NULL; - CFURLRef executableURL = NULL; - processPath = _CFProcessPath(); - if (processPath) { - str = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, processPath); - if (str) { - executableURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, str, PLATFORM_PATH_STYLE, false); - CFRelease(str); - } - } - if (looksLikeBundle) { - CFBundleRef mainBundle = _mainBundle; - if (mainBundle && (3 == mainBundle->_version || 4 == mainBundle->_version)) mainBundle = NULL; - *looksLikeBundle = (mainBundle ? true : false); - } - return executableURL; -} - - -CF_EXPORT CFBundleRef CFBundleGetMainBundle(void) { - CFBundleRef mainBundle; - pthread_mutex_lock(&_mainBundleLock); - mainBundle = _CFBundleGetMainBundleAlreadyLocked(); - pthread_mutex_unlock(&_mainBundleLock); - return mainBundle; -} diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_ResourceFork.c b/CoreFoundation/PlugIn.subproj/CFBundle_ResourceFork.c deleted file mode 100644 index a35d54e78a..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFBundle_ResourceFork.c +++ /dev/null @@ -1,7 +0,0 @@ -/* CFBundle_ResourceFork.c - Copyright (c) 1999-2017, Apple Inc. All rights reserved. - Responsibility: Tony Parker -*/ - -#include - diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c b/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c index 5f666749b0..2586da99de 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Resources.c @@ -1,7 +1,7 @@ /* CFBundle_Resources.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -106,6 +106,22 @@ static CFStringRef _CFBundleGetResourceDirForVersion(uint8_t version) { return CFSTR(""); } +CF_PRIVATE void _CFBundleAppendResourceDir(CFMutableStringRef path, uint8_t version) { + if (1 == version) { + // /path/to/bundle/Support Files/ + CFStringAppend(path, _CFBundleSupportFilesDirectoryName1); + _CFAppendTrailingPathSlash2(path); + } else if (2 == version) { + // /path/to/bundle/Contents/ + CFStringAppend(path, _CFBundleSupportFilesDirectoryName2); + _CFAppendTrailingPathSlash2(path); + } + if (0 == version || 1 == version || 2 == version) { + // /path/to/bundle//Resources + CFStringAppend(path, _CFBundleResourcesDirectoryName); + } +} + CF_EXPORT CFURLRef CFBundleCopyResourceURL(CFBundleRef bundle, CFStringRef resourceName, CFStringRef resourceType, CFStringRef subDirName) { if (!bundle) return NULL; CFURLRef result = (CFURLRef) _CFBundleCopyFindResources(bundle, NULL, NULL, resourceName, resourceType, subDirName, NULL, false, false, NULL); @@ -173,6 +189,7 @@ CF_EXPORT CFArrayRef CFBundleCopyResourceURLsOfTypeInDirectory(CFURLRef bundleUR #pragma mark - #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS +// Note that subDirName is expected to be the string for a URL CF_INLINE Boolean _CFBundleURLHasSubDir(CFURLRef url, CFStringRef subDirName) { Boolean isDir = false, result = false; CFURLRef dirURL = CFURLCreateWithString(kCFAllocatorSystemDefault, subDirName, url); @@ -217,7 +234,6 @@ CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url) { __block Boolean foundResources = false; __block Boolean foundSupportFiles2 = false; __block Boolean foundSupportFiles1 = false; - __block Boolean foundUnknown = false; _CFIterateDirectory(directoryPath, false, NULL, ^Boolean (CFStringRef fileName, CFStringRef fileNameWithPrefix, uint8_t fileType) { // We're looking for a few different names, and also some info on if it's a directory or not. @@ -231,9 +247,6 @@ CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url) { } else if (fileNameLen == supportFilesDirectoryLength && CFStringCompareWithOptions(fileName, _CFBundleSupportFilesDirectoryName1, CFRangeMake(0, supportFilesDirectoryLength), kCFCompareCaseInsensitive) == kCFCompareEqualTo) { foundSupportFiles1 = true; } - } else if (fileType == DT_UNKNOWN) { - // We'll have to do a more expensive check later; readdir couldn't tell us what the kind of a file was. This may mean that we are looking on a network directory. - foundUnknown = true; } return true; }); @@ -256,11 +269,10 @@ CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url) { localVersion = 1; } } - + #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS - // Do a more substantial check for the subdirectories that make up version 0/1/2 bundles. These are sometimes symlinks (like in Frameworks) and they would have been missed by our check above. - // n.b. that the readdir above may return DT_UNKNOWN, for example, when the directory is on a network mount. - if (foundUnknown && localVersion == 3) { + // Do a more substantial check for the subdirectories that make up version 0/1/2 bundles. These are sometimes symlinks (like in Frameworks) and they would have been missed by our check above. Perhaps we can do a check for DT_LNK there as well, if it's sufficient instead of looking at the actual contents. + if (localVersion == 3) { if (hasFrameworkSuffix) { if (_CFBundleURLHasSubDir(url, _CFBundleResourcesURLFromBase0)) localVersion = 0; else if (_CFBundleURLHasSubDir(url, _CFBundleSupportFilesURLFromBase2)) localVersion = 2; @@ -272,7 +284,7 @@ CF_PRIVATE uint8_t _CFBundleGetBundleVersionForURL(CFURLRef url) { } } #endif - + CFRelease(directoryPath); return localVersion; } @@ -300,7 +312,7 @@ CF_EXPORT CFStringRef _CFBundleGetCurrentPlatform(void) { #if TARGET_OS_CYGWIN return CFSTR("Cygwin"); #else - return CFSTR("Linux"); + return CFSTR("Linux"); #endif #elif DEPLOYMENT_TARGET_FREEBSD return CFSTR("FreeBSD"); @@ -322,7 +334,29 @@ CF_PRIVATE CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void) { #if TARGET_OS_CYGWIN return CFSTR("Cygwin"); #else - return CFSTR("Linux"); + return CFSTR("Linux"); +#endif +#elif DEPLOYMENT_TARGET_FREEBSD + return CFSTR("FreeBSD"); +#else +#error Unknown or unspecified DEPLOYMENT_TARGET +#endif +} + +CF_PRIVATE CFStringRef _CFBundleGetAlternatePlatformExecutablesSubdirectoryName(void) { +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + return CFSTR("Mac OS X"); +#elif DEPLOYMENT_TARGET_WINDOWS + return CFSTR("WinNT"); +#elif DEPLOYMENT_TARGET_SOLARIS + return CFSTR("Solaris"); +#elif DEPLOYMENT_TARGET_HPUX + return CFSTR("HP-UX"); +#elif DEPLOYMENT_TARGET_LINUX +#if TARGET_OS_CYGWIN + return CFSTR("Cygwin"); +#else + return CFSTR("Linux"); #endif #elif DEPLOYMENT_TARGET_FREEBSD return CFSTR("FreeBSD"); @@ -331,6 +365,42 @@ CF_PRIVATE CFStringRef _CFBundleGetPlatformExecutablesSubdirectoryName(void) { #endif } +CF_PRIVATE CFStringRef _CFBundleGetOtherPlatformExecutablesSubdirectoryName(void) { +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + return CFSTR("MacOSClassic"); +#elif DEPLOYMENT_TARGET_WINDOWS + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_HPUX + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_SOLARIS + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_LINUX + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_FREEBSD + return CFSTR("Other"); +#else +#error Unknown or unspecified DEPLOYMENT_TARGET +#endif +} + +CF_PRIVATE CFStringRef _CFBundleGetOtherAlternatePlatformExecutablesSubdirectoryName(void) { +#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI + return CFSTR("Mac OS 8"); +#elif DEPLOYMENT_TARGET_WINDOWS + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_HPUX + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_SOLARIS + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_LINUX + return CFSTR("Other"); +#elif DEPLOYMENT_TARGET_FREEBSD + return CFSTR("Other"); +#else +#error Unknown or unspecified DEPLOYMENT_TARGET +#endif +} + CFArrayRef CFBundleCopyExecutableArchitecturesForURL(CFURLRef url) { CFArrayRef result = NULL; CFBundleRef bundle = CFBundleCreate(kCFAllocatorSystemDefault, url); @@ -530,10 +600,7 @@ static void _CFBundleSplitFileName(CFStringRef fileName, CFStringRef *noProductO } } -static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFStringRef subdirectory, CFMutableArrayRef allFiles, Boolean hasFileAdded, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFMutableDictionaryRef addedTypes, Boolean firstLproj, CFStringRef lprojName) { - - CFStringRef product = _CFBundleGetProductNameSuffix(); - CFStringRef platform = _CFBundleGetPlatformNameSuffix(); +static Boolean _CFBundleReadDirectory(CFStringRef pathOfDir, CFStringRef subdirectory, CFMutableArrayRef allFiles, Boolean hasFileAdded, CFMutableDictionaryRef queryTable, CFMutableDictionaryRef typeDir, CFMutableDictionaryRef addedTypes, Boolean firstLproj, CFStringRef product, CFStringRef platform, CFStringRef lprojName) { CFArrayRef stuffToPrefix = NULL; if (lprojName && subdirectory) { @@ -633,6 +700,14 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la CFMutableArrayRef allFiles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks); CFMutableDictionaryRef typeDir = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + 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); + CFMutableStringRef path = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, 0, inPath); if (resourcesDirectory) { @@ -646,7 +721,7 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la _CFAppendPathComponent2(path, subdirectory); } // read the content in sub dir and put them into query table - _CFBundleReadDirectory(path, subdirectory, allFiles, false, queryTable, typeDir, NULL, false, NULL); + _CFBundleReadDirectory(path, subdirectory, allFiles, false, queryTable, typeDir, NULL, false, product, platform, NULL); CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen)); // Strip the string back to the base path CFIndex numOfAllFiles = CFArrayGetCount(allFiles); @@ -667,7 +742,7 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la if (subdirectory) { _CFAppendPathComponent2(path, subdirectory); } - _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, firstLproj, lprojTargetWithLproj); + _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, firstLproj, product, platform, lprojTargetWithLproj); CFRelease(lprojTargetWithLproj); CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen)); // Strip the string back to the base path @@ -683,7 +758,7 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la if (subdirectory) { _CFAppendPathComponent2(path, subdirectory); } - _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, YES, _CFBundleBaseDirectoryWithLproj); + _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, YES, product, platform, _CFBundleBaseDirectoryWithLproj); CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen)); // Strip the string back to the base path if (!hasFileAdded && numOfAllFiles < CFArrayGetCount(allFiles)) { @@ -702,7 +777,7 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la if (subdirectory) { _CFAppendPathComponent2(path, subdirectory); } - _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, false, lprojTargetWithLproj); + _CFBundleReadDirectory(path, subdirectory, allFiles, hasFileAdded, queryTable, typeDir, addedTypes, false, product, platform, lprojTargetWithLproj); CFRelease(lprojTargetWithLproj); CFStringDelete(path, CFRangeMake(basePathLen, CFStringGetLength(path) - basePathLen)); // Strip the string back to the base path @@ -720,6 +795,8 @@ static CFDictionaryRef _createQueryTableAtPath(CFStringRef inPath, CFArrayRef la CFDictionarySetValue(queryTable, _CFBundleAllFiles, allFiles); } + CFRelease(platform); + CFRelease(product); CFRelease(allFiles); CFRelease(typeDir); diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c b/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c index ea3906e90e..1764032b5e 100644 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c +++ b/CoreFoundation/PlugIn.subproj/CFBundle_Strings.c @@ -1,7 +1,7 @@ /* CFBundle_Strings.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFBundle_Tables.c b/CoreFoundation/PlugIn.subproj/CFBundle_Tables.c deleted file mode 100644 index 3b92a0ad06..0000000000 --- a/CoreFoundation/PlugIn.subproj/CFBundle_Tables.c +++ /dev/null @@ -1,239 +0,0 @@ -/* CFBundle_Tables.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors - - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors - Licensed under Apache License v2.0 with Runtime Library Exception - See http://swift.org/LICENSE.txt for license information - See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors - Responsibility: Tony Parker -*/ - -#if 0 - -#include -#include "CFBundle_Internal.h" - -static CFMutableDictionaryRef _bundlesByIdentifier = NULL; -static CFMutableDictionaryRef _bundlesByURL = NULL; -static CFMutableArrayRef _allBundles = NULL; - -#if DEPLOYMENT_TARGET_MACOSX -// Some apps may rely on the fact that CFBundle used to allow bundle objects to be deallocated (despite handing out unretained pointers via CFBundleGetBundleWithIdentifier or CFBundleGetAllBundles). To remain compatible even in the face of unsafe behavior, we can optionally use unsafe-unretained memory management for holding on to bundles. -static Boolean _useUnsafeUnretainedTables(void) { - return false; -} -#endif - -static void _CFBundleAddToTables(CFBundleRef bundle, Boolean alreadyLocked) { - if (bundle->_isUnique) return; - - CFStringRef bundleID = CFBundleGetIdentifier(bundle); - - if (!alreadyLocked) pthread_mutex_lock(&CFBundleGlobalDataLock); - - // Add to the _allBundles list - if (!_allBundles) { - CFArrayCallBacks callbacks = kCFTypeArrayCallBacks; -#if DEPLOYMENT_TARGET_MACOSX - if (_useUnsafeUnretainedTables()) { - callbacks.retain = NULL; - callbacks.release = NULL; - } -#endif - // The _allBundles array holds a strong reference on the bundle. - // It does this to prevent a race on bundle deallocation / creation. See: CFBundle isn't thread-safe in RR mode - // Also, the existence of the CFBundleGetBundleWithIdentifier / CFBundleGetAllBundles API means that any bundle we hand out from there must be permanently retained, or callers will potentially have an object that can be deallocated out from underneath them. - _allBundles = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &callbacks); - } - CFArrayAppendValue(_allBundles, bundle); - - // Add to the table that maps urls to bundles - if (!_bundlesByURL) { - CFDictionaryValueCallBacks nonRetainingDictionaryValueCallbacks = kCFTypeDictionaryValueCallBacks; - nonRetainingDictionaryValueCallbacks.retain = NULL; - nonRetainingDictionaryValueCallbacks.release = NULL; - _bundlesByURL = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &nonRetainingDictionaryValueCallbacks); - } - CFDictionarySetValue(_bundlesByURL, bundle->_url, bundle); - - // Add to the table that maps identifiers to bundles - if (bundleID) { - CFMutableArrayRef bundlesWithThisID = NULL; - CFBundleRef existingBundle = NULL; - if (!_bundlesByIdentifier) { - _bundlesByIdentifier = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - } - bundlesWithThisID = (CFMutableArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID); - if (bundlesWithThisID) { - CFIndex i, count = CFArrayGetCount(bundlesWithThisID); - UInt32 existingVersion, newVersion = CFBundleGetVersionNumber(bundle); - for (i = 0; i < count; i++) { - existingBundle = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, i); - existingVersion = CFBundleGetVersionNumber(existingBundle); - // If you load two bundles with the same identifier and the same version, the last one wins. - if (newVersion >= existingVersion) break; - } - CFArrayInsertValueAtIndex(bundlesWithThisID, i, bundle); - } else { - CFArrayCallBacks nonRetainingArrayCallbacks = kCFTypeArrayCallBacks; - nonRetainingArrayCallbacks.retain = NULL; - nonRetainingArrayCallbacks.release = NULL; - bundlesWithThisID = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &nonRetainingArrayCallbacks); - CFArrayAppendValue(bundlesWithThisID, bundle); - CFDictionarySetValue(_bundlesByIdentifier, bundleID, bundlesWithThisID); - CFRelease(bundlesWithThisID); - } - } - if (!alreadyLocked) pthread_mutex_unlock(&CFBundleGlobalDataLock); -} - -static void _CFBundleRemoveFromTables(CFBundleRef bundle, CFURLRef bundleURL, CFStringRef bundleID) { - // Since we no longer allow bundles to be removed from tables, this method does nothing. Modifying the tables during deallocation is risky because if the caller has over-released the bundle object then we will deadlock on the global lock. -#if DEPLOYMENT_TARGET_MACOSX - if (_useUnsafeUnretainedTables()) { - // Except for special cases of unsafe-unretained, where we must clean up the table or risk handing out a zombie object. There may still be outstanding pointers to these bundes (e.g. the result of CFBundleGetBundleWithIdentifier) but there is nothing we can do about that after this point. - - // Unique bundles aren't in the tables anyway - if (bundle->_isUnique) return; - - pthread_mutex_lock(&CFBundleGlobalDataLock); - // Remove from the table of all bundles - if (_allBundles) { - CFIndex i = CFArrayGetFirstIndexOfValue(_allBundles, CFRangeMake(0, CFArrayGetCount(_allBundles)), bundle); - if (i >= 0) CFArrayRemoveValueAtIndex(_allBundles, i); - } - - // Remove from the table that maps urls to bundles - if (bundleURL && _bundlesByURL) { - CFBundleRef bundleForURL = (CFBundleRef)CFDictionaryGetValue(_bundlesByURL, bundleURL); - if (bundleForURL == bundle) CFDictionaryRemoveValue(_bundlesByURL, bundleURL); - } - - // Remove from the table that maps identifiers to bundles - if (bundleID && _bundlesByIdentifier) { - CFMutableArrayRef bundlesWithThisID = (CFMutableArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID); - if (bundlesWithThisID) { - CFIndex count = CFArrayGetCount(bundlesWithThisID); - while (count-- > 0) if (bundle == (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, count)) CFArrayRemoveValueAtIndex(bundlesWithThisID, count); - if (0 == CFArrayGetCount(bundlesWithThisID)) CFDictionaryRemoveValue(_bundlesByIdentifier, bundleID); - } - } - pthread_mutex_unlock(&CFBundleGlobalDataLock); - } -#endif -} - -CF_PRIVATE CFBundleRef _CFBundleCopyBundleForURL(CFURLRef url, Boolean alreadyLocked) { - CFBundleRef result = NULL; - CFBundleRef main = CFBundleGetMainBundle(); - if (main->_url && url && CFEqual(main->_url, url)) { - return main; - } - 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) pthread_mutex_unlock(&CFBundleGlobalDataLock); - return result; -} - -static CFBundleRef _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(CFStringRef bundleID) { - CFBundleRef result = NULL, bundle; - if (_bundlesByIdentifier && bundleID) { - // Note that this array is maintained in descending order by version number - CFArrayRef bundlesWithThisID = (CFArrayRef)CFDictionaryGetValue(_bundlesByIdentifier, bundleID); - if (bundlesWithThisID) { - CFIndex i, count = CFArrayGetCount(bundlesWithThisID); - if (count > 0) { - // First check for loaded bundles so we will always prefer a loaded to an unloaded bundle - for (i = 0; !result && i < count; i++) { - bundle = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, i); - if (CFBundleIsExecutableLoaded(bundle)) result = bundle; - } - // If no loaded bundle, simply take the first item in the array, i.e. the one with the latest version number - if (!result) result = (CFBundleRef)CFArrayGetValueAtIndex(bundlesWithThisID, 0); - } - } - } - return result; -} - -#pragma mark - Exported Functions - -CF_EXPORT CFBundleRef CFBundleGetBundleWithIdentifier(CFStringRef bundleID) { - CFBundleRef result = NULL; - if (bundleID) { - CFBundleRef main = CFBundleGetMainBundle(); - if (main) { - CFDictionaryRef infoDict = CFBundleGetInfoDictionary(main); - if (infoDict) { - CFStringRef mainBundleID = CFDictionaryGetValue(infoDict, kCFBundleIdentifierKey); - if (mainBundleID && CFGetTypeID(mainBundleID) == CFStringGetTypeID() && CFEqual(mainBundleID, bundleID)) { - return main; - } - } - } - pthread_mutex_lock(&CFBundleGlobalDataLock); - result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); -#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); - if (p) { - CFStringRef imagePath = _CFBundleCopyLoadedImagePathForPointer(p); - // If the pointer is in Foundation, we were called by NSBundle and we should look one more frame up the stack for a hint - if (imagePath && CFStringHasSuffix(imagePath, CFSTR("/Foundation"))) { - CFRelease(imagePath); - // Reset to NULL in case p is null below, that will make us fall back through the right path - imagePath = NULL; - p = __builtin_return_address(1); - if (p) { - imagePath = _CFBundleCopyLoadedImagePathForPointer(p); - } - } - - if (imagePath) { - _CFBundleEnsureBundleExistsForImagePath(imagePath); - CFRelease(imagePath); - } - result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); - } - } -#endif - if (!result) { - // Try to guess the bundle from the identifier and try again - _CFBundleEnsureBundlesUpToDateWithHintAlreadyLocked(bundleID); - result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); - } - pthread_mutex_unlock(&CFBundleGlobalDataLock); - } - - if (!result) { - pthread_mutex_lock(&CFBundleGlobalDataLock); - // Make sure all bundles have been created and try again. - _CFBundleEnsureAllBundlesUpToDateAlreadyLocked(); - result = _CFBundlePrimitiveGetBundleWithIdentifierAlreadyLocked(bundleID); - pthread_mutex_unlock(&CFBundleGlobalDataLock); - } - - return result; -} - -CF_EXPORT CFBundleRef _CFBundleGetExistingBundleWithBundleURL(CFURLRef bundleURL) { - CFBundleRef bundle = NULL; - char buff[CFMaxPathSize]; - CFURLRef newURL = NULL; - - if (!CFURLGetFileSystemRepresentation(bundleURL, true, (uint8_t *)buff, CFMaxPathSize)) return NULL; - - newURL = CFURLCreateFromFileSystemRepresentation(kCFAllocatorSystemDefault, (uint8_t *)buff, strlen(buff), true); - if (!newURL) newURL = (CFURLRef)CFRetain(bundleURL); - bundle = _CFBundleCopyBundleForURL(newURL, false); - if (bundle) CFRelease(bundle); - CFRelease(newURL); - return bundle; -} -#endif diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn.c b/CoreFoundation/PlugIn.subproj/CFPlugIn.c index 6f72b6f4f7..b9b29882a7 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn.c +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn.c @@ -1,7 +1,7 @@ /* CFPlugIn.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn.h b/CoreFoundation/PlugIn.subproj/CFPlugIn.h index 78528f2cc9..9c2fdda4bc 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn.h @@ -1,7 +1,7 @@ /* CFPlugIn.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h b/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h index adb55e943d..0231b88dd9 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugInCOM.h @@ -1,7 +1,7 @@ /* CFPlugInCOM.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c index db8e0083dd..9e026f1df6 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c @@ -1,7 +1,7 @@ /* CFPlugIn_Factory.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h index e2bb97d7b3..70e0735e41 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.h @@ -1,7 +1,7 @@ /* CFPlugIn_Factory.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c index a54428d0c9..afd647a697 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c @@ -1,7 +1,7 @@ /* CFPlugIn_Instance.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c b/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c index fd2075e85f..7c2f7ef5b2 100644 --- a/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c +++ b/CoreFoundation/PlugIn.subproj/CFPlugIn_PlugIn.c @@ -1,7 +1,7 @@ /* CFPlugIn_PlugIn.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -48,6 +48,19 @@ static void _registerType(const void *key, const void *val, void *context) { if (typeID) CFRelease(typeID); } +CF_PRIVATE Boolean _CFBundleNeedsInitPlugIn(CFBundleRef bundle) { + Boolean result = false; + CFDictionaryRef infoDict = CFBundleGetInfoDictionary(bundle), factoryDict; + CFStringRef tempStr; + if (infoDict) { + factoryDict = (CFDictionaryRef)CFDictionaryGetValue(infoDict, kCFPlugInFactoriesKey); + if (factoryDict && CFGetTypeID(factoryDict) == CFDictionaryGetTypeID()) result = true; + tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegistrationKey); + if (tempStr && CFGetTypeID(tempStr) == CFStringGetTypeID() && CFStringCompare(tempStr, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) result = true; + } + return result; +} + CF_PRIVATE void _CFBundleInitPlugIn(CFBundleRef bundle) { CFArrayCallBacks _pluginFactoryArrayCallbacks = {0, NULL, NULL, NULL, NULL}; Boolean doDynamicReg = false; @@ -64,18 +77,12 @@ CF_PRIVATE void _CFBundleInitPlugIn(CFBundleRef bundle) { tempStr = (CFStringRef)CFDictionaryGetValue(infoDict, kCFPlugInDynamicRegistrationKey); if (tempStr && CFGetTypeID(tempStr) == CFStringGetTypeID() && CFStringCompare(tempStr, CFSTR("YES"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) doDynamicReg = true; if (!factoryDict && !doDynamicReg) return; // This is not a plug-in. - - if (__CFBundleGetPlugInData(bundle)->_registeredFactory) { - // We already registered - don't do it again - return; - } /* loadOnDemand is true by default if the plugIn does not do dynamic registration. It is false, by default if it does do dynamic registration. The dynamic register function can set this. */ __CFBundleGetPlugInData(bundle)->_isPlugIn = true; __CFBundleGetPlugInData(bundle)->_loadOnDemand = true; __CFBundleGetPlugInData(bundle)->_isDoingDynamicRegistration = false; __CFBundleGetPlugInData(bundle)->_instanceCount = 0; - __CFBundleGetPlugInData(bundle)->_registeredFactory = true; __CFBundleGetPlugInData(bundle)->_factories = CFArrayCreateMutable(CFGetAllocator(bundle), 0, &_pluginFactoryArrayCallbacks); diff --git a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c index 046efe7cab..6366a5b97a 100644 --- a/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c +++ b/CoreFoundation/Preferences.subproj/CFApplicationPreferences.c @@ -1,7 +1,7 @@ /* CFApplicationPreferences.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.c b/CoreFoundation/Preferences.subproj/CFPreferences.c index 56e24f4251..18723c6262 100644 --- a/CoreFoundation/Preferences.subproj/CFPreferences.c +++ b/CoreFoundation/Preferences.subproj/CFPreferences.c @@ -1,7 +1,7 @@ /* CFPreferences.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -790,7 +790,7 @@ static void getVolatileKeysAndValues(CFAllocatorRef alloc, CFTypeRef context, vo CFDictionaryGetKeysAndValues(dict, (const void **)*buf, (const void **)values); } else if (alloc != kCFAllocatorNull) { if (*buf) { - *buf = __CFSafelyReallocateWithAllocator(alloc, *buf, count * 2 * sizeof(void *), 0, NULL); + *buf = (void **)CFAllocatorReallocate(alloc, *buf, count * 2 * sizeof(void *), 0); } else { *buf = (void **)CFAllocatorAllocate(alloc, count*2*sizeof(void *), 0); } diff --git a/CoreFoundation/Preferences.subproj/CFPreferences.h b/CoreFoundation/Preferences.subproj/CFPreferences.h index 6597e5303d..e6711539ad 100644 --- a/CoreFoundation/Preferences.subproj/CFPreferences.h +++ b/CoreFoundation/Preferences.subproj/CFPreferences.h @@ -1,7 +1,7 @@ /* CFPreferences.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -113,7 +113,7 @@ which have preferences in the scope of the given user and host, or NULL if no ap The returned value must be released by the caller; neither argument may be NULL. Does not supported sandboxed applications. */ CF_EXPORT -_Nullable CFArrayRef CFPreferencesCopyApplicationList(CFStringRef userName, CFStringRef hostName) API_DEPRECATED("Unsupported API", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +_Nullable CFArrayRef CFPreferencesCopyApplicationList(CFStringRef userName, CFStringRef hostName) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0); /* Constructs and returns the list of all keys set in the given location, or NULL if no keys are set. The returned value must be released by the caller; diff --git a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c index f5f55476b8..8073848370 100644 --- a/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c +++ b/CoreFoundation/Preferences.subproj/CFXMLPreferencesDomain.c @@ -1,7 +1,7 @@ /* CFXMLPreferencesDomain.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort.c b/CoreFoundation/RunLoop.subproj/CFMachPort.c index 47731f40a5..60b61c4071 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort.c +++ b/CoreFoundation/RunLoop.subproj/CFMachPort.c @@ -1,7 +1,7 @@ /* CFMachPort.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -217,19 +217,19 @@ struct __CFMachPort { /* Bit 2 in the base reserved bits is used for has-send-ref state */ CF_INLINE Boolean __CFMachPortHasReceive(CFMachPortRef mp) { - return __CFRuntimeGetFlag(mp, 1); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)mp)->_cfinfo[CF_INFO_BITS], 1, 1); } CF_INLINE void __CFMachPortSetHasReceive(CFMachPortRef mp) { - __CFRuntimeSetFlag(mp, 1, true); + __CFBitfieldSetValue(((CFRuntimeBase *)mp)->_cfinfo[CF_INFO_BITS], 1, 1, 1); } CF_INLINE Boolean __CFMachPortHasSend(CFMachPortRef mp) { - return __CFRuntimeGetFlag(mp, 2); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)mp)->_cfinfo[CF_INFO_BITS], 2, 2); } CF_INLINE void __CFMachPortSetHasSend(CFMachPortRef mp) { - __CFRuntimeSetFlag(mp, 2, true); + __CFBitfieldSetValue(((CFRuntimeBase *)mp)->_cfinfo[CF_INFO_BITS], 2, 2, 1); } CF_INLINE Boolean __CFMachPortIsValid(CFMachPortRef mp) { @@ -583,9 +583,8 @@ Boolean CFMachPortIsValid(CFMachPortRef mp) { __CFGenericValidateType(mp, CFMachPortGetTypeID()); if (!__CFMachPortIsValid(mp)) return false; mach_port_type_t type = 0; - MACH_PORT_TYPE_PORT_RIGHTS; kern_return_t ret = mach_port_type(mach_task_self(), mp->_port, &type); - if (KERN_SUCCESS != ret || (0 == (type & MACH_PORT_TYPE_PORT_RIGHTS))) { + if (KERN_SUCCESS != ret || (type & ~(MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE|MACH_PORT_TYPE_RECEIVE|MACH_PORT_TYPE_DNREQUEST))) { return false; } return true; diff --git a/CoreFoundation/RunLoop.subproj/CFMachPort.h b/CoreFoundation/RunLoop.subproj/CFMachPort.h index e21c5af87b..c3f59c1071 100644 --- a/CoreFoundation/RunLoop.subproj/CFMachPort.h +++ b/CoreFoundation/RunLoop.subproj/CFMachPort.h @@ -1,7 +1,7 @@ /* CFMachPort.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/RunLoop.subproj/CFMessagePort.c b/CoreFoundation/RunLoop.subproj/CFMessagePort.c index b20d0854cb..235480f829 100644 --- a/CoreFoundation/RunLoop.subproj/CFMessagePort.c +++ b/CoreFoundation/RunLoop.subproj/CFMessagePort.c @@ -1,7 +1,7 @@ /* CFMessagePort.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -73,47 +73,47 @@ struct __CFMessagePort { /* Bit 3 in the base reserved bits is used for is-deallocing state */ CF_INLINE Boolean __CFMessagePortIsValid(CFMessagePortRef ms) { - return __CFRuntimeGetFlag(ms, 0); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 0, 0); } CF_INLINE void __CFMessagePortSetValid(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 0, true); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 0, 0, 1); } CF_INLINE void __CFMessagePortUnsetValid(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 0, false); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 0, 0, 0); } CF_INLINE Boolean __CFMessagePortExtraMachRef(CFMessagePortRef ms) { - return __CFRuntimeGetFlag(ms, 1); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 1, 1); } CF_INLINE void __CFMessagePortSetExtraMachRef(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 1, true); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 1, 1, 1); } CF_INLINE void __CFMessagePortUnsetExtraMachRef(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 1, false); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 1, 1, 0); } CF_INLINE Boolean __CFMessagePortIsRemote(CFMessagePortRef ms) { - return __CFRuntimeGetFlag(ms, 2); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 2, 2); } CF_INLINE void __CFMessagePortSetRemote(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 2, true); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 2, 2, 1); } CF_INLINE void __CFMessagePortUnsetRemote(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 2, false); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 2, 2, 0); } CF_INLINE Boolean __CFMessagePortIsDeallocing(CFMessagePortRef ms) { - return __CFRuntimeGetFlag(ms, 3); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 3, 3); } CF_INLINE void __CFMessagePortSetIsDeallocing(CFMessagePortRef ms) { - __CFRuntimeSetFlag(ms, 3, true); + __CFBitfieldSetValue(((CFRuntimeBase *)ms)->_cfinfo[CF_INFO_BITS], 3, 3, 1); } CF_INLINE void __CFMessagePortLock(CFMessagePortRef ms) { @@ -1144,7 +1144,7 @@ void CFMessagePortSetDispatchQueue(CFMessagePortRef ms, dispatch_queue_t queue) if (MACH_RCV_TOO_LARGE != ret) HALT; uint32_t newSize = round_msg(msg->msgh_size + MAX_TRAILER_SIZE); - msg = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, msg, newSize, 0, NULL); + msg = CFAllocatorReallocate(kCFAllocatorSystemDefault, msg, newSize, 0); msg->msgh_size = newSize; } diff --git a/CoreFoundation/RunLoop.subproj/CFMessagePort.h b/CoreFoundation/RunLoop.subproj/CFMessagePort.h index 619fff42c5..25b05b31bc 100644 --- a/CoreFoundation/RunLoop.subproj/CFMessagePort.h +++ b/CoreFoundation/RunLoop.subproj/CFMessagePort.h @@ -1,7 +1,7 @@ /* CFMessagePort.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -60,7 +60,7 @@ CF_EXPORT SInt32 CFMessagePortSendRequest(CFMessagePortRef remote, SInt32 msgid, CF_EXPORT CFRunLoopSourceRef CFMessagePortCreateRunLoopSource(CFAllocatorRef allocator, CFMessagePortRef local, CFIndex order); -CF_EXPORT void CFMessagePortSetDispatchQueue(CFMessagePortRef ms, dispatch_queue_t queue) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT void CFMessagePortSetDispatchQueue(CFMessagePortRef ms, dispatch_queue_t queue) CF_AVAILABLE(10_6, 4_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/RunLoop.subproj/CFRunLoop.c b/CoreFoundation/RunLoop.subproj/CFRunLoop.c index da2e573a2e..02cc72dacd 100644 --- a/CoreFoundation/RunLoop.subproj/CFRunLoop.c +++ b/CoreFoundation/RunLoop.subproj/CFRunLoop.c @@ -1,7 +1,7 @@ /* CFRunLoop.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -21,8 +21,6 @@ #if __HAS_DISPATCH__ #include #endif -#define cf_trace(...) - #if DEPLOYMENT_TARGET_WINDOWS @@ -71,6 +69,7 @@ extern mach_port_t _dispatch_get_main_queue_port_4CF(void); #elif DEPLOYMENT_TARGET_WINDOWS || TARGET_OS_CYGWIN #include +#define DISPATCH_EXPORT extern DISPATCH_EXPORT HANDLE _dispatch_get_main_queue_handle_4CF(void); DISPATCH_EXPORT void _dispatch_main_queue_callback_4CF(void); @@ -80,9 +79,11 @@ DISPATCH_EXPORT void _dispatch_main_queue_callback_4CF(void); #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 +#define LARGE_INTEGER uint64_t #elif DEPLOYMENT_TARGET_LINUX +#if TARGET_OS_CYGWIN +#else #include #include #include @@ -95,6 +96,7 @@ extern void _dispatch_main_queue_callback_4CF(void *_Null_unspecified msg); #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(x) #endif +#endif #if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_IPHONESIMULATOR || DEPLOYMENT_TARGET_LINUX CF_EXPORT pthread_t _CF_pthread_main_thread_np(void); @@ -153,7 +155,6 @@ static pthread_t kNilPthreadT = (pthread_t)0; #define CF_RUN_LOOP_PROBES 0 -#pragma mark CFRunLoopProbes #if CF_RUN_LOOP_PROBES #include "CFRunLoopProbes.h" #else @@ -249,8 +250,7 @@ CF_PRIVATE void __CFRestartAllThreads(CFArrayRef threads) { static uint32_t __CF_last_warned_port_count = 0; -static void foo() __attribute__((unused)); -static void foo() { +static void __attribute__((unused)) foo() { uint32_t pcnt = __CFGetProcessPortCount(); if (__CF_last_warned_port_count + 1000 < pcnt) { CFArrayRef threads = __CFStopAllThreads(); @@ -385,6 +385,8 @@ static __CFPortSet __CFPortSetAllocate(void) { result->used = 0; result->size = 4; result->handles = (HANDLE *)CFAllocatorAllocate(kCFAllocatorSystemDefault, result->size * sizeof(HANDLE), 0); + +#define CF_SPINLOCK_INIT_FOR_STRUCTS(X) InitializeCriticalSection(&X) CF_SPINLOCK_INIT_FOR_STRUCTS(result->lock); return result; } @@ -420,7 +422,7 @@ static kern_return_t __CFPortSetInsert(__CFPort port, __CFPortSet portSet) { __CFLock(&(portSet->lock)); if (portSet->used >= portSet->size) { portSet->size += 4; - portSet->handles = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, portSet->handles, portSet->size * sizeof(HANDLE), 0, NULL); + portSet->handles = (HANDLE *)CFAllocatorReallocate(kCFAllocatorSystemDefault, portSet->handles, portSet->size * sizeof(HANDLE), 0); } if (portSet->used >= MAXIMUM_WAIT_OBJECTS) { CFLog(kCFLogLevelWarning, CFSTR("*** More than MAXIMUM_WAIT_OBJECTS (%d) ports add to a port set. The last ones will be ignored."), MAXIMUM_WAIT_OBJECTS); @@ -584,13 +586,13 @@ static kern_return_t mk_timer_arm(HANDLE name, LARGE_INTEGER expire_time) { // There is a race we know about here, (timer fire time calculated -> thread suspended -> timer armed == late timer fire), but we don't have a way to avoid it at this time, since the only way to specify an absolute value to the timer is to calculate the relative time first. Fixing that would probably require not using the TSR for timers on Windows. uint64_t now = mach_absolute_time(); if (now > expire_time) { - result.QuadPart = 0; + result = 0; } else { uint64_t timeDiff = expire_time - now; 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); + result = -(amountOfTimeToWait * 10000000); } BOOL res = SetWaitableTimer(name, &result, 0, NULL, NULL, FALSE); @@ -613,6 +615,7 @@ static kern_return_t mk_timer_cancel(HANDLE name, LARGE_INTEGER *result_time) { CF_EXPORT Boolean __CFMainThreadHasExited; + CF_BREAKPOINT_FUNCTION(void _CFRunLoopError_MainThreadHasExited(void)); #pragma mark - @@ -761,8 +764,6 @@ struct __CFRunLoop { CFAbsoluteTime _runTime; CFAbsoluteTime _sleepTime; CFTypeRef _counterpart; - _Atomic(uint8_t) _fromTSD; - CFLock_t _timerTSRLock; }; /* Bit 0 of the base reserved bits is used for stopped state */ @@ -809,23 +810,23 @@ CF_INLINE void __CFRunLoopUnsetIgnoreWakeUps(CFRunLoopRef rl) { } CF_INLINE Boolean __CFRunLoopIsSleeping(CFRunLoopRef rl) { - return __CFRuntimeGetFlag(rl, 1); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1); } CF_INLINE void __CFRunLoopSetSleeping(CFRunLoopRef rl) { - __CFRuntimeSetFlag(rl, 1, true); + __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1, 1); } CF_INLINE void __CFRunLoopUnsetSleeping(CFRunLoopRef rl) { - __CFRuntimeSetFlag(rl, 1, false); + __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 1, 1, 0); } CF_INLINE Boolean __CFRunLoopIsDeallocating(CFRunLoopRef rl) { - return __CFRuntimeGetFlag(rl, 2); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 2, 2); } CF_INLINE void __CFRunLoopSetDeallocating(CFRunLoopRef rl) { - __CFRuntimeSetFlag(rl, 2, true); + __CFBitfieldSetValue(((CFRuntimeBase *)rl)->_cfinfo[CF_INFO_BITS], 2, 2, 1); } CF_INLINE void __CFRunLoopLock(CFRunLoopRef rl) { @@ -914,7 +915,7 @@ static CFRunLoopModeRef __CFRunLoopFindMode(CFRunLoopRef rl, CFStringRef modeNam }); // Set timer to far out there. The unique leeway makes this timer easy to spot in debug output. - dispatch_source_set_timer(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 321); + _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 321); dispatch_resume(rlm->_timerSource); ret = __CFPortSetInsert(queuePort, rlm->_portSet); @@ -1051,19 +1052,20 @@ void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeNa /* Bit 3 in the base reserved bits is used for invalid state in run loop objects */ CF_INLINE Boolean __CFIsValid(const void *cf) { - return __CFRuntimeGetFlag(cf, 3); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3); } CF_INLINE void __CFSetValid(void *cf) { - __CFRuntimeSetFlag(cf, 3, true); + __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3, 1); } CF_INLINE void __CFUnsetValid(void *cf) { - __CFRuntimeSetFlag(cf, 3, false); + __CFBitfieldSetValue(((CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 3, 3, 0); } struct __CFRunLoopSource { CFRuntimeBase _base; + uint32_t _bits; pthread_mutex_t _lock; CFIndex _order; /* immutable */ CFMutableBagRef _runLoops; @@ -1071,19 +1073,20 @@ struct __CFRunLoopSource { CFRunLoopSourceContext version0; /* immutable, except invalidation */ CFRunLoopSourceContext1 version1; /* immutable, except invalidation */ } _context; - _Atomic(Boolean) _signaled; }; +/* Bit 1 of the base reserved bits is used for signalled state */ + CF_INLINE Boolean __CFRunLoopSourceIsSignaled(CFRunLoopSourceRef rls) { - return rls->_signaled; + return (Boolean)__CFBitfieldGetValue(rls->_bits, 1, 1); } CF_INLINE void __CFRunLoopSourceSetSignaled(CFRunLoopSourceRef rls) { - rls->_signaled = true; + __CFBitfieldSetValue(rls->_bits, 1, 1, 1); } CF_INLINE void __CFRunLoopSourceUnsetSignaled(CFRunLoopSourceRef rls) { - rls->_signaled = false; + __CFBitfieldSetValue(rls->_bits, 1, 1, 0); } CF_INLINE void __CFRunLoopSourceLock(CFRunLoopSourceRef rls) { @@ -1113,27 +1116,27 @@ struct __CFRunLoopObserver { /* Bit 1 of the base reserved bits is used for repeats state */ CF_INLINE Boolean __CFRunLoopObserverIsFiring(CFRunLoopObserverRef rlo) { - return __CFRuntimeGetFlag(rlo, 0); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0); } CF_INLINE void __CFRunLoopObserverSetFiring(CFRunLoopObserverRef rlo) { - __CFRuntimeSetFlag(rlo, 0, true); + __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0, 1); } CF_INLINE void __CFRunLoopObserverUnsetFiring(CFRunLoopObserverRef rlo) { - __CFRuntimeSetFlag(rlo, 0, false); + __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 0, 0, 0); } CF_INLINE Boolean __CFRunLoopObserverRepeats(CFRunLoopObserverRef rlo) { - return __CFRuntimeGetFlag(rlo, 1); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1); } CF_INLINE void __CFRunLoopObserverSetRepeats(CFRunLoopObserverRef rlo) { - __CFRuntimeSetFlag(rlo, 1, true); + __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1, 1); } CF_INLINE void __CFRunLoopObserverUnsetRepeats(CFRunLoopObserverRef rlo) { - __CFRuntimeSetFlag(rlo, 1, false); + __CFBitfieldSetValue(((CFRuntimeBase *)rlo)->_cfinfo[CF_INFO_BITS], 1, 1, 0); } CF_INLINE void __CFRunLoopObserverLock(CFRunLoopObserverRef rlo) { @@ -1215,6 +1218,15 @@ CF_INLINE void __CFRunLoopTimerUnlock(CFRunLoopTimerRef rlt) { pthread_mutex_unlock(&(rlt->_lock)); } +static CFLock_t __CFRLTFireTSRLock = CFLockInit; + +CF_INLINE void __CFRunLoopTimerFireTSRLock(void) { + __CFLock(&__CFRLTFireTSRLock); +} + +CF_INLINE void __CFRunLoopTimerFireTSRUnlock(void) { + __CFUnlock(&__CFRLTFireTSRLock); +} #pragma mark - @@ -1316,26 +1328,34 @@ static void __CFRunLoopDeallocateObservers(const void *value, void *context) { if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); } -static void __CFRunLoopKillOneTimer(const void *value, void *context) { - CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)value; - __CFRunLoopTimerLock(rlt); - // if the run loop is deallocating, and since a timer can only be in one - // run loop, we're going to be removing the timer from all modes, so be - // a little heavy-handed and direct - CFSetRemoveAllValues(rlt->_rlModes); - rlt->_runLoop = NULL; - __CFRunLoopTimerUnlock(rlt); -} - static void __CFRunLoopDeallocateTimers(const void *value, void *context) { CFRunLoopModeRef rlm = (CFRunLoopModeRef)value; if (NULL == rlm->_timers) return; + void (^deallocateTimers)(CFMutableArrayRef timers) = ^(CFMutableArrayRef timers) { + CFIndex idx, cnt; + const void **list, *buffer[256]; + cnt = CFArrayGetCount(timers); + list = (const void **)((cnt <= 256) ? buffer : CFAllocatorAllocate(kCFAllocatorSystemDefault, cnt * sizeof(void *), 0)); + CFArrayGetValues(timers, CFRangeMake(0, CFArrayGetCount(timers)), list); + for (idx = 0; idx < cnt; idx++) { + CFRetain(list[idx]); + } + CFArrayRemoveAllValues(timers); + for (idx = 0; idx < cnt; idx++) { + CFRunLoopTimerRef rlt = (CFRunLoopTimerRef)list[idx]; + __CFRunLoopTimerLock(rlt); + // if the run loop is deallocating, and since a timer can only be in one + // run loop, we're going to be removing the timer from all modes, so be + // a little heavy-handed and direct + CFSetRemoveAllValues(rlt->_rlModes); + rlt->_runLoop = NULL; + __CFRunLoopTimerUnlock(rlt); + CFRelease(list[idx]); + } + if (list != buffer) CFAllocatorDeallocate(kCFAllocatorSystemDefault, list); + }; - const CFRange range = CFRangeMake(0, CFArrayGetCount(rlm->_timers)); - if (range.length) { - CFArrayApplyFunction(rlm->_timers, range, __CFRunLoopKillOneTimer, context); - CFArrayRemoveAllValues(rlm->_timers); - } + if (rlm->_timers && CFArrayGetCount(rlm->_timers)) deallocateTimers(rlm->_timers); } CF_EXPORT CFRunLoopRef _CFRunLoopGet0b(pthread_t t); @@ -1343,14 +1363,6 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0b(pthread_t t); static void __CFRunLoopDeallocate(CFTypeRef cf) { CFRunLoopRef rl = (CFRunLoopRef)cf; - if (rl->_fromTSD == 0) { - CRSetCrashLogMessage("Attempting to deallocate CFRunLoop outside of thread destructor -- this is likely an over-release of the run loop"); - HALT; - } - - // unsetting this here to possibly try to catch multiple concurrent __CFRunLoopDeallocate calls (never seen wild) - rl->_fromTSD = 0; - if (_CFRunLoopGet0b(pthread_main_thread_np()) == cf) HALT; /* We try to keep the run loop in a valid state as long as possible, @@ -1448,8 +1460,6 @@ static CFRunLoopRef __CFRunLoopCreate(pthread_t t) { loop->_blocks_tail = NULL; loop->_counterpart = NULL; loop->_pthread = t; - loop->_fromTSD = 0; - loop->_timerTSRLock = CFLockInit; #if DEPLOYMENT_TARGET_WINDOWS loop->_winthread = GetCurrentThreadId(); #else @@ -1487,19 +1497,14 @@ CF_PRIVATE CFRunLoopRef _CFRunLoopCacheLookup(pthread_t t, const Boolean createC return loop; } -CF_PRIVATE CFRunLoopRef _CFRunLoopGetButDontCreateCurrent(void) { - CFRunLoopRef loop = (CFRunLoopRef)_CFGetTSDCreateIfNeeded(__CFTSDKeyRunLoop, false); - if (loop == NULL) { - loop = _CFRunLoopCacheLookup(pthread_self(), false); - } - return loop; -} - // should only be called by Foundation CF_EXPORT Boolean _CFRunLoopIsCurrent(const CFRunLoopRef rl) { Boolean result = false; if (rl) { - const CFRunLoopRef loop = _CFRunLoopGetButDontCreateCurrent(); + CFRunLoopRef loop = (CFRunLoopRef)_CFGetTSDCreateIfNeeded(__CFTSDKeyRunLoop, false); + if (loop == NULL) { + loop = _CFRunLoopCacheLookup(pthread_self(), false); + } result = (rl == loop); } return result; @@ -1513,6 +1518,7 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) { } __CFLock(&loopsLock); if (!__CFRunLoops) { + __CFUnlock(&loopsLock); CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, &kCFTypeDictionaryValueCallBacks); CFRunLoopRef mainLoop = __CFRunLoopCreate(pthread_main_thread_np()); CFDictionarySetValue(dict, pthreadPointer(pthread_main_thread_np()), mainLoop); @@ -1520,18 +1526,22 @@ CF_EXPORT CFRunLoopRef _CFRunLoopGet0(pthread_t t) { CFRelease(dict); } CFRelease(mainLoop); + __CFLock(&loopsLock); } - CFRunLoopRef newLoop = NULL; CFRunLoopRef loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t)); + __CFUnlock(&loopsLock); if (!loop) { - newLoop = __CFRunLoopCreate(t); - CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop); - loop = newLoop; + CFRunLoopRef newLoop = __CFRunLoopCreate(t); + __CFLock(&loopsLock); + loop = (CFRunLoopRef)CFDictionaryGetValue(__CFRunLoops, pthreadPointer(t)); + if (!loop) { + CFDictionarySetValue(__CFRunLoops, pthreadPointer(t), newLoop); + loop = newLoop; + } + // don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it + __CFUnlock(&loopsLock); + CFRelease(newLoop); } - __CFUnlock(&loopsLock); - // don't release run loops inside the loopsLock, because CFRunLoopDeallocate may end up taking it - if (newLoop) { CFRelease(newLoop); } - if (pthread_equal(t, pthread_self())) { _CFSetTSD(__CFTSDKeyRunLoop, (void *)loop, NULL); if (0 == _CFGetTSD(__CFTSDKeyRunLoopCntr)) { @@ -1590,10 +1600,7 @@ CF_PRIVATE void __CFFinalizeRunLoop(uintptr_t data) { __CFRunLoopRemoveAllSources(rl, kCFRunLoopCommonModes); CFRelease(array); } - if (rl) { - rl->_fromTSD = 1; - CFRelease(rl); - } + if (rl) CFRelease(rl); } pthread_t _CFRunLoopGet1(CFRunLoopRef rl) { @@ -1623,11 +1630,9 @@ CF_EXPORT CFTypeRef _CFRunLoopGet2b(CFRunLoopRef rl) { #if DEPLOYMENT_TARGET_MACOSX void _CFRunLoopSetCurrent(CFRunLoopRef rl) { if (pthread_main_np()) return; - CFRunLoopRef currentLoop = _CFRunLoopGetButDontCreateCurrent(); + CFRunLoopRef currentLoop = CFRunLoopGetCurrent(); if (rl != currentLoop) { - if (currentLoop) { - CFRetain(currentLoop); // avoid a deallocation of the currentLoop inside the lock - } + CFRetain(currentLoop); // avoid a deallocation of the currentLoop inside the lock __CFLock(&loopsLock); if (rl) { CFDictionarySetValue(__CFRunLoops, pthreadPointer(pthread_self()), rl); @@ -1635,9 +1640,7 @@ void _CFRunLoopSetCurrent(CFRunLoopRef rl) { CFDictionaryRemoveValue(__CFRunLoops, pthreadPointer(pthread_self())); } __CFUnlock(&loopsLock); - if (currentLoop) { - CFRelease(currentLoop); - } + CFRelease(currentLoop); _CFSetTSD(__CFTSDKeyRunLoop, NULL, NULL); _CFSetTSD(__CFTSDKeyRunLoopCntr, 0, (void (*)(void *))__CFFinalizeRunLoop); } @@ -1751,42 +1754,35 @@ void CFRunLoopAddCommonMode(CFRunLoopRef rl, CFStringRef modeName) { #if __HAS_DISPATCH__ -static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) { +static void __attribute__((noinline)) __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(void *msg) { _dispatch_main_queue_callback_4CF(msg); - __asm __volatile__(""); // thwart tail-call optimization + asm __volatile__(""); // thwart tail-call optimization } #endif -static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { +static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(CFRunLoopObserverCallBack func, CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info) { if (func) { func(observer, activity, info); } - __asm __volatile__(""); // thwart tail-call optimization + asm __volatile__(""); // thwart tail-call optimization } -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(CFRunLoopTimerCallBack func, CFRunLoopTimerRef timer, void *info) { +static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(CFRunLoopTimerCallBack func, CFRunLoopTimerRef timer, void *info) { if (func) { func(timer, info); } - __asm __volatile__(""); // thwart tail-call optimization + asm __volatile__(""); // thwart tail-call optimization } -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(void (^block)(void)) { +static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(void (^block)(void)) { if (block) { block(); } - __asm __volatile__(""); // thwart tail-call optimization + asm __volatile__(""); // thwart tail-call optimization } static Boolean __CFRunLoopDoBlocks(CFRunLoopRef rl, CFRunLoopModeRef rlm) { // Call with rl and rlm locked - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_BLOCKS | DBG_FUNC_START, rl, rlm, 0, 0); - if (!rl->_blocks_head) return false; if (!rlm || !rlm->_name) return false; Boolean did = false; @@ -1818,9 +1814,7 @@ static Boolean __CFRunLoopDoBlocks(CFRunLoopRef rl, CFRunLoopModeRef rlm) { // C CFRelease(curr->_mode); free(curr); if (doit) { - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_BLOCK | DBG_FUNC_START, rl, rlm, block, 0); __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__(block); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_BLOCK | DBG_FUNC_END, rl, rlm, block, 0); did = true; } Block_release(block); // do this before relocking to prevent deadlocks where some yahoo wants to run the run loop reentrantly from their dealloc @@ -1833,18 +1827,11 @@ static Boolean __CFRunLoopDoBlocks(CFRunLoopRef rl, CFRunLoopModeRef rlm) { // C rl->_blocks_head = head; if (!rl->_blocks_tail) rl->_blocks_tail = tail; } - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_BLOCKS | DBG_FUNC_END, rl, rlm, 0, 0); - return did; } /* rl is locked, rlm is locked on entrance and exit */ -static void __CFRunLoopDoObservers() __attribute__((noinline)); -static void __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopActivity activity) { /* DOES CALLOUT */ - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_OBSERVERS | DBG_FUNC_START, rl, rlm, activity, 0); - +static void __attribute__((noinline)) __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopActivity activity) { /* DOES CALLOUT */ CHECK_FOR_FORK(); CFIndex cnt = rlm->_observers ? CFArrayGetCount(rlm->_observers) : 0; @@ -1869,11 +1856,7 @@ static void __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunL Boolean doInvalidate = !__CFRunLoopObserverRepeats(rlo); __CFRunLoopObserverSetFiring(rlo); __CFRunLoopObserverUnlock(rlo); - CFRunLoopObserverCallBack callout = rlo->_callout; - void *info = rlo->_context.info; - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_OBSERVER | DBG_FUNC_START, callout, rlo, activity, info); - __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(callout, rlo, activity, info); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_OBSERVER | DBG_FUNC_END, callout, rlo, activity, info); + __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__(rlo->_callout, rlo, activity, rlo->_context.info); if (doInvalidate) { CFRunLoopObserverInvalidate(rlo); } @@ -1887,8 +1870,6 @@ static void __CFRunLoopDoObservers(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunL __CFRunLoopModeLock(rlm); if (collectedObservers != buffer) free(collectedObservers); - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_OBSERVERS | DBG_FUNC_END, rl, rlm, activity, 0); } static CFComparisonResult __CFRunLoopSourceComparator(const void *val1, const void *val2, void *context) { @@ -1917,16 +1898,14 @@ static void __CFRunLoopCollectSources0(const void *value, void *context) { } } -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(void (*perform)(void *), void *info) { +static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(void (*perform)(void *), void *info) { if (perform) { perform(info); } - __asm __volatile__(""); // thwart tail-call optimization + asm __volatile__(""); // thwart tail-call optimization } -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__() __attribute__((noinline)); -static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__( +static void __attribute__((noinline)) __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__( #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, @@ -1941,78 +1920,68 @@ static void __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__( perform(info); #endif } - __asm __volatile__(""); // thwart tail-call optimization -} - -static Boolean __CFRunLoopDoSource0(CFRunLoopSourceRef rls) { - - Boolean sourceHandled = false; - __CFRunLoopSourceLock(rls); - if (__CFRunLoopSourceIsSignaled(rls)) { - __CFRunLoopSourceUnsetSignaled(rls); - if (__CFIsValid(rls)) { - __CFRunLoopSourceUnlock(rls); - void *perform = rls->_context.version0.perform; - void *info = rls->_context.version0.info; - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_SOURCE0 | DBG_FUNC_START, perform, info, 0, 0); - __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(perform, info); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_SOURCE0 | DBG_FUNC_END, perform, info, 0, 0); - CHECK_FOR_FORK(); - sourceHandled = true; - } else { - __CFRunLoopSourceUnlock(rls); - } - } else { - __CFRunLoopSourceUnlock(rls); - } - - - return sourceHandled; + asm __volatile__(""); // thwart tail-call optimization } /* rl is locked, rlm is locked on entrance and exit */ static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Boolean stopAfterHandle) __attribute__((noinline)); static Boolean __CFRunLoopDoSources0(CFRunLoopRef rl, CFRunLoopModeRef rlm, Boolean stopAfterHandle) { /* DOES CALLOUT */ - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_SOURCES0 | DBG_FUNC_START, rl, rlm, stopAfterHandle, 0); - CHECK_FOR_FORK(); CFTypeRef sources = NULL; Boolean sourceHandled = false; - + /* Fire the version 0 sources */ if (NULL != rlm->_sources0 && 0 < CFSetGetCount(rlm->_sources0)) { CFSetApplyFunction(rlm->_sources0, (__CFRunLoopCollectSources0), &sources); } if (NULL != sources) { - __CFRunLoopModeUnlock(rlm); - __CFRunLoopUnlock(rl); - // sources is either a single (retained) CFRunLoopSourceRef or an array of (retained) CFRunLoopSourceRef + __CFRunLoopModeUnlock(rlm); + __CFRunLoopUnlock(rl); + // sources is either a single (retained) CFRunLoopSourceRef or an array of (retained) CFRunLoopSourceRef if (CFGetTypeID(sources) == CFRunLoopSourceGetTypeID()) { CFRunLoopSourceRef rls = (CFRunLoopSourceRef)sources; - - sourceHandled = __CFRunLoopDoSource0(rls); - - } else { - CFIndex cnt = CFArrayGetCount((CFArrayRef)sources); - CFArraySortValues((CFMutableArrayRef)sources, CFRangeMake(0, cnt), (__CFRunLoopSourceComparator), NULL); - for (CFIndex idx = 0; idx < cnt; idx++) { - CFRunLoopSourceRef rls = (CFRunLoopSourceRef)CFArrayGetValueAtIndex((CFArrayRef)sources, idx); - - sourceHandled = __CFRunLoopDoSource0(rls); - - if (stopAfterHandle && sourceHandled) { - break; - } - } - } - CFRelease(sources); - __CFRunLoopLock(rl); - __CFRunLoopModeLock(rlm); + __CFRunLoopSourceLock(rls); + if (__CFRunLoopSourceIsSignaled(rls)) { + __CFRunLoopSourceUnsetSignaled(rls); + if (__CFIsValid(rls)) { + __CFRunLoopSourceUnlock(rls); + __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(rls->_context.version0.perform, rls->_context.version0.info); + CHECK_FOR_FORK(); + sourceHandled = true; + } else { + __CFRunLoopSourceUnlock(rls); + } + } else { + __CFRunLoopSourceUnlock(rls); + } + } else { + CFIndex cnt = CFArrayGetCount((CFArrayRef)sources); + CFArraySortValues((CFMutableArrayRef)sources, CFRangeMake(0, cnt), (__CFRunLoopSourceComparator), NULL); + for (CFIndex idx = 0; idx < cnt; idx++) { + CFRunLoopSourceRef rls = (CFRunLoopSourceRef)CFArrayGetValueAtIndex((CFArrayRef)sources, idx); + __CFRunLoopSourceLock(rls); + if (__CFRunLoopSourceIsSignaled(rls)) { + __CFRunLoopSourceUnsetSignaled(rls); + if (__CFIsValid(rls)) { + __CFRunLoopSourceUnlock(rls); + __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__(rls->_context.version0.perform, rls->_context.version0.info); + CHECK_FOR_FORK(); + sourceHandled = true; + } else { + __CFRunLoopSourceUnlock(rls); + } + } else { + __CFRunLoopSourceUnlock(rls); + } + if (stopAfterHandle && sourceHandled) { + break; + } + } + } + CFRelease(sources); + __CFRunLoopLock(rl); + __CFRunLoopModeLock(rlm); } - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_SOURCES0 | DBG_FUNC_END, rl, rlm, stopAfterHandle, 0); - return sourceHandled; } @@ -2020,16 +1989,11 @@ CF_INLINE void __CFRunLoopDebugInfoForRunLoopSource(CFRunLoopSourceRef rls) { } // msg, size and reply are unused on Windows -static Boolean __CFRunLoopDoSource1() __attribute__((noinline)); - +static Boolean __attribute__((noinline)) __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI -static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls, mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply) -#else -static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopSourceRef rls) + , mach_msg_header_t *msg, CFIndex size, mach_msg_header_t **reply #endif - -{ - + ) { /* DOES CALLOUT */ CHECK_FOR_FORK(); Boolean sourceHandled = false; @@ -2042,16 +2006,12 @@ static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRun __CFRunLoopSourceUnsetSignaled(rls); __CFRunLoopSourceUnlock(rls); __CFRunLoopDebugInfoForRunLoopSource(rls); - void *perform = rls->_context.version1.perform; - void *info = rls->_context.version1.info; - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_SOURCE1 | DBG_FUNC_START, rl, rlm, perform, info); - __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(perform, + __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__(rls->_context.version1.perform, #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI msg, size, reply, #endif - info); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_SOURCE1 | DBG_FUNC_END, rl, rlm, perform, info); - CHECK_FOR_FORK(); + rls->_context.version1.info); + CHECK_FOR_FORK(); sourceHandled = true; } else { if (_LogCFRunLoop) { CFLog(kCFLogLevelDebug, CFSTR("%p (%s) __CFRunLoopDoSource1 rls %p is invalid"), CFRunLoopGetCurrent(), *_CFGetProgname(), rls); } @@ -2060,7 +2020,6 @@ static Boolean __CFRunLoopDoSource1(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRun CFRelease(rls); __CFRunLoopLock(rl); __CFRunLoopModeLock(rlm); - return sourceHandled; } @@ -2136,8 +2095,6 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { if (CFRUNLOOP_NEXT_TIMER_ARMED_ENABLED()) { CFRUNLOOP_NEXT_TIMER_ARMED((unsigned long)(nextSoftDeadline - mach_absolute_time())); } - - cf_trace(KDEBUG_EVENT_CFRL_NEXT_TIMER_ARMED, rl, rlm, (nextSoftDeadline - mach_absolute_time()), 0); #if USE_DISPATCH_SOURCE_FOR_TIMERS // We're going to hand off the range of allowable timer fire date to dispatch and let it fire when appropriate for the system. uint64_t leeway = __CFTSRToNanoseconds(nextHardDeadline - nextSoftDeadline); @@ -2155,13 +2112,13 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { } // Arm the dispatch timer - dispatch_source_set_timer(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway); + _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway); rlm->_dispatchTimerArmed = true; } else { // Cancel the dispatch timer if (rlm->_dispatchTimerArmed) { // Cancel the dispatch timer - dispatch_source_set_timer(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 888); + _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 888); rlm->_dispatchTimerArmed = false; } @@ -2172,7 +2129,7 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { } } #else - dispatch_source_set_timer(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway); + _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, deadline, DISPATCH_TIME_FOREVER, leeway); #endif #else if (rlm->_timerPort) { @@ -2190,7 +2147,7 @@ static void __CFArmNextTimerInMode(CFRunLoopModeRef rlm, CFRunLoopRef rl) { #if USE_DISPATCH_SOURCE_FOR_TIMERS if (rlm->_dispatchTimerArmed) { - dispatch_source_set_timer(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 333); + _dispatch_source_set_runloop_timer_4CF(rlm->_timerSource, DISPATCH_TIME_FOREVER, DISPATCH_TIME_FOREVER, 333); rlm->_dispatchTimerArmed = false; } #endif @@ -2228,9 +2185,6 @@ static void __CFRepositionTimerInMode(CFRunLoopModeRef rlm, CFRunLoopTimerRef rl // mode and rl are locked on entry and exit static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLoopTimerRef rlt) { /* DOES CALLOUT */ - - cf_trace(KDEBUG_EVENT_CFRL_TIMERS_FIRING | DBG_FUNC_START, rl, rlm, rlt, 0); - Boolean timerHandled = false; uint64_t oldFireTSR = 0; @@ -2253,19 +2207,15 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo rlm->_timerSoftDeadline = UINT64_MAX; rlm->_timerHardDeadline = UINT64_MAX; __CFRunLoopTimerUnlock(rlt); - __CFLock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRLock(); oldFireTSR = rlt->_fireTSR; - __CFUnlock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRUnlock(); __CFArmNextTimerInMode(rlm, rl); __CFRunLoopModeUnlock(rlm); __CFRunLoopUnlock(rl); - CFRunLoopTimerCallBack callout = rlt->_callout; - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_TIMER | DBG_FUNC_START, callout, rlt, context_info, 0); - __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(callout, rlt, context_info); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_TIMER | DBG_FUNC_END, callout, rlt, context_info, 0); - + __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__(rlt->_callout, rlt, context_info); CHECK_FOR_FORK(); if (doInvalidate) { CFRunLoopTimerInvalidate(rlt); /* DOES CALLOUT */ @@ -2336,7 +2286,7 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo modes[idx] = (CFTypeRef)__CFRunLoopFindMode(rlt_rl, name, false); CFRelease(name); } - __CFLock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRLock(); rlt->_fireTSR = nextFireTSR; rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTimeIntervalUntilTSR(nextFireTSR); for (CFIndex idx = 0; idx < cnt; idx++) { @@ -2345,35 +2295,29 @@ static Boolean __CFRunLoopDoTimer(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFRunLo __CFRepositionTimerInMode(rlm, rlt, true); } } - __CFUnlock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRUnlock(); for (CFIndex idx = 0; idx < cnt; idx++) { __CFRunLoopModeUnlock((CFRunLoopModeRef)modes[idx]); } CFRelease(rlt_rl); } else { __CFRunLoopTimerUnlock(rlt); - __CFLock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRLock(); rlt->_fireTSR = nextFireTSR; rlt->_nextFireDate = CFAbsoluteTimeGetCurrent() + __CFTimeIntervalUntilTSR(nextFireTSR); - __CFUnlock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRUnlock(); } } } else { __CFRunLoopTimerUnlock(rlt); } CFRelease(rlt); - - cf_trace(KDEBUG_EVENT_CFRL_TIMERS_FIRING | DBG_FUNC_END, rl, rlm, rlt, 0); - return timerHandled; } // rl and rlm are locked on entry and exit static Boolean __CFRunLoopDoTimers(CFRunLoopRef rl, CFRunLoopModeRef rlm, uint64_t limitTSR) { /* DOES CALLOUT */ - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_TIMERS | DBG_FUNC_START, rl, rlm, limitTSR, 0); - Boolean timerHandled = false; CFMutableArrayRef timers = NULL; for (CFIndex idx = 0, cnt = rlm->_timers ? CFArrayGetCount(rlm->_timers) : 0; idx < cnt; idx++) { @@ -2392,11 +2336,7 @@ static Boolean __CFRunLoopDoTimers(CFRunLoopRef rl, CFRunLoopModeRef rlm, uint64 Boolean did = __CFRunLoopDoTimer(rl, rlm, rlt); timerHandled = timerHandled || did; } - if (timers) CFRelease(timers); - - cf_trace(KDEBUG_EVENT_CFRL_IS_DOING_TIMERS | DBG_FUNC_END, rl, rlm, limitTSR, 0); - return timerHandled; } @@ -2421,7 +2361,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #define TIMEOUT_INFINITY (~(mach_msg_timeout_t)0) -static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_port_t *livePort, mach_msg_timeout_t timeout, voucher_mach_msg_state_t *voucherState, voucher_t *voucherCopy, CFRunLoopRef rl, CFRunLoopModeRef rlm) { +static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header_t **buffer, size_t buffer_size, mach_port_t *livePort, mach_msg_timeout_t timeout, voucher_mach_msg_state_t *voucherState, voucher_t *voucherCopy) { Boolean originalBuffer = true; kern_return_t ret = KERN_SUCCESS; for (;;) { /* In that sleep of death what nightmares may come ... */ @@ -2431,18 +2371,9 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header msg->msgh_remote_port = MACH_PORT_NULL; msg->msgh_size = buffer_size; msg->msgh_id = 0; - if (TIMEOUT_INFINITY == timeout) { - CFRUNLOOP_SLEEP(); - cf_trace(KDEBUG_EVENT_CFRL_SLEEP, port, 0, 0, 0); - } else { - CFRUNLOOP_POLL(); - cf_trace(KDEBUG_EVENT_CFRL_POLL, port, 0, 0, 0); - } - cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_END, rl, rlm, port, timeout); - cf_trace(KDEBUG_EVENT_CFRL_IS_WAITING | DBG_FUNC_START, rl, rlm, port, timeout); + if (TIMEOUT_INFINITY == timeout) { CFRUNLOOP_SLEEP(); } else { CFRUNLOOP_POLL(); } ret = mach_msg(msg, MACH_RCV_MSG|(voucherState ? MACH_RCV_VOUCHER : 0)|MACH_RCV_LARGE|((TIMEOUT_INFINITY != timeout) ? MACH_RCV_TIMEOUT : 0)|MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0)|MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AV), 0, msg->msgh_size, port, timeout, MACH_PORT_NULL); - cf_trace(KDEBUG_EVENT_CFRL_IS_WAITING | DBG_FUNC_END, rl, rlm, port, timeout); - cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_START, rl, rlm, port, timeout); + // Take care of all voucher-related work right after mach_msg. // If we don't release the previous voucher we're going to leak it. voucher_mach_msg_revert(*voucherState); @@ -2455,7 +2386,6 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header } CFRUNLOOP_WAKEUP(ret); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP, port, 0, 0, 0); if (MACH_MSG_SUCCESS == ret) { *livePort = msg ? msg->msgh_local_port : MACH_PORT_NULL; return true; @@ -2470,13 +2400,13 @@ static Boolean __CFRunLoopServiceMachPort(mach_port_name_t port, mach_msg_header buffer_size = round_msg(msg->msgh_size + MAX_TRAILER_SIZE); if (originalBuffer) *buffer = NULL; originalBuffer = false; - *buffer = __CFSafelyReallocate(*buffer, buffer_size, NULL); + *buffer = realloc(*buffer, buffer_size); } HALT; return false; } -#elif DEPLOYMENT_TARGET_LINUX +#elif DEPLOYMENT_TARGET_LINUX && !TARGET_OS_CYGWIN #define TIMEOUT_INFINITY UINT64_MAX @@ -2627,7 +2557,7 @@ struct __timeout_context { dispatch_source_t ds; #endif CFRunLoopRef rl; - _Atomic(uint64_t) termTSR; + uint64_t termTSR; }; static void __CFRunLoopTimeoutCancel(void *arg) { @@ -2643,9 +2573,7 @@ static void __CFRunLoopTimeout(void *arg) { struct __timeout_context *context = (struct __timeout_context *)arg; context->termTSR = 0ULL; CFRUNLOOP_WAKEUP_FOR_TIMEOUT(); - CFRunLoopRef rl = context->rl; - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_TIMEOUT, rl, 0, 0, 0); - CFRunLoopWakeUp(rl); + CFRunLoopWakeUp(context->rl); // The interval is DISPATCH_TIME_FOREVER, so this won't fire again } @@ -2727,20 +2655,15 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter __CFRunLoopUnsetIgnoreWakeUps(rl); - if (rlm->_observerMask & kCFRunLoopBeforeTimers) { - __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers); - } - - if (rlm->_observerMask & kCFRunLoopBeforeSources) { - __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources); - } + if (rlm->_observerMask & kCFRunLoopBeforeTimers) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers); + if (rlm->_observerMask & kCFRunLoopBeforeSources) __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources); __CFRunLoopDoBlocks(rl, rlm); Boolean sourceHandledThisLoop = __CFRunLoopDoSources0(rl, rlm, stopAfterHandle); if (sourceHandledThisLoop) { __CFRunLoopDoBlocks(rl, rlm); - } + } Boolean poll = sourceHandledThisLoop || (0ULL == timeout_context->termTSR); @@ -2748,7 +2671,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter if (MACH_PORT_NULL != dispatchPort && !didDispatchPortLastTime) { #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI msg = (mach_msg_header_t *)msg_buffer; - if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL, rl, rlm)) { + if (__CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0, &voucherState, NULL)) { goto handle_msg; } #elif DEPLOYMENT_TARGET_LINUX && !TARGET_OS_CYGWIN @@ -2786,7 +2709,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter do { msg = (mach_msg_header_t *)msg_buffer; - __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy, rl, rlm); + __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy); if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) { // Drain the internal queue. If one of the callout blocks sets the timerFired flag, break out and service the timer. @@ -2805,7 +2728,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter } while (1); #else msg = (mach_msg_header_t *)msg_buffer; - __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy, rl, rlm); + __CFRunLoopServiceMachPort(waitSet, &msg, sizeof(msg_buffer), &livePort, poll ? 0 : TIMEOUT_INFINITY, &voucherState, &voucherCopy); #endif @@ -2877,11 +2800,9 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #endif if (MACH_PORT_NULL == livePort) { CFRUNLOOP_WAKEUP_FOR_NOTHING(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_NOTHING, rl, rlm, livePort, 0); // handle nothing } else if (livePort == rl->_wakeUpPort) { CFRUNLOOP_WAKEUP_FOR_WAKEUP(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_WAKEUP, rl, rlm, livePort, 0); // do nothing on Mac OS #if DEPLOYMENT_TARGET_WINDOWS // Always reset the wake up port, or risk spinning forever @@ -2891,7 +2812,6 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #if USE_DISPATCH_SOURCE_FOR_TIMERS else if (modeQueuePort != MACH_PORT_NULL && livePort == modeQueuePort) { CFRUNLOOP_WAKEUP_FOR_TIMER(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_TIMER, rl, rlm, livePort, 0); if (!__CFRunLoopDoTimers(rl, rlm, mach_absolute_time())) { // Re-arm the next timer, because we apparently fired early __CFArmNextTimerInMode(rlm, rl); @@ -2909,22 +2829,16 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter } } #endif - - /* --- DISPATCHES --- */ - #if __HAS_DISPATCH__ else if (livePort == dispatchPort) { CFRUNLOOP_WAKEUP_FOR_DISPATCH(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_DISPATCH, rl, rlm, livePort, 0); __CFRunLoopModeUnlock(rlm); __CFRunLoopUnlock(rl); _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)6, NULL); #if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX void *msg = 0; #endif - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_DISPATCH | DBG_FUNC_START, rl, rlm, msg, livePort); __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__(msg); - cf_trace(KDEBUG_EVENT_CFRL_IS_CALLING_DISPATCH | DBG_FUNC_END, rl, rlm, msg, livePort); _CFSetTSD(__CFTSDKeyIsInGCDMainQ, (void *)0, NULL); __CFRunLoopLock(rl); __CFRunLoopModeLock(rlm); @@ -2932,12 +2846,8 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter didDispatchPortLastTime = true; } #endif - - /* --- SOURCE1S --- */ - else { CFRUNLOOP_WAKEUP_FOR_SOURCE(); - cf_trace(KDEBUG_EVENT_CFRL_WAKEUP_FOR_SOURCE, rl, rlm, 0, 0); // Despite the name, this works for windows handles as well CFRunLoopSourceRef rls = __CFRunLoopModeFindSourceForMachPort(rl, rlm, livePort); if (rls) { @@ -2951,14 +2861,9 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter #elif DEPLOYMENT_TARGET_WINDOWS || (DEPLOYMENT_TARGET_LINUX && !TARGET_OS_CYGWIN) sourceHandledThisLoop = __CFRunLoopDoSource1(rl, rlm, rls) || sourceHandledThisLoop; #endif - } else { - os_log_error(_CFOSLog(), "__CFRunLoopModeFindSourceForMachPort returned NULL for mode '%@' livePort: %u", rlm->_name, livePort); - } + } - } - - /* --- BLOCKS --- */ - + } #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI if (msg && msg != (mach_msg_header_t *)msg_buffer) free(msg); #endif @@ -2989,7 +2894,7 @@ static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInter { free(timeout_context); } - + return retVal; } @@ -3020,14 +2925,12 @@ SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterva int32_t result = kCFRunLoopRunFinished; if (currentMode->_observerMask & kCFRunLoopEntry ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry); - cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_START, rl, currentMode, seconds, previousMode); - result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode); - cf_trace(KDEBUG_EVENT_CFRL_RUN | DBG_FUNC_END, rl, currentMode, seconds, previousMode); - if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); + result = __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode); + if (currentMode->_observerMask & kCFRunLoopExit ) __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); __CFRunLoopModeUnlock(currentMode); __CFRunLoopPopPerRunData(rl, previousPerRun); - rl->_currentMode = previousMode; + rl->_currentMode = previousMode; __CFRunLoopUnlock(rl); return result; } @@ -3066,15 +2969,6 @@ Boolean CFRunLoopIsWaiting(CFRunLoopRef rl) { void CFRunLoopWakeUp(CFRunLoopRef rl) { CHECK_FOR_FORK(); - if (__CFMainThreadHasExited && rl == CFRunLoopGetMain()) { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - os_log_error(_CFOSLog(), "Attempting to wake up main runloop, but the main thread as exited. This message will only log once. Break on _CFRunLoopError_MainThreadHasExited to debug."); - }); - _CFRunLoopError_MainThreadHasExited(); - return; - } - // This lock is crucial to ignorable wakeups, do not remove it. __CFRunLoopLock(rl); if (__CFRunLoopIsIgnoringWakeUps(rl)) { @@ -3138,7 +3032,7 @@ void CFRunLoopPerformBlock(CFRunLoopRef rl, CFTypeRef mode, void (^block)(void)) if (__CFMainThreadHasExited && rl == CFRunLoopGetMain()) { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - os_log_error(_CFOSLog(), "Attempting to perform block on main runloop, but the main thread as exited. This message will only log once. Break on _CFRunLoopError_MainThreadHasExited to debug."); + CFLog(kCFLogLevelError, CFSTR("Attempting to perform block on main runloop, but the main thread as exited. This message will only log once. Break on _CFRunLoopError_MainThreadHasExited to debug.")); }); _CFRunLoopError_MainThreadHasExited(); return; @@ -3572,9 +3466,9 @@ void CFRunLoopAddTimer(CFRunLoopRef rl, CFRunLoopTimerRef rlt, CFStringRef modeN } CFSetAddValue(rlt->_rlModes, rlm->_name); __CFRunLoopTimerUnlock(rlt); - __CFLock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRLock(); __CFRepositionTimerInMode(rlm, rlt, false); - __CFUnlock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRUnlock(); if (!_CFExecutableLinkedOnOrAfter(CFSystemVersionLion)) { // Normally we don't do this on behalf of clients, but for // backwards compatibility due to the change in timer handling... @@ -3723,7 +3617,7 @@ CFRunLoopSourceRef CFRunLoopSourceCreate(CFAllocatorRef allocator, CFIndex order __CFSetValid(memory); __CFRunLoopSourceUnsetSignaled(memory); __CFRunLoopLockInit(&memory->_lock); - memory->_signaled = false; + memory->_bits = 0; memory->_order = order; memory->_runLoops = NULL; size = 0; @@ -4171,9 +4065,11 @@ CFAbsoluteTime CFRunLoopTimerGetNextFireDate(CFRunLoopTimerRef rlt) { __CFGenericValidateType(rlt, CFRunLoopTimerGetTypeID()); CFAbsoluteTime at = 0.0; __CFRunLoopTimerLock(rlt); + __CFRunLoopTimerFireTSRLock(); if (__CFIsValid(rlt)) { at = rlt->_nextFireDate; } + __CFRunLoopTimerFireTSRUnlock(); __CFRunLoopTimerUnlock(rlt); return at; } @@ -4212,7 +4108,7 @@ void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDat modes[idx] = __CFRunLoopFindMode(rl, name, false); CFRelease(name); } - __CFLock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRLock(); rlt->_fireTSR = nextFireTSR; rlt->_nextFireDate = fireDate; for (CFIndex idx = 0; idx < cnt; idx++) { @@ -4221,7 +4117,7 @@ void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDat __CFRepositionTimerInMode(rlm, rlt, true); } } - __CFUnlock(&rl->_timerTSRLock); + __CFRunLoopTimerFireTSRUnlock(); for (CFIndex idx = 0; idx < cnt; idx++) { __CFRunLoopModeUnlock((CFRunLoopModeRef)modes[idx]); } @@ -4234,8 +4130,10 @@ void CFRunLoopTimerSetNextFireDate(CFRunLoopTimerRef rlt, CFAbsoluteTime fireDat if (!_CFRunLoopIsCurrent(rl)) { CFRunLoopWakeUp(rl); } CFRelease(rl); } else { + __CFRunLoopTimerFireTSRLock(); rlt->_fireTSR = nextFireTSR; rlt->_nextFireDate = fireDate; + __CFRunLoopTimerFireTSRUnlock(); __CFRunLoopTimerUnlock(rlt); } } diff --git a/CoreFoundation/RunLoop.subproj/CFRunLoop.h b/CoreFoundation/RunLoop.subproj/CFRunLoop.h index 9fef4fa178..83dd9ec3a4 100644 --- a/CoreFoundation/RunLoop.subproj/CFRunLoop.h +++ b/CoreFoundation/RunLoop.subproj/CFRunLoop.h @@ -1,7 +1,7 @@ /* CFRunLoop.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -73,7 +73,7 @@ CF_EXPORT void CFRunLoopWakeUp(CFRunLoopRef rl); CF_EXPORT void CFRunLoopStop(CFRunLoopRef rl); #if __BLOCKS__ -CF_EXPORT void CFRunLoopPerformBlock(CFRunLoopRef rl, CFTypeRef mode, void (^block)(void)) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT void CFRunLoopPerformBlock(CFRunLoopRef rl, CFTypeRef mode, void (^block)(void)) CF_AVAILABLE(10_6, 4_0); #endif CF_EXPORT Boolean CFRunLoopContainsSource(CFRunLoopRef rl, CFRunLoopSourceRef source, CFRunLoopMode mode); @@ -142,7 +142,7 @@ CF_EXPORT CFTypeID CFRunLoopObserverGetTypeID(void); CF_EXPORT CFRunLoopObserverRef CFRunLoopObserverCreate(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, CFRunLoopObserverCallBack callout, CFRunLoopObserverContext *context); #if __BLOCKS__ -CF_EXPORT CFRunLoopObserverRef CFRunLoopObserverCreateWithHandler(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, void (^block) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +CF_EXPORT CFRunLoopObserverRef CFRunLoopObserverCreateWithHandler(CFAllocatorRef allocator, CFOptionFlags activities, Boolean repeats, CFIndex order, void (^block) (CFRunLoopObserverRef observer, CFRunLoopActivity activity)) CF_AVAILABLE(10_7, 5_0); #endif CF_EXPORT CFOptionFlags CFRunLoopObserverGetActivities(CFRunLoopObserverRef observer); @@ -166,7 +166,7 @@ CF_EXPORT CFTypeID CFRunLoopTimerGetTypeID(void); CF_EXPORT CFRunLoopTimerRef CFRunLoopTimerCreate(CFAllocatorRef allocator, CFAbsoluteTime fireDate, CFTimeInterval interval, CFOptionFlags flags, CFIndex order, CFRunLoopTimerCallBack callout, CFRunLoopTimerContext *context); #if __BLOCKS__ -CF_EXPORT CFRunLoopTimerRef CFRunLoopTimerCreateWithHandler(CFAllocatorRef allocator, CFAbsoluteTime fireDate, CFTimeInterval interval, CFOptionFlags flags, CFIndex order, void (^block) (CFRunLoopTimerRef timer)) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +CF_EXPORT CFRunLoopTimerRef CFRunLoopTimerCreateWithHandler(CFAllocatorRef allocator, CFAbsoluteTime fireDate, CFTimeInterval interval, CFOptionFlags flags, CFIndex order, void (^block) (CFRunLoopTimerRef timer)) CF_AVAILABLE(10_7, 5_0); #endif CF_EXPORT CFAbsoluteTime CFRunLoopTimerGetNextFireDate(CFRunLoopTimerRef timer); @@ -180,8 +180,8 @@ CF_EXPORT void CFRunLoopTimerGetContext(CFRunLoopTimerRef timer, CFRunLoopTimerC // Setting a tolerance for a timer allows it to fire later than the scheduled fire date, improving the ability of the system to optimize for increased power savings and responsiveness. The timer may fire at any time between its scheduled fire date and the scheduled fire date plus the tolerance. The timer will not fire before the scheduled fire date. For repeating timers, the next fire date is calculated from the original fire date regardless of tolerance applied at individual fire times, to avoid drift. The default value is zero, which means no additional tolerance is applied. The system reserves the right to apply a small amount of tolerance to certain timers regardless of the value of this property. // As the user of the timer, you will have the best idea of what an appropriate tolerance for a timer may be. A general rule of thumb, though, is to set the tolerance to at least 10% of the interval, for a repeating timer. Even a small amount of tolerance will have a significant positive impact on the power usage of your application. The system may put a maximum value of the tolerance. -CF_EXPORT CFTimeInterval CFRunLoopTimerGetTolerance(CFRunLoopTimerRef timer) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); -CF_EXPORT void CFRunLoopTimerSetTolerance(CFRunLoopTimerRef timer, CFTimeInterval tolerance) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +CF_EXPORT CFTimeInterval CFRunLoopTimerGetTolerance(CFRunLoopTimerRef timer) CF_AVAILABLE(10_9, 7_0); +CF_EXPORT void CFRunLoopTimerSetTolerance(CFRunLoopTimerRef timer, CFTimeInterval tolerance) CF_AVAILABLE(10_9, 7_0); CF_EXTERN_C_END CF_IMPLICIT_BRIDGING_DISABLED diff --git a/CoreFoundation/RunLoop.subproj/CFSocket.c b/CoreFoundation/RunLoop.subproj/CFSocket.c index 33a57cf69a..79b0f0edae 100644 --- a/CoreFoundation/RunLoop.subproj/CFSocket.c +++ b/CoreFoundation/RunLoop.subproj/CFSocket.c @@ -1,7 +1,7 @@ /* CFSocket.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -1210,51 +1210,51 @@ struct __CFSocket { /* Of this, bits 0-1 are used for the read callback type. */ CF_INLINE Boolean __CFSocketIsWriteSignalled(CFSocketRef s) { - return __CFRuntimeGetFlag(s, 6); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6); } CF_INLINE void __CFSocketSetWriteSignalled(CFSocketRef s) { - __CFRuntimeSetFlag(s, 6, true); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6, 1); } CF_INLINE void __CFSocketUnsetWriteSignalled(CFSocketRef s) { - __CFRuntimeSetFlag(s, 6, false); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 6, 6, 0); } CF_INLINE Boolean __CFSocketIsReadSignalled(CFSocketRef s) { - return __CFRuntimeGetFlag(s, 5); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5); } CF_INLINE void __CFSocketSetReadSignalled(CFSocketRef s) { - __CFRuntimeSetFlag(s, 5, true); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5, 1); } CF_INLINE void __CFSocketUnsetReadSignalled(CFSocketRef s) { - __CFRuntimeSetFlag(s, 5, false); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 5, 5, 0); } CF_INLINE Boolean __CFSocketIsValid(CFSocketRef s) { - return __CFRuntimeGetFlag(s, 4); + return (Boolean)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4); } CF_INLINE void __CFSocketSetValid(CFSocketRef s) { - __CFRuntimeSetFlag(s, 4, true); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4, 1); } CF_INLINE void __CFSocketUnsetValid(CFSocketRef s) { - __CFRuntimeSetFlag(s, 4, false); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 4, 4, 0); } CF_INLINE uint8_t __CFSocketCallBackTypes(CFSocketRef s) { - return (uint8_t)__CFRuntimeGetValue(s, 3, 0); + return (uint8_t)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 3, 0); } CF_INLINE uint8_t __CFSocketReadCallBackType(CFSocketRef s) { - return (uint8_t)__CFRuntimeGetValue(s, 1, 0); + return (uint8_t)__CFBitfieldGetValue(((const CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 1, 0); } CF_INLINE void __CFSocketSetCallBackTypes(CFSocketRef s, uint8_t types) { - __CFRuntimeSetValue(s, 3, 0, types & 0xF); + __CFBitfieldSetValue(((CFRuntimeBase *)s)->_cfinfo[CF_INFO_BITS], 3, 0, types & 0xF); } CF_INLINE void __CFSocketLock(CFSocketRef s) { @@ -2192,8 +2192,8 @@ static void *__CFSocketManager(void * arg) maxnrfds = __CFMax(rfds, wfds); if (maxnrfds > fdentries * (int)NFDBITS) { fdentries = (maxnrfds + NFDBITS - 1) / NFDBITS; - writefds = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, writefds, fdentries * sizeof(fd_mask), 0, NULL); - readfds = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, readfds, fdentries * sizeof(fd_mask), 0, NULL); + writefds = (fd_set *)CFAllocatorReallocate(kCFAllocatorSystemDefault, writefds, fdentries * sizeof(fd_mask), 0); + readfds = (fd_set *)CFAllocatorReallocate(kCFAllocatorSystemDefault, readfds, fdentries * sizeof(fd_mask), 0); } memset(writefds, 0, fdentries * sizeof(fd_mask)); memset(readfds, 0, fdentries * sizeof(fd_mask)); diff --git a/CoreFoundation/RunLoop.subproj/CFSocket.h b/CoreFoundation/RunLoop.subproj/CFSocket.h index 462d6b1089..c6b8f1fd6c 100644 --- a/CoreFoundation/RunLoop.subproj/CFSocket.h +++ b/CoreFoundation/RunLoop.subproj/CFSocket.h @@ -1,7 +1,7 @@ /* CFSocket.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -125,7 +125,7 @@ CF_ENUM(CFOptionFlags) { kCFSocketAutomaticallyReenableAcceptCallBack = 2, kCFSocketAutomaticallyReenableDataCallBack = 3, kCFSocketAutomaticallyReenableWriteCallBack = 8, - kCFSocketLeaveErrors API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 64, + kCFSocketLeaveErrors CF_ENUM_AVAILABLE(10_5, 2_0) = 64, kCFSocketCloseOnInvalidate = 128 }; diff --git a/CoreFoundation/Stream.subproj/CFConcreteStreams.c b/CoreFoundation/Stream.subproj/CFConcreteStreams.c index b86ec5dff4..8068360eac 100644 --- a/CoreFoundation/Stream.subproj/CFConcreteStreams.c +++ b/CoreFoundation/Stream.subproj/CFConcreteStreams.c @@ -1,7 +1,7 @@ /* CFConcreteStreams.c - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -49,7 +49,7 @@ typedef struct { CONST_STRING_DECL(kCFStreamPropertyFileCurrentOffset, "kCFStreamPropertyFileCurrentOffset"); -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI +#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI CONST_STRING_DECL(_kCFStreamPropertyFileNativeHandle, "_kCFStreamPropertyFileNativeHandle"); #endif CONST_STRING_DECL(_kCFStreamPropertyHTTPTrailer, "_kCFStreamPropertyHTTPTrailer"); @@ -58,25 +58,8 @@ CONST_STRING_DECL(_kCFStreamPropertyHTTPTrailer, "_kCFStreamPropertyHTTPTrailer" extern void _CFFileDescriptorInduceFakeReadCallBack(CFFileDescriptorRef); static void fileCallBack(CFFileDescriptorRef f, CFOptionFlags callBackTypes, void *info); -static void *_fs_retain(void *info) -{ - struct _CFStream *s = (struct _CFStream*)info; - if (s) { - CFRetain(s); - } - return s; -} - -static void _fs_release(void *info) -{ - struct _CFStream *s = (struct _CFStream*)info; - if (s) { - CFRelease(s); - } -} - static void constructCFFD(_CFFileStreamContext *fileStream, Boolean forRead, struct _CFStream *stream) { - CFFileDescriptorContext context = {0, stream, _fs_retain, _fs_release, (void *)CFCopyDescription}; + CFFileDescriptorContext context = {0, stream, NULL, NULL, (void *)CFCopyDescription}; CFFileDescriptorRef cffd = CFFileDescriptorCreate(CFGetAllocator(stream), fileStream->fd, false, fileCallBack, &context); CFFileDescriptorEnableCallBacks(cffd, forRead ? kCFFileDescriptorReadCallBack : kCFFileDescriptorWriteCallBack); if (fileStream->rlInfo.rlArray) { @@ -116,9 +99,9 @@ static Boolean constructFD(_CFFileStreamContext *fileStream, CFStreamError *erro do { #if DEPLOYMENT_TARGET_WINDOWS - fileStream->fd = _wopen(path, flags, 0666); + fileStream->fd = _wopen(path, flags, 0666); #else - fileStream->fd = open((const char *)path, flags, 0666); + fileStream->fd = open((const char *)path, flags, 0666); #endif if (fileStream->fd < 0) break; @@ -329,21 +312,14 @@ static void fileClose(struct _CFStream *stream, void *info) { #ifdef REAL_FILE_SCHEDULING static void fileCallBack(CFFileDescriptorRef f, CFOptionFlags type, void *info) { struct _CFStream *stream = (struct _CFStream *)info; - - if (stream == NULL) { - return; - } - Boolean isReadStream = (CFGetTypeID(stream) == CFReadStreamGetTypeID()); _CFFileStreamContext *fileStream = isReadStream ? CFReadStreamGetInfoPointer((CFReadStreamRef)stream) : CFWriteStreamGetInfoPointer((CFWriteStreamRef)stream); - if (fileStream) { - if (type == kCFFileDescriptorWriteCallBack) { + if (type == kCFFileDescriptorWriteCallBack) { __CFBitSet(fileStream->flags, SCHEDULE_AFTER_WRITE); CFWriteStreamSignalEvent((CFWriteStreamRef)stream, kCFStreamEventCanAcceptBytes, NULL); - } else { + } else { __CFBitSet(fileStream->flags, SCHEDULE_AFTER_READ); CFReadStreamSignalEvent((CFReadStreamRef)stream, kCFStreamEventHasBytesAvailable, NULL); - } } } #endif @@ -442,7 +418,7 @@ static CFTypeRef fileCopyProperty(struct _CFStream *stream, CFStringRef property if (fileStream->offset != -1) { result = CFNumberCreate(CFGetAllocator((CFTypeRef)stream), kCFNumberSInt64Type, &(fileStream->offset)); } -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI +#if DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI } else if (CFEqual(propertyName, _kCFStreamPropertyFileNativeHandle)) { int fd = fileStream->fd; if (fd != -1) { @@ -889,5 +865,10 @@ CF_EXPORT CFWriteStreamRef CFWriteStreamCreateWithAllocatedBuffers(CFAllocatorRe return (CFWriteStreamRef)_CFStreamCreateWithConstantCallbacks(alloc, &ctxt, (struct _CFStreamCallBacks *)(&writeDataCallBacks), FALSE); } +CF_SWIFT_EXPORT _Nullable CFErrorRef _CFReadStreamCopyError(CFReadStreamRef stream) { return CFReadStreamCopyError(stream); } + +CF_SWIFT_EXPORT _Nullable CFErrorRef _CFWriteStreamCopyError(CFWriteStreamRef stream) { return CFWriteStreamCopyError(stream); } + + #undef BUF_SIZE diff --git a/CoreFoundation/Stream.subproj/CFSocketStream.c b/CoreFoundation/Stream.subproj/CFSocketStream.c index 60c9191195..5948057eae 100644 --- a/CoreFoundation/Stream.subproj/CFSocketStream.c +++ b/CoreFoundation/Stream.subproj/CFSocketStream.c @@ -1,7 +1,7 @@ /* CFSocketStream.c - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStream.c b/CoreFoundation/Stream.subproj/CFStream.c index 5fffb592fa..b8e3cd7cbd 100644 --- a/CoreFoundation/Stream.subproj/CFStream.c +++ b/CoreFoundation/Stream.subproj/CFStream.c @@ -1,7 +1,7 @@ /* CFStream.c - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStream.h b/CoreFoundation/Stream.subproj/CFStream.h index 274ad9095d..6246a12528 100644 --- a/CoreFoundation/Stream.subproj/CFStream.h +++ b/CoreFoundation/Stream.subproj/CFStream.h @@ -1,7 +1,7 @@ /* CFStream.h - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -132,9 +132,9 @@ CFStreamStatus CFWriteStreamGetStatus(CFWriteStreamRef stream); /* Returns NULL if no error has occurred; otherwise returns the error. */ CF_EXPORT -CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFErrorRef CFReadStreamCopyError(CFReadStreamRef stream) CF_AVAILABLE(10_5, 2_0); CF_EXPORT -CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFErrorRef CFWriteStreamCopyError(CFWriteStreamRef stream) CF_AVAILABLE(10_5, 2_0); /* Returns success/failure. Opening a stream causes it to reserve all the system resources it requires. If the stream can open non-blocking, this will always @@ -254,10 +254,10 @@ void CFWriteStreamUnscheduleFromRunLoop(CFWriteStreamRef stream, CFRunLoopRef ru * with a runloop will disassociate the stream from any existing dispatch queue. */ CF_EXPORT -void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +void CFReadStreamSetDispatchQueue(CFReadStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0); CF_EXPORT -void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q) CF_AVAILABLE(10_9, 7_0); /* * Returns the previously set dispatch queue with an incremented retain count. @@ -265,10 +265,10 @@ void CFWriteStreamSetDispatchQueue(CFWriteStreamRef stream, dispatch_queue_t q) * scheduled on a runloop subsequent to it having had a dispatch queue set. */ CF_EXPORT -dispatch_queue_t CFReadStreamCopyDispatchQueue(CFReadStreamRef stream) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +dispatch_queue_t CFReadStreamCopyDispatchQueue(CFReadStreamRef stream) CF_AVAILABLE(10_9, 7_0); CF_EXPORT -dispatch_queue_t CFWriteStreamCopyDispatchQueue(CFWriteStreamRef stream) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +dispatch_queue_t CFWriteStreamCopyDispatchQueue(CFWriteStreamRef stream) CF_AVAILABLE(10_9, 7_0); /* The following API is deprecated starting in 10.5; please use CFRead/WriteStreamCopyError(), above, instead */ diff --git a/CoreFoundation/Stream.subproj/CFStreamAbstract.h b/CoreFoundation/Stream.subproj/CFStreamAbstract.h index f19de2ef33..4ccec0c676 100644 --- a/CoreFoundation/Stream.subproj/CFStreamAbstract.h +++ b/CoreFoundation/Stream.subproj/CFStreamAbstract.h @@ -1,7 +1,7 @@ /* CFStreamAbstract.h - Copyright (c) 2000-2017, Apple Inc.and the Swift project authors + Copyright (c) 2000-2016, Apple Inc.and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStreamInternal.h b/CoreFoundation/Stream.subproj/CFStreamInternal.h index ec1f521f0d..c0ff804784 100644 --- a/CoreFoundation/Stream.subproj/CFStreamInternal.h +++ b/CoreFoundation/Stream.subproj/CFStreamInternal.h @@ -1,7 +1,7 @@ /* CFStreamInternal.h - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/Stream.subproj/CFStreamPriv.h b/CoreFoundation/Stream.subproj/CFStreamPriv.h index 6633cc59d4..b71bb8ad98 100644 --- a/CoreFoundation/Stream.subproj/CFStreamPriv.h +++ b/CoreFoundation/Stream.subproj/CFStreamPriv.h @@ -1,7 +1,7 @@ /* CFStreamPriv.h - Copyright (c) 2000-2017, Apple Inc. and the Swift project authors + Copyright (c) 2000-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -114,7 +114,7 @@ CF_EXTERN_C_END * 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 API_AVAILABLE(macosx(10.12.4), ios(5.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFStreamPropertyFileNativeHandle CF_AVAILABLE_IOS(5_0); /* * SPI: The _kCFStreamPropertyHTTPTrailer property is a dictionary of HTTP headers & values that the caller diff --git a/CoreFoundation/String.subproj/CFAttributedString.c b/CoreFoundation/String.subproj/CFAttributedString.c index 3241600faf..61306e8fa2 100644 --- a/CoreFoundation/String.subproj/CFAttributedString.c +++ b/CoreFoundation/String.subproj/CFAttributedString.c @@ -6,10 +6,10 @@ // See http://swift.org/LICENSE.txt for license information // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // + + /* CFAttributedString.c - Copyright (c) 2004-2017, Apple Inc. All rights reserved. - Original Author: Ali Ozer - Responsibility: Ali Ozer + Copyright (c) 2004-2015, Apple Inc. All rights reserved. */ #include @@ -18,7 +18,6 @@ #include #include "CFInternal.h" - struct __CFAttributedString { CFRuntimeBase base; CFStringRef string; @@ -28,22 +27,20 @@ struct __CFAttributedString { /* Mutability is determined by a bit in the CF base. Mutable if bit 0 is 0. So by default freshly created attributed strings are mutable. Don't change mutability once the object has been created and initialized! */ CF_INLINE Boolean __CFAttributedStringIsMutable(CFAttributedStringRef attrStr) { - // The first bit is 'immutable', so flip the sense - return !__CFRuntimeGetFlag(attrStr, 0); + return __CFBitfieldGetValue(((const CFRuntimeBase *)attrStr)->_cfinfo[CF_INFO_BITS], 0, 0) ? false : true; } CF_INLINE void __CFAttributedStringSetMutable(CFAttributedStringRef attrStr, Boolean flag) { - // The first bit is 'immutable', so flip the sense - __CFRuntimeSetFlag(attrStr, 0, !flag); + __CFBitfieldSetValue(((CFRuntimeBase *)attrStr)->_cfinfo[CF_INFO_BITS], 0, 0, (flag ? 0 : 1)); } /* Assertions */ #define __CFAssertIsAttributedString(cf) __CFGenericValidateType(cf, CFAttributedStringGetTypeID()) -#define __CFAssertIndexIsInBounds(cf, idx) CFAssert3((idx) >= 0 && (idx) < CFAttributedStringGetLength(cf), __kCFLogAssertion, "%s(): index %ld out of bounds (length %ld)", __PRETTY_FUNCTION__, idx, CFAttributedStringGetLength(cf)) -#define __CFAssertRangeIsInBounds(cf, idx, count) CFAssert4((idx) >= 0 && (idx + count) <= CFAttributedStringGetLength(cf), __kCFLogAssertion, "%s(): range %ld,%ld out of bounds (length %ld)", __PRETTY_FUNCTION__, idx, count, CFAttributedStringGetLength(cf)) -#define __CFAssertRangeIsWithinLength(len, idx, count) CFAssert4((idx) >= 0 && (idx + count) <= len, __kCFLogAssertion, "%s(): range %ld,%ld out of bounds (length %ld)", __PRETTY_FUNCTION__, idx, count, len) +#define __CFAssertIndexIsInBounds(cf, idx) CFAssert3((idx) >= 0 && (idx) < CFAttributedStringGetLength(cf), __kCFLogAssertion, "%s(): index %d out of bounds (length %d)", __PRETTY_FUNCTION__, idx, CFAttributedStringGetLength(cf)) +#define __CFAssertRangeIsInBounds(cf, idx, count) CFAssert4((idx) >= 0 && (idx + count) <= CFAttributedStringGetLength(cf), __kCFLogAssertion, "%s(): range %d,%d out of bounds (length %d)", __PRETTY_FUNCTION__, idx, count, CFAttributedStringGetLength(cf)) +#define __CFAssertRangeIsWithinLength(len, idx, count) CFAssert4((idx) >= 0 && (idx + count) <= len, __kCFLogAssertion, "%s(): range %d,%d out of bounds (length %d)", __PRETTY_FUNCTION__, idx, count, len) #define __CFAssertIsAttributedStringAndMutable(cf) CFAssert1((CFGetTypeID(cf) == CFAttributedStringGetTypeID()) && __CFAttributedStringIsMutable(cf), __kCFLogAssertion, "%s(): argument not a CFMutableAttributedString", __PRETTY_FUNCTION__) @@ -494,29 +491,29 @@ void CFAttributedStringSetAttributes(CFMutableAttributedStringRef attrStr, CFRan CFIndex numAdditionalItems = CFDictionaryGetCount(replacementAttrs); if (numAdditionalItems) { // Extract the new keys and values so we don't do it over and over for each range - createLocalArray(additionalKeys, numAdditionalItems); - createLocalArray(additionalValues, numAdditionalItems); + createLocalArray(additionalKeys, numAdditionalItems); + createLocalArray(additionalValues, numAdditionalItems); CFDictionaryGetKeysAndValues(replacementAttrs, additionalKeys, additionalValues); - - // CFAttributedStringBeginEditing(attrStr); + + // CFAttributedStringBeginEditing(attrStr); while (range.length) { CFRange effectiveRange; CFMutableDictionaryRef attrs = (CFMutableDictionaryRef)CFRunArrayGetValueAtIndex(attrStr->attributeArray, range.location, &effectiveRange, NULL); - // Intersect effectiveRange and range - if (effectiveRange.location < range.location) { - effectiveRange.length -= (range.location - effectiveRange.location); - effectiveRange.location = range.location; - } - if (effectiveRange.length > range.length) effectiveRange.length = range.length; - // We need to make a new copy - attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); - __CFDictionaryAddMultiple(attrs, additionalKeys, additionalValues, numAdditionalItems); - CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); - CFRelease(attrs); + // Intersect effectiveRange and range + if (effectiveRange.location < range.location) { + effectiveRange.length -= (range.location - effectiveRange.location); + effectiveRange.location = range.location; + } + if (effectiveRange.length > range.length) effectiveRange.length = range.length; + // We need to make a new copy + attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); + __CFDictionaryAddMultiple(attrs, additionalKeys, additionalValues, numAdditionalItems); + CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); + CFRelease(attrs); range.length -= effectiveRange.length; range.location += effectiveRange.length; } - // CFAttributedStringEndEditing(attrStr); + // CFAttributedStringEndEditing(attrStr); freeLocalArray(additionalKeys); freeLocalArray(additionalValues); @@ -534,21 +531,21 @@ void CFAttributedStringSetAttribute(CFMutableAttributedStringRef attrStr, CFRang CFRange effectiveRange; // effectiveRange.location returned here may be equal to or smaller than range.location CFMutableDictionaryRef attrs = (CFMutableDictionaryRef)CFRunArrayGetValueAtIndex(attrStr->attributeArray, range.location, &effectiveRange, NULL); - // Intersect effectiveRange and range - if (effectiveRange.location < range.location) { - effectiveRange.length -= (range.location - effectiveRange.location); - effectiveRange.location = range.location; - } - if (effectiveRange.length > range.length) effectiveRange.length = range.length; - // First check to see if the same value already exists; this will avoid a copy - CFTypeRef existingValue = CFDictionaryGetValue(attrs, attrName); - if (!existingValue || !CFEqual(existingValue, value)) { - // We need to make a new copy - attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); - CFDictionarySetValue(attrs, attrName, value); - CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); - CFRelease(attrs); - } + // Intersect effectiveRange and range + if (effectiveRange.location < range.location) { + effectiveRange.length -= (range.location - effectiveRange.location); + effectiveRange.location = range.location; + } + if (effectiveRange.length > range.length) effectiveRange.length = range.length; + // First check to see if the same value already exists; this will avoid a copy + CFTypeRef existingValue = CFDictionaryGetValue(attrs, attrName); + if (!existingValue || !CFEqual(existingValue, value)) { + // We need to make a new copy + attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); + CFDictionarySetValue(attrs, attrName, value); + CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); + CFRelease(attrs); + } range.length -= effectiveRange.length; range.location += effectiveRange.length; } @@ -564,20 +561,20 @@ void CFAttributedStringRemoveAttribute(CFMutableAttributedStringRef attrStr, CFR while (range.length) { CFRange effectiveRange; CFMutableDictionaryRef attrs = (CFMutableDictionaryRef)CFRunArrayGetValueAtIndex(attrStr->attributeArray, range.location, &effectiveRange, NULL); - // Intersect effectiveRange and range - if (effectiveRange.location < range.location) { - effectiveRange.length -= (range.location - effectiveRange.location); - effectiveRange.location = range.location; - } - if (effectiveRange.length > range.length) effectiveRange.length = range.length; - // First check to see if the value is not there; this will avoid a copy - if (CFDictionaryContainsKey(attrs, attrName)) { - // We need to make a new copy - attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); - CFDictionaryRemoveValue(attrs, attrName); - CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); - CFRelease(attrs); - } + // Intersect effectiveRange and range + if (effectiveRange.location < range.location) { + effectiveRange.length -= (range.location - effectiveRange.location); + effectiveRange.location = range.location; + } + if (effectiveRange.length > range.length) effectiveRange.length = range.length; + // First check to see if the value is not there; this will avoid a copy + if (CFDictionaryContainsKey(attrs, attrName)) { + // We need to make a new copy + attrs = __CFAttributedStringCreateAttributesDictionary(CFGetAllocator(attrStr), attrs); + CFDictionaryRemoveValue(attrs, attrName); + CFRunArrayReplace(attrStr->attributeArray, effectiveRange, attrs, effectiveRange.length); + CFRelease(attrs); + } range.length -= effectiveRange.length; range.location += effectiveRange.length; } @@ -620,7 +617,6 @@ void CFAttributedStringEndEditing(CFMutableAttributedStringRef attrStr) { /*** Functions for NSCFAttributedString usage ***/ - CFIndex _CFAttributedStringGetLength(CFAttributedStringRef attrStr) { return CFStringGetLength(attrStr->string); } diff --git a/CoreFoundation/String.subproj/CFBurstTrie.c b/CoreFoundation/String.subproj/CFBurstTrie.c index 0643946800..46b3450b09 100644 --- a/CoreFoundation/String.subproj/CFBurstTrie.c +++ b/CoreFoundation/String.subproj/CFBurstTrie.c @@ -1,7 +1,7 @@ /* CFBurstTrie.c - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -1208,13 +1208,12 @@ static Boolean advanceCursorOnMappedPageForByte(Page *page, CompactMapCursor *cu BOOL shouldContinue = TRUE; if (!(cursor->entryOffsetInPage == 0 && entry->strlen == 0)) { - if (entry->string[cursor->offsetInEntry] == byte) { + cursor->offsetInEntry++; + if (entry->string[cursor->offsetInEntry] == byte) found = TRUE; - cursor->offsetInEntry++; - } else if (entry->string[cursor->offsetInEntry] > byte) { + else if (entry->string[cursor->offsetInEntry] > byte) shouldContinue = FALSE; - cursor->offsetInEntry++; - } else { + else { minPrefixLength = entry->pfxLen + cursor->offsetInEntry; cursor->entryOffsetInPage += getPackedPageEntrySize(entry); } @@ -1247,7 +1246,7 @@ static Boolean advanceCursorOnMappedPageForByte(Page *page, CompactMapCursor *cu else if (entry->string[0] < byte) cursor->entryOffsetInPage += getPackedPageEntrySize(entry); else { - cursor->offsetInEntry = 1; + cursor->offsetInEntry = 0; found = TRUE; break; } @@ -1303,7 +1302,7 @@ static Boolean advanceCursorMappedPageSortedByKey(Page *page, CompactMapCursor * if (cursor->isOnPage) { entry = (PageEntry*)&page->data[cursor->entryOffsetInPage]; prefix = entry->string; - prefixLength = cursor->offsetInEntry; + prefixLength = cursor->offsetInEntry + 1; } while (cursor->entryOffsetInPage < pageSize) { @@ -1335,7 +1334,7 @@ static Boolean advanceCursorMappedPageSortedByKey(Page *page, CompactMapCursor * return FALSE; else if (cmpResult2 == 0) { cursor->isOnPage = TRUE; - cursor->offsetInEntry = prefixLength + length; + cursor->offsetInEntry = prefixLength + length - 1; getMapCursorPayloadFromPageEntry(entry, cursor, &cursor->payload); return TRUE; } else @@ -1499,11 +1498,12 @@ static void traverseFromMapCursorMappedPageWithPrefixCompression(Page *page, Com uint32_t minPrefixLength = 0; if (cursor->isOnPage) { PageEntryPacked *entry = (PageEntryPacked*)&page->data[offset]; - int32_t remainingLength = entry->strlen - cursor->offsetInEntry; + int32_t remainingLength = entry->strlen - cursor->offsetInEntry - 1; if (remainingLength >= 0 && remainingLength <= capacity) { - memcpy(bytes + length, entry->string + cursor->offsetInEntry, remainingLength); + memcpy(bytes + length, entry->string + cursor->offsetInEntry + 1, remainingLength); callback(ctx, bytes, length + remainingLength, entry->payload, stop); - if (*stop) return; + if (*stop) + return; } minPrefixLength = entry->pfxLen + cursor->offsetInEntry; offset += getPackedPageEntrySize(entry); @@ -1523,7 +1523,8 @@ static void traverseFromMapCursorMappedPageWithPrefixCompression(Page *page, Com memcpy(bytes + length, entry->string, entry->strlen); callback(ctx, bytes, length + entry->strlen, entry->payload, stop); length += entry->strlen; - if (*stop) return; + if (*stop) + return; } previousEntry = entry; offset += getPackedPageEntrySize(entry); @@ -1538,14 +1539,14 @@ static void traverseFromMapCursorMappedPageSortedByKey(Page *page, CompactMapCur const UInt8 *prefix = NULL; if (cursor->isOnPage) { PageEntry *entry = (PageEntry*)&page->data[offset]; - int32_t remainingLength = entry->strlen - cursor->offsetInEntry; + 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; + prefixLength = cursor->offsetInEntry + 1; prefix = entry->string; offset += getPageEntrySize(entry); } @@ -1623,7 +1624,7 @@ static Boolean getMapCursorPayloadFromPackedPageEntry(PageEntryPacked *entry, co if (payload) *payload = entry->payload; return TRUE; - } else if (cursor->offsetInEntry != entry->strlen) + } else if (cursor->offsetInEntry != entry->strlen - 1) return FALSE; else { if (payload) @@ -1640,7 +1641,7 @@ static Boolean getMapCursorPayloadFromPageEntry(PageEntry *entry, const CompactM if (payload) *payload = entry->payload; return TRUE; - } else if (cursor->offsetInEntry != entry->strlen) + } else if (cursor->offsetInEntry != entry->strlen - 1) return FALSE; else { if (payload) @@ -1846,7 +1847,7 @@ static void serializeCFBurstTrieList(CFBurstTrieRef trie, ListNodeRef listNode, for (listCount = 0; listNode; listCount++) { if (listCount >= size) { size *= 2; - nodes = __CFSafelyReallocate(nodes, sizeof(ListNodeRef) * size, NULL); + nodes = (ListNodeRef *)realloc(nodes, sizeof(ListNodeRef) * size); } nodes[listCount] = listNode; listNode = listNode->next; diff --git a/CoreFoundation/String.subproj/CFBurstTrie.h b/CoreFoundation/String.subproj/CFBurstTrie.h index fd7bcdfedc..5ceea2dc14 100644 --- a/CoreFoundation/String.subproj/CFBurstTrie.h +++ b/CoreFoundation/String.subproj/CFBurstTrie.h @@ -1,7 +1,7 @@ /* CFBurstTrie.h - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -60,121 +60,121 @@ typedef CF_OPTIONS(CFOptionFlags, CFBurstTrieOpts) { typedef void (*CFBurstTrieTraversalCallback)(void* context, const UInt8* key, uint32_t keyLength, uint32_t payload, Boolean *stop); CF_EXPORT -CFBurstTrieRef CFBurstTrieCreate() API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFBurstTrieRef CFBurstTrieCreate(void) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -CFBurstTrieRef CFBurstTrieCreateWithOptions(CFDictionaryRef options) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +CFBurstTrieRef CFBurstTrieCreateWithOptions(CFDictionaryRef options) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -CFBurstTrieRef CFBurstTrieCreateFromFile(CFStringRef path) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFBurstTrieRef CFBurstTrieCreateFromFile(CFStringRef path) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -CFBurstTrieRef CFBurstTrieCreateFromMapBytes(char *mapBase) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFBurstTrieRef CFBurstTrieCreateFromMapBytes(char *mapBase) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -Boolean CFBurstTrieInsert(CFBurstTrieRef trie, CFStringRef term, CFRange termRange, CFIndex payload) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +Boolean CFBurstTrieSerialize(CFBurstTrieRef trie, CFStringRef path, CFBurstTrieOpts opts) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -Boolean CFBurstTrieSerializeWithFileDescriptor(CFBurstTrieRef trie, int fd, CFBurstTrieOpts opts) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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)) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFIndex CFBurstTrieGetCount(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -CFBurstTrieRef CFBurstTrieRetain(CFBurstTrieRef trie) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFBurstTrieRef CFBurstTrieRetain(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -void CFBurstTrieRelease(CFBurstTrieRef trie) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +void CFBurstTrieRelease(CFBurstTrieRef trie) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -CFBurstTrieCursorRef CFBurstTrieCreateCursorForBytes(CFBurstTrieRef trie, const UInt8* bytes, CFIndex length) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +CFBurstTrieCursorRef CFBurstTrieCreateCursorForBytes(CFBurstTrieRef trie, const UInt8* bytes, CFIndex length) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -CFBurstTrieCursorRef CFBurstTrieCursorCreateByCopy(CFBurstTrieCursorRef cursor) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +CFBurstTrieCursorRef CFBurstTrieCursorCreateByCopy(CFBurstTrieCursorRef cursor) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -Boolean CFBurstTrieSetCursorForBytes(CFBurstTrieRef trie, CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +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) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +Boolean CFBurstTrieCursorIsEqual(CFBurstTrieCursorRef lhs, CFBurstTrieCursorRef rhs) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -Boolean CFBurstTrieCursorAdvanceForBytes(CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +Boolean CFBurstTrieCursorAdvanceForBytes(CFBurstTrieCursorRef cursor, const UInt8* bytes, CFIndex length) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -Boolean CFBurstTrieCursorGetPayload(CFBurstTrieCursorRef cursor, uint32_t *payload) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +Boolean CFBurstTrieCursorGetPayload(CFBurstTrieCursorRef cursor, uint32_t *payload) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -void CFBurstTrieTraverseFromCursor(CFBurstTrieCursorRef cursor, void *ctx, CFBurstTrieTraversalCallback callback) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +void CFBurstTrieTraverseFromCursor(CFBurstTrieCursorRef cursor, void *ctx, CFBurstTrieTraversalCallback callback) CF_AVAILABLE(10_8, 6_0); CF_EXPORT -void CFBurstTrieCursorRelease(CFBurstTrieCursorRef cursor) API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +void CFBurstTrieCursorRelease(CFBurstTrieCursorRef cursor) CF_AVAILABLE(10_8, 6_0); CF_EXTERN_C_END diff --git a/CoreFoundation/String.subproj/CFCharacterSet.c b/CoreFoundation/String.subproj/CFCharacterSet.c index 27c0d8311b..ed9886558a 100644 --- a/CoreFoundation/String.subproj/CFCharacterSet.c +++ b/CoreFoundation/String.subproj/CFCharacterSet.c @@ -1,7 +1,7 @@ /* CFCharacterSet.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -92,69 +92,43 @@ struct __CFCharacterSet { /* _base._info values interesting for CFCharacterSet */ enum { - __kCFCharSetClassBuiltin = 0, - __kCFCharSetClassRange = 1, - __kCFCharSetClassString = 2, - __kCFCharSetClassBitmap = 3, - __kCFCharSetClassCompactBitmap = 4, + __kCFCharSetClassTypeMask = 0x0070, + __kCFCharSetClassBuiltin = 0x0000, + __kCFCharSetClassRange = 0x0010, + __kCFCharSetClassString = 0x0020, + __kCFCharSetClassBitmap = 0x0030, + __kCFCharSetClassSet = 0x0040, + __kCFCharSetClassCompactBitmap = 0x0040, + + __kCFCharSetIsInvertedMask = 0x0008, + __kCFCharSetIsInverted = 0x0008, + + __kCFCharSetHasHashValueMask = 0x00004, + __kCFCharSetHasHashValue = 0x0004, + + /* Generic CFBase values */ + __kCFCharSetIsMutableMask = 0x0001, + __kCFCharSetIsMutable = 0x0001, }; /* Inline accessor macros for _base._info */ -CF_INLINE Boolean __CFCSetIsMutable(CFCharacterSetRef cset) { - return __CFRuntimeGetFlag(cset, 0); -} - -CF_INLINE Boolean __CFCSetIsBuiltin(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4) == __kCFCharSetClassBuiltin; -} - -CF_INLINE Boolean __CFCSetIsRange(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4) == __kCFCharSetClassRange; -} - -CF_INLINE Boolean __CFCSetIsString(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4) == __kCFCharSetClassString; -} - -CF_INLINE Boolean __CFCSetIsBitmap(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4) == __kCFCharSetClassBitmap; -} -CF_INLINE Boolean __CFCSetIsCompactBitmap(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4) == __kCFCharSetClassCompactBitmap; -} - -CF_INLINE UInt32 __CFCSetClassType(CFCharacterSetRef cset) { - return __CFRuntimeGetValue(cset, 6, 4); -} - -CF_INLINE Boolean __CFCSetIsInverted(CFCharacterSetRef cset) { - return __CFRuntimeGetFlag(cset, 3); -} - -CF_INLINE Boolean __CFCSetHasHashValue(CFCharacterSetRef cset) { - return __CFRuntimeGetFlag(cset, 2); -} - -CF_INLINE void __CFCSetPutIsMutable(CFMutableCharacterSetRef cset, Boolean isMutable) { - __CFRuntimeSetFlag(cset, 0, isMutable); -} - -CF_INLINE void __CFCSetPutIsInverted(CFMutableCharacterSetRef cset, Boolean isInverted) { - __CFRuntimeSetFlag(cset, 3, isInverted); -} - -CF_INLINE void __CFCSetPutHasHashValue(CFMutableCharacterSetRef cset, Boolean hasHash) { - __CFRuntimeSetFlag(cset, 2, hasHash); -} - -CF_INLINE void __CFCSetPutClassType(CFMutableCharacterSetRef cset, UInt32 classType) { - __CFRuntimeSetValue(cset, 6, 4, classType); -} - -CF_PRIVATE Boolean __CFCharacterSetIsMutable(CFCharacterSetRef cset) { - return __CFCSetIsMutable(cset); -} +CF_INLINE Boolean __CFCSetIsMutable(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetIsMutableMask) == __kCFCharSetIsMutable;} +CF_INLINE Boolean __CFCSetIsBuiltin(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask) == __kCFCharSetClassBuiltin;} +CF_INLINE Boolean __CFCSetIsRange(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask) == __kCFCharSetClassRange;} +CF_INLINE Boolean __CFCSetIsString(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask) == __kCFCharSetClassString;} +CF_INLINE Boolean __CFCSetIsBitmap(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask) == __kCFCharSetClassBitmap;} +CF_INLINE Boolean __CFCSetIsCompactBitmap(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask) == __kCFCharSetClassCompactBitmap;} +CF_INLINE Boolean __CFCSetIsInverted(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetIsInvertedMask) == __kCFCharSetIsInverted;} +CF_INLINE Boolean __CFCSetHasHashValue(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetHasHashValueMask) == __kCFCharSetHasHashValue;} +CF_INLINE UInt32 __CFCSetClassType(CFCharacterSetRef cset) {return (cset->_base._cfinfo[CF_INFO_BITS] & __kCFCharSetClassTypeMask);} + +CF_INLINE void __CFCSetPutIsMutable(CFMutableCharacterSetRef cset, Boolean isMutable) {(isMutable ? (cset->_base._cfinfo[CF_INFO_BITS] |= __kCFCharSetIsMutable) : (cset->_base._cfinfo[CF_INFO_BITS] &= ~ __kCFCharSetIsMutable));} +CF_INLINE void __CFCSetPutIsInverted(CFMutableCharacterSetRef cset, Boolean isInverted) {(isInverted ? (cset->_base._cfinfo[CF_INFO_BITS] |= __kCFCharSetIsInverted) : (cset->_base._cfinfo[CF_INFO_BITS] &= ~__kCFCharSetIsInverted));} +CF_INLINE void __CFCSetPutHasHashValue(CFMutableCharacterSetRef cset, Boolean hasHash) {(hasHash ? (cset->_base._cfinfo[CF_INFO_BITS] |= __kCFCharSetHasHashValue) : (cset->_base._cfinfo[CF_INFO_BITS] &= ~__kCFCharSetHasHashValue));} +CF_INLINE void __CFCSetPutClassType(CFMutableCharacterSetRef cset, UInt32 classType) {cset->_base._cfinfo[CF_INFO_BITS] &= ~__kCFCharSetClassTypeMask; cset->_base._cfinfo[CF_INFO_BITS] |= classType;} + +CF_PRIVATE Boolean __CFCharacterSetIsMutable(CFCharacterSetRef cset) {return __CFCSetIsMutable(cset);} /* Inline contents accessor macros */ @@ -386,7 +360,7 @@ CF_INLINE void __CFCSetAllocateAnnexForPlane(CFCharacterSetRef cset, int plane) if (NULL == cset->_annex->_nonBMPPlanes) { cset->_annex->_nonBMPPlanes = (CFCharacterSetRef*)CFAllocatorAllocate(CFGetAllocator(cset), sizeof(CFCharacterSetRef) * plane, 0); } else { - cset->_annex->_nonBMPPlanes = __CFSafelyReallocateWithAllocator(CFGetAllocator(cset), cset->_annex->_nonBMPPlanes, sizeof(CFCharacterSetRef) * plane, 0, NULL); + cset->_annex->_nonBMPPlanes = (CFCharacterSetRef*)CFAllocatorReallocate(CFGetAllocator(cset), (void *)cset->_annex->_nonBMPPlanes, sizeof(CFCharacterSetRef) * plane, 0); } } } @@ -397,7 +371,6 @@ CF_INLINE void __CFCSetAnnexSetIsInverted(CFCharacterSetRef cset, Boolean flag) } CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCharacterSetRef annexCSet, int plane) { - if (plane < 1) { HALT; } __CFCSetAllocateAnnexForPlane(cset, plane); if (__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) CFRelease(cset->_annex->_nonBMPPlanes[plane - 1]); if (annexCSet) { @@ -409,7 +382,6 @@ CF_INLINE void __CFCSetPutCharacterSetToAnnexPlane(CFCharacterSetRef cset, CFCha } CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef cset, int plane) { - if (plane < 1) { HALT; } __CFCSetAllocateAnnexForPlane(cset, plane); if (!__CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane)) { cset->_annex->_nonBMPPlanes[plane - 1] = (CFCharacterSetRef)CFCharacterSetCreateMutable(CFGetAllocator(cset)); @@ -419,7 +391,6 @@ CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSet(CFCharacterSetRef } CF_INLINE CFCharacterSetRef __CFCSetGetAnnexPlaneCharacterSetNoAlloc(CFCharacterSetRef cset, int plane) { - if (plane < 1) { HALT; } return (cset->_annex && __CFCSetAnnexBitmapGetPlane(cset->_annex->_validEntriesBitmap, plane) ? cset->_annex->_nonBMPPlanes[plane - 1] : NULL); } @@ -823,21 +794,20 @@ static void __CFCSetMakeBitmap(CFMutableCharacterSetRef cset) { } } -CF_INLINE Boolean __CFCSetGenericInit(CFMutableCharacterSetRef cset, UInt32 classType, Boolean isMutable) { - __CFCSetPutIsMutable(cset, isMutable); - __CFCSetPutClassType(cset, classType); +CF_INLINE Boolean __CFCSetGenericInit(CFMutableCharacterSetRef cset, UInt32 flags) { + cset->_base._cfinfo[CF_INFO_BITS] |= flags; cset->_hashValue = 0; cset->_annex = NULL; return true; } -CF_INLINE CFMutableCharacterSetRef __CFCSetGenericCreate(CFAllocatorRef allocator, UInt32 classType, Boolean isMutable) { +CF_INLINE CFMutableCharacterSetRef __CFCSetGenericCreate(CFAllocatorRef allocator, UInt32 flags) { CFMutableCharacterSetRef cset; CFIndex size = sizeof(struct __CFCharacterSet) - sizeof(CFRuntimeBase); cset = (CFMutableCharacterSetRef)_CFRuntimeCreateInstance(allocator, CFCharacterSetGetTypeID(), size, NULL); if (NULL == cset) return NULL; - __CFCSetGenericInit(cset, classType, isMutable); + __CFCSetGenericInit(cset, flags); return cset; } @@ -925,17 +895,22 @@ static Boolean __CFCharacterSetEqual(CFTypeRef cf1, CFTypeRef cf2) { return (__CFCSetRangeFirstChar((CFCharacterSetRef)cf1) == __CFCSetRangeFirstChar((CFCharacterSetRef)cf2) && __CFCSetRangeLength((CFCharacterSetRef)cf1) && __CFCSetRangeLength((CFCharacterSetRef)cf2) && isInvertStateIdentical ? true : false); case __kCFCharSetClassString: - if (!isInvertStateIdentical) { - return false; - } + if (isInvertStateIdentical) { + const UniChar *buf1 = __CFCSetStringBuffer((CFCharacterSetRef)cf1); + const UniChar *buf1End = buf1 + __CFCSetStringLength((CFCharacterSetRef)cf1); + const UniChar *buf2 = __CFCSetStringBuffer((CFCharacterSetRef)cf2); + const UniChar *buf2End = buf2 + __CFCSetStringLength((CFCharacterSetRef)cf2); - CFIndex length = __CFCSetStringLength((CFCharacterSetRef)cf1); - if (__CFCSetStringLength((CFCharacterSetRef)cf2) != length) { - return false; - } - - // Both strings are sorted and have duplicates removed. We can simply compare the buffers. - if (memcmp(__CFCSetStringBuffer((CFCharacterSetRef)cf1), __CFCSetStringBuffer((CFCharacterSetRef)cf2), length * sizeof(UniChar)) != 0) { + while ((buf1 < buf1End) && (buf2 < buf2End)) { + UniChar char1 = *buf1; + UniChar char2 = *buf2; + + if (char1 != char2) return false; + + do { ++buf1; } while ((buf1 < buf1End) && (char1 == *buf1)); + do { ++buf2; } while ((buf2 < buf2End) && (char2 == *buf2)); + } + } else { return false; } break; @@ -1323,15 +1298,13 @@ CFCharacterSetRef CFCharacterSetGetPredefined(CFCharacterSetPredefinedSet theSet __CFCSetValidateBuiltinType(theSetIdentifier, __PRETTY_FUNCTION__); - if ((theSetIdentifier < kCFCharacterSetControl) || (theSetIdentifier > __kCFLastBuiltinSetID)) { return NULL; } - OSSpinLockLock(&__CFCharacterSetLock); cset = ((NULL != __CFBuiltinSets) ? __CFBuiltinSets[theSetIdentifier - 1] : NULL); OSSpinLockUnlock(&__CFCharacterSetLock); if (NULL != cset) return cset; - if (!(cset = __CFCSetGenericCreate(kCFAllocatorSystemDefault, __kCFCharSetClassBuiltin, false))) return NULL; + if (!(cset = __CFCSetGenericCreate(kCFAllocatorSystemDefault, __kCFCharSetClassBuiltin))) return NULL; __CFCSetPutBuiltinType((CFMutableCharacterSetRef)cset, theSetIdentifier); OSSpinLockLock(&__CFCharacterSetLock); @@ -1344,11 +1317,11 @@ CFCharacterSetRef CFCharacterSetGetPredefined(CFCharacterSetPredefinedSet theSet #if DEPLOYMENT_RUNTIME_SWIFT Boolean _CFCharacterSetInitWithCharactersInRange(CFMutableCharacterSetRef cset, CFRange theRange) { if (theRange.length) { - if (!__CFCSetGenericInit(cset, __kCFCharSetClassRange, false)) return false; + if (!__CFCSetGenericInit(cset, __kCFCharSetClassRange)) return false; __CFCSetPutRangeFirstChar(cset, theRange.location); __CFCSetPutRangeLength(cset, theRange.length); } else { - if (!__CFCSetGenericInit(cset, __kCFCharSetClassBitmap, false)) return false; + if (!__CFCSetGenericInit(cset, __kCFCharSetClassBitmap)) return false; __CFCSetPutBitmapBits(cset, NULL); __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 } @@ -1362,11 +1335,11 @@ CFCharacterSetRef CFCharacterSetCreateWithCharactersInRange(CFAllocatorRef alloc __CFCSetValidateRange(theRange, __PRETTY_FUNCTION__); if (theRange.length) { - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassRange, false))) return NULL; + if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassRange))) return NULL; __CFCSetPutRangeFirstChar(cset, theRange.location); __CFCSetPutRangeLength(cset, theRange.length); } else { - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap, false))) return NULL; + if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap))) return NULL; __CFCSetPutBitmapBits(cset, NULL); __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 } @@ -1378,35 +1351,17 @@ static int chcompar(const void *a, const void *b) { return -(int)(*(UniChar *)b - *(UniChar *)a); } -// Search the string for duplicates and remove them (effectively shifting down the remainder of the string). This is a set after all. -// precondition: *base must be sorted -// returns: new length of the string -static CFIndex removedupes(UniChar *base, CFIndex length) { - if (length < 2) return length; - - CFIndex j = 0; - for (CFIndex i = 1; i < length; i++) { - if (base[j] != base[i]) { - j++; - base[j] = base[i]; - } - } - - return j + 1; -} - #if DEPLOYMENT_RUNTIME_SWIFT Boolean _CFCharacterSetInitWithCharactersInString(CFMutableCharacterSetRef cset, CFStringRef theString) { CFIndex length; length = CFStringGetLength(theString); if (length < __kCFStringCharSetMax) { - if (!__CFCSetGenericInit(cset, __kCFCharSetClassString, false)) return false; + if (!__CFCSetGenericInit(cset, __kCFCharSetClassString)) return false; __CFCSetPutStringBuffer(cset, (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, __kCFStringCharSetMax * sizeof(UniChar), 0)); __CFCSetPutStringLength(cset, length); CFStringGetCharacters(theString, CFRangeMake(0, length), __CFCSetStringBuffer(cset)); qsort(__CFCSetStringBuffer(cset), length, sizeof(UniChar), chcompar); - __CFCSetPutStringLength(cset, removedupes(__CFCSetStringBuffer(cset), length)); if (0 == length) { __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 @@ -1443,12 +1398,11 @@ CFCharacterSetRef CFCharacterSetCreateWithCharactersInString(CFAllocatorRef allo if (length < __kCFStringCharSetMax) { CFMutableCharacterSetRef cset; - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassString, false))) return NULL; + if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassString))) return NULL; __CFCSetPutStringBuffer(cset, (UniChar *)CFAllocatorAllocate(CFGetAllocator(cset), __kCFStringCharSetMax * sizeof(UniChar), 0)); __CFCSetPutStringLength(cset, length); CFStringGetCharacters(theString, CFRangeMake(0, length), __CFCSetStringBuffer(cset)); qsort(__CFCSetStringBuffer(cset), length, sizeof(UniChar), chcompar); - __CFCSetPutStringLength(cset, removedupes(__CFCSetStringBuffer(cset), length)); if (0 == length) { __CFCSetPutHasHashValue(cset, true); // _hashValue is 0 @@ -1570,7 +1524,7 @@ Boolean _CFCharacterSetInitWithBitmapRepresentation(CFMutableCharacterSetRef cse CFCharacterSetRef CFCharacterSetCreateWithBitmapRepresentation(CFAllocatorRef allocator, CFDataRef theData) { CFMutableCharacterSetRef cset; - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap, false))) return NULL; + if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap))) return NULL; __CFCharacterSetInitWithBitmapRepresentation(allocator, cset, theData); @@ -1591,7 +1545,7 @@ CFCharacterSetRef CFCharacterSetCreateInvertedSet(CFAllocatorRef alloc, CFCharac #if DEPLOYMENT_RUNTIME_SWIFT Boolean _CFCharacterSetInitMutable(CFMutableCharacterSetRef cset) { - if (!__CFCSetGenericInit(cset, __kCFCharSetClassBitmap, true)) return false; + if (!__CFCSetGenericInit(cset, __kCFCharSetClassBitmap| __kCFCharSetIsMutable)) return false; __CFCSetPutBitmapBits(cset, NULL); __CFCSetPutHasHashValue(cset, true); return true; @@ -1603,7 +1557,7 @@ Boolean _CFCharacterSetInitMutable(CFMutableCharacterSetRef cset) { CFMutableCharacterSetRef CFCharacterSetCreateMutable(CFAllocatorRef allocator) { CFMutableCharacterSetRef cset; - if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap, true))) return NULL; + if (!(cset = __CFCSetGenericCreate(allocator, __kCFCharSetClassBitmap| __kCFCharSetIsMutable))) return NULL; __CFCSetPutBitmapBits(cset, NULL); __CFCSetPutHasHashValue(cset, true); // Hash value is 0 @@ -1723,7 +1677,8 @@ Boolean CFCharacterSetIsCharacterMember(CFCharacterSetRef theSet, UniChar theCha Boolean result = false; CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (NSCharacterSet *)theSet, longCharacterIsMember:(UTF32Char)theChar); - + CF_SWIFT_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (CFSwiftRef)theSet, NSCharacterSet.longCharacterIsMember, theChar); + __CFGenericValidateType(theSet, __kCFCharacterSetTypeID); isInverted = __CFCSetIsInverted(theSet); @@ -1938,6 +1893,7 @@ Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFIndex thePlan Boolean isInverted = __CFCSetIsInverted(theSet); CF_OBJC_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (NSCharacterSet *)theSet, hasMemberInPlane:(uint8_t)thePlane); + CF_SWIFT_FUNCDISPATCHV(__kCFCharacterSetTypeID, Boolean, (CFSwiftRef)theSet, NSCharacterSet.hasMemberInPlane, thePlane); if (__CFCSetIsEmpty(theSet)) { return (isInverted ? TRUE : FALSE); @@ -2214,7 +2170,7 @@ void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange return; } else if (theRange.location < firstChar && firstChar <= theRange.location + theRange.length) { __CFCSetPutRangeFirstChar(theSet, theRange.location); - __CFCSetPutRangeLength(theSet, __CFMax(firstChar + length, theRange.location + theRange.length) - theRange.location); + __CFCSetPutRangeLength(theSet, length + (firstChar - theRange.location)); __CFCSetPutHasHashValue(theSet, false); return; } @@ -2226,7 +2182,6 @@ void CFCharacterSetAddCharactersInRange(CFMutableCharacterSetRef theSet, CFRange __CFCSetPutStringLength(theSet, __CFCSetStringLength(theSet) + theRange.length); while (theRange.length--) *buffer++ = (UniChar)theRange.location++; qsort(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet), sizeof(UniChar), chcompar); - __CFCSetPutStringLength(theSet, removedupes(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet))); __CFCSetPutHasHashValue(theSet, false); return; } @@ -2293,7 +2248,6 @@ void CFCharacterSetRemoveCharactersInRange(CFMutableCharacterSetRef theSet, CFRa __CFCSetPutStringLength(theSet, __CFCSetStringLength(theSet) + theRange.length); while (theRange.length--) *buffer++ = (UniChar)theRange.location++; qsort(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet), sizeof(UniChar), chcompar); - __CFCSetPutStringLength(theSet, removedupes(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet))); __CFCSetPutHasHashValue(theSet, false); return; } @@ -2375,7 +2329,6 @@ void CFCharacterSetAddCharactersInString(CFMutableCharacterSetRef theSet, CFStr } __CFCSetPutStringLength(theSet, newLength); qsort(__CFCSetStringBuffer(theSet), newLength, sizeof(UniChar), chcompar); - __CFCSetPutStringLength(theSet, removedupes(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet))); } __CFCSetPutHasHashValue(theSet, false); @@ -2464,7 +2417,6 @@ void CFCharacterSetRemoveCharactersInString(CFMutableCharacterSetRef theSet, CFS } __CFCSetPutStringLength(theSet, newLength); qsort(__CFCSetStringBuffer(theSet), newLength, sizeof(UniChar), chcompar); - __CFCSetPutStringLength(theSet, removedupes(__CFCSetStringBuffer(theSet), __CFCSetStringLength(theSet))); __CFCSetPutHasHashValue(theSet, false); if (hasSurrogate) __CFApplySurrogatesInString(theSet, theString, &CFCharacterSetRemoveCharactersInRange); @@ -2693,12 +2645,13 @@ void CFCharacterSetIntersect(CFMutableCharacterSetRef theSet, CFCharacterSetRef case __kCFCharSetClassString: __CFCSetPutStringLength(theSet, __CFCSetStringLength(theOtherSet)); - if (!__CFCSetStringBuffer(theSet)) __CFCSetPutStringBuffer(theSet, (UniChar *)CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), 0)); - memmove(__CFCSetStringBuffer(theSet), __CFCSetStringBuffer(theOtherSet), __CFCSetStringLength(theSet) * sizeof(UniChar)); + if (!__CFCSetStringBuffer(theSet)) + __CFCSetPutStringBuffer(theSet, (UniChar *)CFAllocatorAllocate(CFGetAllocator(theSet), __kCFStringCharSetMax * sizeof(UniChar), 0)); + memmove(__CFCSetStringBuffer(theSet), __CFCSetStringBuffer(theOtherSet), __CFCSetStringLength(theSet) * sizeof(UniChar)); break; case __kCFCharSetClassBitmap: - __CFCSetPutBitmapBits(theSet, (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * __kCFBitmapSize, 0)); + __CFCSetPutBitmapBits(theSet, (uint8_t *)CFAllocatorAllocate(CFGetAllocator(theSet), sizeof(uint8_t) * __kCFBitmapSize, 0)); memmove(__CFCSetBitmapBits(theSet), __CFCSetBitmapBits(theOtherSet), __kCFBitmapSize); break; diff --git a/CoreFoundation/String.subproj/CFCharacterSet.h b/CoreFoundation/String.subproj/CFCharacterSet.h index 9a7c9ab77f..b5b1d640e6 100644 --- a/CoreFoundation/String.subproj/CFCharacterSet.h +++ b/CoreFoundation/String.subproj/CFCharacterSet.h @@ -1,7 +1,7 @@ /* CFCharacterSet.h - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -73,7 +73,7 @@ typedef CF_ENUM(CFIndex, CFCharacterSetPredefinedSet) { 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*) */ - kCFCharacterSetNewline API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 15, /* Newline character set (U000A ~ U000D, U0085, U2028, and U2029) */ + kCFCharacterSetNewline CF_ENUM_AVAILABLE(10_5, 2_0) = 15, /* Newline character set (U000A ~ U000D, U0085, U2028, and U2029) */ kCFCharacterSetIllegal = 12/* Illegal character set */ }; @@ -200,7 +200,7 @@ CF_EXPORT Boolean CFCharacterSetHasMemberInPlane(CFCharacterSetRef theSet, CFInd /*! @function CFCharacterSetCreateMutable Creates a new empty mutable character set. - @param alloc The CFAllocator which should be used to allocate + @param allocator The CFAllocator which should be used to allocate memory for the array and its storage for values. This parameter may be NULL in which case the current default CFAllocator is used. If this reference is not a valid @@ -213,7 +213,7 @@ CFMutableCharacterSetRef CFCharacterSetCreateMutable(CFAllocatorRef alloc); /*! @function CFCharacterSetCreateCopy Creates a new character set with the values from the given character set. This function tries to compact the backing store where applicable. - @param alloc The CFAllocator which should be used to allocate + @param allocator The CFAllocator which should be used to allocate memory for the array and its storage for values. This parameter may be NULL in which case the current default CFAllocator is used. If this reference is not a valid @@ -229,7 +229,7 @@ CFCharacterSetRef CFCharacterSetCreateCopy(CFAllocatorRef alloc, CFCharacterSetR /*! @function CFCharacterSetCreateMutableCopy Creates a new mutable character set with the values from the given character set. - @param alloc The CFAllocator which should be used to allocate + @param allocator The CFAllocator which should be used to allocate memory for the array and its storage for values. This parameter may be NULL in which case the current default CFAllocator is used. If this reference is not a valid @@ -270,7 +270,7 @@ CF_EXPORT Boolean CFCharacterSetIsLongCharacterMember(CFCharacterSetRef theSet, /*! @function CFCharacterSetCreateBitmapRepresentation Creates a new immutable data with the bitmap representation from the given character set. - @param alloc The CFAllocator which should be used to allocate + @param allocator The CFAllocator which should be used to allocate memory for the array and its storage for values. This parameter may be NULL in which case the current default CFAllocator is used. If this reference is not a valid diff --git a/CoreFoundation/String.subproj/CFCharacterSetPriv.h b/CoreFoundation/String.subproj/CFCharacterSetPriv.h index ef47e79720..41d3ca17dd 100644 --- a/CoreFoundation/String.subproj/CFCharacterSetPriv.h +++ b/CoreFoundation/String.subproj/CFCharacterSetPriv.h @@ -1,7 +1,7 @@ /* CFCharacterSetPriv.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFString.c b/CoreFoundation/String.subproj/CFString.c index b1f4fa3633..ad8e930d37 100644 --- a/CoreFoundation/String.subproj/CFString.c +++ b/CoreFoundation/String.subproj/CFString.c @@ -1,7 +1,7 @@ /* CFString.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -20,7 +20,6 @@ #include #include #include -#include #include "CFInternal.h" #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX #include "CFLocaleInternal.h" @@ -95,7 +94,7 @@ extern size_t malloc_good_size(size_t size); #endif extern void __CFStrConvertBytesToUnicode(const uint8_t *bytes, UniChar *buffer, CFIndex numChars); -static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef validFormatSpecifiers, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args, CFErrorRef *errorPtr); +static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args); #if defined(DEBUG) @@ -183,30 +182,28 @@ The bit usages should not be modified in a way that would effect these bit patte Note that some of the bit patterns in the enum below overlap and are duplicated. Keep this in mind as you do searches for use cases. */ enum { - // These are bit numbers - do not use them as masks - __kCFIsMutable = 0, - // !!! Bit 1 has been freed up - __kCFHasLengthByte = 2, - __kCFHasNullByte = 3, - __kCFIsUnicode = 4, + __kCFFreeContentsWhenDoneMask = 0x020, + __kCFFreeContentsWhenDone = 0x020, + __kCFContentsMask = 0x060, + __kCFHasInlineContents = 0x000, + __kCFNotInlineContentsNoFree = 0x040, // Don't free + __kCFNotInlineContentsDefaultFree = 0x020, // Use allocator's free function + __kCFNotInlineContentsCustomFree = 0x060, // Use a specially provided free function + __kCFHasContentsAllocatorMask = 0x060, + __kCFHasContentsAllocator = 0x060, // (For mutable strings) use a specially provided allocator + __kCFHasContentsDeallocatorMask = 0x060, + __kCFHasContentsDeallocator = 0x060, + __kCFIsMutableMask = 0x01, + __kCFIsMutable = 0x01, + __kCFIsUnicodeMask = 0x10, + __kCFIsUnicode = 0x10, + __kCFHasNullByteMask = 0x08, + __kCFHasNullByte = 0x08, + __kCFHasLengthByteMask = 0x04, + __kCFHasLengthByte = 0x04, + // !!! Bit 0x02 has been freed up }; -typedef enum { - // These are values in bit numbers 5 & 6 - __kCFHasInlineContents = 0, - __kCFNotInlineContentsDefaultFree = 1, // Use allocator's free function - __kCFNotInlineContentsNoFree = 2, // Don't free - __kCFNotInlineContentsCustomFree = 3, // Use a specially provided free function -} _CFStringInlineContents; - -CF_INLINE void __CFStrSetInlineContents(CFStringRef str, _CFStringInlineContents contents) {__CFRuntimeSetValue(str, 6, 5, contents);} -CF_INLINE Boolean __CFStrIsInline(CFStringRef str) {return __CFRuntimeGetValue(str, 6, 5) == __kCFHasInlineContents;} -CF_INLINE Boolean __CFStrFreeContentsWhenDone(CFStringRef str) { - // Contents of this flag are shared with the inline contents field - return __CFRuntimeGetFlag(str, 5); -} -CF_INLINE Boolean __CFStrHasContentsDeallocator(CFStringRef str) {return __CFRuntimeGetValue(str, 6, 5) == __kCFNotInlineContentsCustomFree;} -CF_INLINE Boolean __CFStrHasContentsAllocator(CFStringRef str) {return __CFRuntimeGetValue(str, 6, 5) == __kCFNotInlineContentsCustomFree;} // !!! Assumptions: // Mutable strings are not inline @@ -217,41 +214,28 @@ CF_INLINE Boolean __CFStrHasContentsAllocator(CFStringRef str) {return __CF /* The following set of functions and macros need to be updated on change to the bit configuration */ -CF_INLINE Boolean __CFStrIsMutable(CFStringRef str) {return __CFRuntimeGetFlag(str, __kCFIsMutable);} -CF_INLINE Boolean __CFStrIsUnicode(CFStringRef str) {return __CFRuntimeGetFlag(str, __kCFIsUnicode);} -CF_INLINE Boolean __CFStrIsEightBit(CFStringRef str) {return !__CFRuntimeGetFlag(str, __kCFIsUnicode);} -CF_INLINE Boolean __CFStrHasNullByte(CFStringRef str) {return __CFRuntimeGetFlag(str, __kCFHasNullByte);} -CF_INLINE Boolean __CFStrHasLengthByte(CFStringRef str) {return __CFRuntimeGetFlag(str, __kCFHasLengthByte);} -CF_INLINE Boolean __CFStrHasExplicitLength(CFStringRef str) { - // Has explicit length if (1) mutable or (2) not mutable and no length byte - const uint8_t isMutableMask = 1 | 4; // is_mutable_mask | has_length_byte_mask - const uint8_t hasLengthByteMask = 4; // has_length_byte_mask - return (__CFRuntimeGetValue(str, 2, 0) & isMutableMask) != hasLengthByteMask; -} - -CF_INLINE void __CFStrSetIsMutable(CFStringRef str) {__CFRuntimeSetFlag(str, __kCFIsMutable, true);} -CF_INLINE void __CFStrSetHasNullByte(CFStringRef str, Boolean flag) {__CFRuntimeSetFlag(str, __kCFHasNullByte, flag);} -CF_INLINE void __CFStrSetHasLengthByte(CFStringRef str, Boolean flag) {__CFRuntimeSetFlag(str, __kCFHasLengthByte, flag);} -CF_INLINE void __CFStrSetUnicode(CFMutableStringRef str, Boolean flag) {__CFRuntimeSetFlag(str, __kCFIsUnicode, flag);} - -CF_INLINE void __CFStrSetHasLengthAndNullBytes(CFMutableStringRef str) { - __CFStrSetHasLengthByte(str, true); - __CFStrSetHasNullByte(str, true); -} -CF_INLINE void __CFStrClearHasLengthAndNullBytes(CFMutableStringRef str) { - __CFStrSetHasLengthByte(str, false); - __CFStrSetHasNullByte(str, false); -} - +CF_INLINE Boolean __CFStrIsMutable(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsMutableMask) == __kCFIsMutable;} +CF_INLINE Boolean __CFStrIsInline(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFContentsMask) == __kCFHasInlineContents;} +CF_INLINE Boolean __CFStrFreeContentsWhenDone(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFFreeContentsWhenDoneMask) == __kCFFreeContentsWhenDone;} +CF_INLINE Boolean __CFStrHasContentsDeallocator(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasContentsDeallocatorMask) == __kCFHasContentsDeallocator;} +CF_INLINE Boolean __CFStrIsUnicode(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) == __kCFIsUnicode;} +CF_INLINE Boolean __CFStrIsEightBit(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFIsUnicodeMask) != __kCFIsUnicode;} +CF_INLINE Boolean __CFStrHasNullByte(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasNullByteMask) == __kCFHasNullByte;} +CF_INLINE Boolean __CFStrHasLengthByte(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasLengthByteMask) == __kCFHasLengthByte;} +CF_INLINE Boolean __CFStrHasExplicitLength(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & (__kCFIsMutableMask | __kCFHasLengthByteMask)) != __kCFHasLengthByte;} // Has explicit length if (1) mutable or (2) not mutable and no length byte CF_INLINE Boolean __CFStrIsConstant(CFStringRef str) { #if DEPLOYMENT_RUNTIME_SWIFT return str->base._swift_strong_rc & _CF_SWIFT_RC_PINNED_FLAG; #else - return __CFRuntimeIsConstant(str); +#if __LP64__ + return str->base._rc == 0; +#else + return (str->base._cfinfo[CF_RC_BITS]) == 0; +#endif #endif } -CF_INLINE SInt32 __CFStrSkipAnyLengthByte(CFStringRef str) {return __CFRuntimeGetFlag(str, __kCFHasLengthByte) ? 1 : 0;} // Number of bytes to skip over the length byte in the contents +CF_INLINE SInt32 __CFStrSkipAnyLengthByte(CFStringRef str) {return ((str->base._cfinfo[CF_INFO_BITS] & __kCFHasLengthByteMask) == __kCFHasLengthByte) ? 1 : 0;} // Number of bytes to skip over the length byte in the contents /* Returns ptr to the buffer (which might include the length byte). */ @@ -273,7 +257,7 @@ CF_INLINE CFAllocatorRef __CFStrContentsDeallocator(CFStringRef str) { // Assumption: Called with immutable strings only, and on strings that are known to have a contentsDeallocator CF_INLINE void __CFStrSetContentsDeallocator(CFStringRef str, CFAllocatorRef allocator) { - CFRetain(allocator); + if (!(0 || 0)) CFRetain(allocator); *__CFStrContentsDeallocatorPtr(str) = allocator; } @@ -290,7 +274,7 @@ CF_INLINE CFAllocatorRef __CFStrContentsAllocator(CFMutableStringRef str) { // Assumption: Called with strings that have a contents allocator; also, contents allocator follows custom CF_INLINE void __CFStrSetContentsAllocator(CFMutableStringRef str, CFAllocatorRef allocator) { - CFRetain(allocator); + if (!(0 || 0)) CFRetain(allocator); *(__CFStrContentsAllocatorPtr(str)) = allocator; } @@ -331,6 +315,7 @@ CF_INLINE void __CFStrSetContentPtr(CFStringRef str, const void *p) { // XXX_PCB catch all writes for mutable string case. *((void **)&((CFMutableStringRef)str)->variants.notInlineImmutable1.buffer) = (void *)p; } +CF_INLINE void __CFStrSetInfoBits(CFStringRef str, UInt32 v) {__CFBitfieldSetValue(((CFMutableStringRef)str)->base._cfinfo[CF_INFO_BITS], 6, 0, v);} CF_INLINE void __CFStrSetExplicitLength(CFStringRef str, CFIndex v) { if (__CFStrIsInline(str)) { @@ -340,9 +325,16 @@ CF_INLINE void __CFStrSetExplicitLength(CFStringRef str, CFIndex v) { } } +CF_INLINE void __CFStrSetUnicode(CFMutableStringRef str) {str->base._cfinfo[CF_INFO_BITS] |= __kCFIsUnicode;} +CF_INLINE void __CFStrClearUnicode(CFMutableStringRef str) {str->base._cfinfo[CF_INFO_BITS] &= ~__kCFIsUnicode;} +CF_INLINE void __CFStrSetHasLengthAndNullBytes(CFMutableStringRef str) {str->base._cfinfo[CF_INFO_BITS] |= (__kCFHasLengthByte | __kCFHasNullByte);} +CF_INLINE void __CFStrClearHasLengthAndNullBytes(CFMutableStringRef str) {str->base._cfinfo[CF_INFO_BITS] &= ~(__kCFHasLengthByte | __kCFHasNullByte);} + + // Assumption: The following set of inlines (using str->variants.notInlineMutable) are called with mutable strings only CF_INLINE Boolean __CFStrIsFixed(CFStringRef str) {return str->variants.notInlineMutable.isFixedCapacity;} CF_INLINE Boolean __CFStrIsExternalMutable(CFStringRef str) {return str->variants.notInlineMutable.isExternalMutable;} +CF_INLINE Boolean __CFStrHasContentsAllocator(CFStringRef str) {return (str->base._cfinfo[CF_INFO_BITS] & __kCFHasContentsAllocatorMask) == __kCFHasContentsAllocator;} CF_INLINE void __CFStrSetIsFixed(CFMutableStringRef str) {str->variants.notInlineMutable.isFixedCapacity = 1;} CF_INLINE void __CFStrSetIsExternalMutable(CFMutableStringRef str) {str->variants.notInlineMutable.isExternalMutable = 1;} //CF_INLINE void __CFStrSetHasGap(CFMutableStringRef str) {str->variants.notInlineMutable.hasGap = 1;} currently unused @@ -378,6 +370,15 @@ static void __CFStrDeallocateMutableContents(CFMutableStringRef str, void *buffe } } +#if 0 +// Mark contents from not freed at all to being managed by default allocator (happens on mutation of externally mutable buffer string which was set to no free) +CF_INLINE void __CFStrEnsureContentsFreeable(CFMutableStringRef str) { + if ((str->base._cfinfo[CF_INFO_BITS] & __kCFContentsMask) == __kCFNotInlineContentsNoFree) { + str->base._cfinfo[CF_INFO_BITS] &= ~__kCFContentsMask; + str->base._cfinfo[CF_INFO_BITS] |= __kCFNotInlineContentsDefaultFree; + } +} +#endif /* CFString specific init flags Note that you cannot count on the external buffer not being copied. @@ -678,7 +679,7 @@ CF_INLINE void push (CFStringStackInfo *si, const CFStringDeferredRange *newRang // increase size of the stack si->capacity = (si->capacity + 4) * 2; if (si->hasMalloced) { - si->stack = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, si->stack, si->capacity * sizeof(CFStringDeferredRange), 0, NULL); + si->stack = (CFStringDeferredRange *)CFAllocatorReallocate(kCFAllocatorSystemDefault, si->stack, si->capacity * sizeof(CFStringDeferredRange), 0); } else { CFStringDeferredRange *newStack = (CFStringDeferredRange *)CFAllocatorAllocate(kCFAllocatorSystemDefault, si->capacity * sizeof(CFStringDeferredRange), 0); memmove(newStack, si->stack, si->count * sizeof(CFStringDeferredRange)); @@ -828,10 +829,10 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange * __CFStrSetCapacity(str, 0); __CFStrClearCapacityProvidedExternally(str); __CFStrClearHasLengthAndNullBytes(str); - if (!__CFStrIsExternalMutable(str)) __CFStrSetUnicode(str, false); // External mutable implies Unicode + if (!__CFStrIsExternalMutable(str)) __CFStrClearUnicode(str); // External mutable implies Unicode } else { if (!__CFStrIsExternalMutable(str)) { - __CFStrSetUnicode(str, false); + __CFStrClearUnicode(str); if (curCapacity >= (int)(sizeof(uint8_t) * 2)) { // If there's room __CFStrSetHasLengthAndNullBytes(str); ((uint8_t *)curContents)[0] = ((uint8_t *)curContents)[1] = 0; @@ -895,9 +896,9 @@ static void __CFStringChangeSizeMultiple(CFMutableStringRef str, const CFRange * } else { if (hasLengthAndNullBytes) __CFStrClearHasLengthAndNullBytes(str); } - if (oldIsUnicode) __CFStrSetUnicode(str, false); + if (oldIsUnicode) __CFStrClearUnicode(str); } else { // New is unicode... - if (!oldIsUnicode) __CFStrSetUnicode(str, true); + if (!oldIsUnicode) __CFStrSetUnicode(str); if (hasLengthAndNullBytes) __CFStrClearHasLengthAndNullBytes(str); } __CFStrSetExplicitLength(str, newLength); @@ -938,7 +939,7 @@ static void __CFStringDeallocate(CFTypeRef cf) { if (__CFStrHasContentsDeallocator(str)) { CFAllocatorRef allocator = __CFStrContentsDeallocator(str); CFAllocatorDeallocate(allocator, contents); - CFRelease(allocator); + if (!(0 || 0 )) CFRelease(allocator); } else { CFAllocatorRef alloc = __CFGetAllocator(str); CFAllocatorDeallocate(alloc, contents); @@ -947,7 +948,7 @@ static void __CFStringDeallocate(CFTypeRef cf) { } if (isMutable && __CFStrHasContentsAllocator(str)) { CFAllocatorRef allocator = __CFStrContentsAllocator((CFMutableStringRef)str); - CFRelease(allocator); + if (!(0 || 0)) CFRelease(allocator); } } } @@ -998,9 +999,6 @@ static Boolean __CFStringEqual(CFTypeRef cf1, CFTypeRef cf2) { return true; } -CF_PRIVATE Boolean _CFStringEqual(CFStringRef cf1, CFStringRef cf2) { - return __CFStringEqual(cf1, cf2); -} /* String hashing: Should give the same results whatever the encoding; so we hash UniChars. If the length is less than or equal to 96, then the hash function is simply the @@ -1327,7 +1325,7 @@ CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3( if (vBuf.shouldFreeChars && (alloc == vBuf.allocator) && encoding == kCFStringEncodingUnicode) { vBuf.shouldFreeChars = false; // Transferring ownership to the CFString - bytes = __CFSafelyReallocateWithAllocator(vBuf.allocator, (void *)vBuf.chars.unicode, numBytes, 0, NULL); // Tighten up the storage + bytes = CFAllocatorReallocate(vBuf.allocator, (void *)vBuf.chars.unicode, numBytes, 0); // Tighten up the storage noCopy = true; #if INSTRUMENT_SHARED_STRINGS if (encoding == kCFStringEncodingASCII) recordedEncoding = "ForeignASCII-NoCopy"; @@ -1504,11 +1502,12 @@ CF_PRIVATE CFStringRef __CFStringCreateImmutableFunnel3( if (str) { if (__CFOASafe) __CFSetLastAllocationEventName(str, "CFString (immutable)"); - _CFStringInlineContents allocBits = contentsDeallocator == alloc ? __kCFNotInlineContentsDefaultFree : (contentsDeallocator == kCFAllocatorNull ? __kCFNotInlineContentsNoFree : __kCFNotInlineContentsCustomFree); - __CFStrSetInlineContents(str, useInlineData ? __kCFHasInlineContents : allocBits); - __CFStrSetUnicode(str, encoding == kCFStringEncodingUnicode); - __CFStrSetHasNullByte(str, useNullByte); - __CFStrSetHasLengthByte(str, useLengthByte); + CFOptionFlags allocBits = (0) ? __kCFHasContentsDeallocator : (contentsDeallocator == alloc ? __kCFNotInlineContentsDefaultFree : (contentsDeallocator == kCFAllocatorNull ? __kCFNotInlineContentsNoFree : __kCFNotInlineContentsCustomFree)); + __CFStrSetInfoBits(str, + (useInlineData ? __kCFHasInlineContents : allocBits) | + ((encoding == kCFStringEncodingUnicode) ? __kCFIsUnicode : 0) | + (useNullByte ? __kCFHasNullByte : 0) | + (useLengthByte ? __kCFHasLengthByte : 0)); if (!useLengthByte) { CFIndex length = numBytes - (hasLengthByte ? 1 : 0); @@ -1607,18 +1606,6 @@ CFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t * return __CFStringCreateImmutableFunnel3(alloc, bytes, numBytes, encoding, externalFormat, true, false, false, true, contentsDeallocator, 0); } -CFStringRef CFStringCreateStringWithValidatedFormat(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef validFormatSpecifiers, CFStringRef format, va_list arguments, CFErrorRef *errorPtr) { - CFStringRef str; - CFMutableStringRef outputString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); //should use alloc if no copy/release - __CFStrSetDesiredCapacity(outputString, 120); // Given this will be tightened later, choosing a larger working string is fine - __CFStringAppendFormatCore(outputString, NULL, NULL, formatOptions, NULL, validFormatSpecifiers, format, 0, NULL, 0, arguments, errorPtr); - // ??? copy/release should not be necessary here -- just make immutable, compress if possible - // (However, this does make the string inline, and cause the supplied allocator to be used...) - str = (CFStringRef)CFStringCreateCopy(alloc, outputString); - CFRelease(outputString); - return str; -} - CFStringRef CFStringCreateWithFormatAndArguments(CFAllocatorRef alloc, CFDictionaryRef formatOptions, CFStringRef format, va_list arguments) { return _CFStringCreateWithFormatAndArgumentsAux2(alloc, NULL, NULL, formatOptions, format, arguments); } @@ -1627,7 +1614,7 @@ CFStringRef _CFStringCreateWithFormatAndArgumentsAux2(CFAllocatorRef alloc, CFS CFStringRef str; CFMutableStringRef outputString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0); //should use alloc if no copy/release __CFStrSetDesiredCapacity(outputString, 120); // Given this will be tightened later, choosing a larger working string is fine - __CFStringAppendFormatCore(outputString, copyDescFunc, contextDescFunc, formatOptions, NULL, NULL, format, 0, NULL, 0, arguments, NULL); + __CFStringAppendFormatCore(outputString, copyDescFunc, contextDescFunc, formatOptions, NULL, format, 0, NULL, 0, arguments); // ??? copy/release should not be necessary here -- just make immutable, compress if possible // (However, this does make the string inline, and cause the supplied allocator to be used...) str = (CFStringRef)CFStringCreateCopy(alloc, outputString); @@ -1823,7 +1810,11 @@ CFStringRef __CFStringMakeConstantString(const char *cStr) { if (CFDictionaryGetCount(constantStringTable) == count) { // add did nothing, someone already put it there result = (CFStringRef)CFDictionaryGetValue(constantStringTable, key); } else if (!isTaggedPointerString) { - __CFRuntimeSetRC(result, 0); +#if __LP64__ + ((struct __CFString *)result)->base._rc = 0; +#else + ((struct __CFString *)result)->base._cfinfo[CF_RC_BITS] = 0; +#endif } __CFUnlock(&_CFSTRLock); // This either eliminates the extra retain on the freshly created string, or frees it, if it was actually not inserted into the table @@ -1925,9 +1916,10 @@ CF_INLINE void __CFStringReplace(CFMutableStringRef str, CFRange range, CFString */ #define DEFAULTMINCAPACITY 32 -CF_INLINE CFMutableStringRef __CFStringCreateMutableFunnel(CFAllocatorRef alloc, CFIndex maxLength, _CFStringInlineContents inlineContents, Boolean isUnicode) { +CF_INLINE CFMutableStringRef __CFStringCreateMutableFunnel(CFAllocatorRef alloc, CFIndex maxLength, UInt32 additionalInfoBits) { CFMutableStringRef str; - Boolean hasExternalContentsAllocator = (inlineContents == __kCFNotInlineContentsCustomFree); + if ((0)) additionalInfoBits |= __kCFHasContentsAllocator; + Boolean hasExternalContentsAllocator = (additionalInfoBits & __kCFHasContentsAllocator) ? true : false; if (alloc == NULL) alloc = __CFGetDefaultAllocator(); @@ -1936,9 +1928,7 @@ CF_INLINE CFMutableStringRef __CFStringCreateMutableFunnel(CFAllocatorRef alloc, if (str) { if (__CFOASafe) __CFSetLastAllocationEventName(str, "CFString (mutable)"); - __CFStrSetInlineContents(str, inlineContents); - __CFStrSetUnicode(str, isUnicode); - __CFStrSetIsMutable(str); + __CFStrSetInfoBits(str, __kCFIsMutable | additionalInfoBits); str->variants.notInlineMutable.buffer = NULL; __CFStrSetExplicitLength(str, 0); str->variants.notInlineMutable.hasGap = str->variants.notInlineMutable.isFixedCapacity = str->variants.notInlineMutable.isExternalMutable = str->variants.notInlineMutable.capacityProvidedExternally = 0; @@ -1954,13 +1944,13 @@ CF_INLINE CFMutableStringRef __CFStringCreateMutableFunnel(CFAllocatorRef alloc, } CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocatorRef alloc, UniChar *chars, CFIndex numChars, CFIndex capacity, CFAllocatorRef externalCharactersAllocator) { - _CFStringInlineContents contentsAllocationBits = externalCharactersAllocator ? ((externalCharactersAllocator == kCFAllocatorNull) ? __kCFNotInlineContentsNoFree : __kCFNotInlineContentsCustomFree) : __kCFNotInlineContentsDefaultFree; - CFMutableStringRef string = __CFStringCreateMutableFunnel(alloc, 0, contentsAllocationBits, true); + CFOptionFlags contentsAllocationBits = externalCharactersAllocator ? ((externalCharactersAllocator == kCFAllocatorNull) ? __kCFNotInlineContentsNoFree : __kCFHasContentsAllocator) : __kCFNotInlineContentsDefaultFree; + CFMutableStringRef string = __CFStringCreateMutableFunnel(alloc, 0, contentsAllocationBits | __kCFIsUnicode); if (string) { __CFStrSetIsExternalMutable(string); if (__CFStrHasContentsAllocator(string)) { CFAllocatorRef allocator = __CFStrContentsAllocator((CFMutableStringRef)string); - CFRelease(allocator); + if (!(0 || 0)) CFRelease(allocator); __CFStrSetContentsAllocator(string, externalCharactersAllocator); } CFStringSetExternalCharactersNoCopy(string, chars, numChars, capacity); @@ -1969,7 +1959,7 @@ CFMutableStringRef CFStringCreateMutableWithExternalCharactersNoCopy(CFAllocator } CFMutableStringRef CFStringCreateMutable(CFAllocatorRef alloc, CFIndex maxLength) { - return __CFStringCreateMutableFunnel(alloc, maxLength, __kCFNotInlineContentsDefaultFree, false); + return __CFStringCreateMutableFunnel(alloc, maxLength, __kCFNotInlineContentsDefaultFree); } CFMutableStringRef CFStringCreateMutableCopy(CFAllocatorRef alloc, CFIndex maxLength, CFStringRef string) { @@ -2305,7 +2295,6 @@ CF_INLINE bool _CFCanUseLocale(CFLocaleRef locale) { } #define MAX_CASE_MAPPING_BUF (8) -#define WHITE_SPACE_CHARACTER (0x0020) #define ZERO_WIDTH_JOINER (0x200D) #define COMBINING_GRAPHEME_JOINER (0x034F) // Hangul ranges @@ -3244,7 +3233,7 @@ Boolean CFStringFindWithOptionsAndLocale(CFStringRef string, CFStringRef stringT do { str1Char = CFStringGetCharacterFromInlineBuffer(&inlineBuf1, --index); - } while (CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP), (rangeToSearch.location < index)); + } while (CFUniCharIsMemberOfBitmap(str1Char, graphemeBMP) && (rangeToSearch.location < index)); if (str1Char < 0x0510) { while (++str1Index < maxStr1Index) if (!CFUniCharIsMemberOfBitmap(CFStringGetCharacterFromInlineBuffer(&inlineBuf1, str1Index), graphemeBMP)) break; @@ -3433,8 +3422,6 @@ enum { kCFStringHangulStateBreak }; -#pragma mark FitzPatrick (skin tone) Modifier Functions - static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCharacterSet(void) { static CFCharacterSetInlineBuffer buffer; static dispatch_once_t initOnce; @@ -3446,13 +3433,11 @@ static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCha U+270A RAISED FIST…U+270D WRITING HAND U+1F385 FATHER CHRISTMAS U+1F3C2 SNOWBOARDER…U+1F3C4 SURFER - U+1F3C7 HORSE RACING U+1F3CA SWIMMER - U+1F3CC GOLFER U+1F442 EAR…U+1F443 NOSE U+1F446 WHITE UP POINTING BACKHAND INDEX…U+1F450 OPEN HANDS SIGN U+1F466 BOY…U+1F469 WOMAN - U+1F46A FAMILY…U+1F46F WOMAN WITH BUNNY EARS + U+1F46E POLICE OFFICER U+1F470 BRIDE WITH VEIL…U+1F478 PRINCESS U+1F47C BABY ANGEL U+1F47F IMP @@ -3461,7 +3446,6 @@ static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCha U+1F485 NAIL POLISH U+1F486 FACE MASSAGE…U+1F487 HAIRCUT U+1F4AA FLEXED BICEPS - U+1F574 MAN IN BUSINESS SUIT LEVITATING U+1F575 SLEUTH OR SPY U+1F590 RAISED HAND WITH FINGERS SPLAYED U+1F595 REVERSED HAND WITH MIDDLE FINGER EXTENDED…U+1F596 RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS @@ -3474,50 +3458,12 @@ static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCha U+1F6A3 ROWBOAT U+1F6B4 BICYCLIST…U+1F6B6 PEDESTRIAN U+1F6C0 BATH - U+1F6CC SLEEPING ACCOMMODATION U+1F910 ZIPPER-MOUTH FACE…U+1F915 FACE WITH HEAD-BANDAGE U+1F917 HUGGING FACE…U+1F918 SIGN OF THE HORNS 9.0 U+26F9 PERSON WITH BALL U+1F3CB WEIGHT LIFTER - U+1F57A MAN DANCING - U+1F919 CALL ME HAND - U+1F91A RAISED BACK OF HAND - U+1F91B LEFT-FACING FIST - U+1F91C RIGHT-FACING FIST - U+1F91D HANDSHAKE - U+1F91E HAND WITH INDEX AND MIDDLE FINGERS CROSSED - U+1F926 FACE PALM - U+1F930 PREGNANT WOMAN - U+1F933 SELFIE - U+1F934 PRINCE - U+1F935 MAN IN TUXEDO - U+1F936 MOTHER CHRISTMAS - U+1F937 SHRUG - U+1F938 PERSON DOING CARTWHEEL - U+1F939 JUGGLING - U+1F93C WRESTLERS - U+1F93D WATER POLO - U+1F93E HANDBALL - - 10.0 - U+1F91F LOVE-YOU GESTURE - U+1F931 BREAST-FEEDING - U+1F932 PALMS UP TOGETHER - U+1F9D1 ADULT - U+1F9D2 CHILD - U+1F9D3 OLDER ADULT - U+1F9D4 BEARDED PERSON - U+1F9D5 PERSON WITH HEADSCARF [WOMAN WITH HEADSCARF] - U+1F9D6 PERSON IN STEAMY ROOM - U+1F9D7 PERSON CLIMBING - U+1F9D8 PERSON IN LOTUS POSITION - U+1F9D9 MAGE - U+1F9DA FAIRY - U+1F9DB VAMPIRE - U+1F9DC MERPERSON - U+1F9DD ELF */ CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x261D, 1)); // WHITE UP POINTING INDEX @@ -3525,22 +3471,18 @@ static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCha CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x270A, 4)); // RAISED FIST ~ WRITING HAND CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F385, 1)); // FATHER CHRISTMAS CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C2, 3)); // SNOWBOARDER ~ SURFER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3C7, 1)); // HORSE RACING CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CA, 1)); // SWIMMER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CC, 1)); // GOLFER CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F442, 2)); // EAR ~ NOSE CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F446, 0x1F451 - 0x1F446)); // WHITE UP POINTING BACKHAND INDEX ~ OPEN HANDS SIGN CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F466, 4)); // BOY ~ WOMAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F46A, 6)); // FAMILY…U+1F46F WOMAN WITH BUNNY EARS + CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F46E, 1)); // POLICE OFFICER CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F470, 0x1F479 - 0x1F470)); // BRIDE WITH VEIL ~ PRINCESS CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F47C, 1)); // BABY ANGEL CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F47F, 1)); // IMP CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F481, 3)); // INFORMATION DESK PERSON ~ DANCER CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F485, 3)); // NAIL POLISH ~ HAIRCUT CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4AA, 1)); // FLEXED BICEPS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F574, 1)); // MAN IN BUSINESS SUIT LEVITATING CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F575, 1)); // SLEUTH OR SPY - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F57A, 1)); // MAN DANCING CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F590, 1)); // RAISED HAND WITH FINGERS SPLAYED CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F595, 2)); // REVERSED HAND WITH MIDDLE FINGER EXTENDED ~ RAISED HAND WITH PART BETWEEN MIDDLE AND RING FINGERS CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F600, 0x1F638 - 0x1F600)); // GRINNING FACE ~ FACE WITH MEDICAL MASK @@ -3549,16 +3491,8 @@ static const CFCharacterSetInlineBuffer *__CFStringGetFitzpatrickModifierBaseCha CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6A3, 1)); // ROWBOAT CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B4, 0x1F6B7 - 0x1F6B4)); // BICYCLIST ~ PEDESTRIAN CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6C0, 1)); // BATH - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6CC, 1)); // SLEEPING ACCOMMODATION CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F910, 0x1F916 - 0x1F910)); // U+1F910 ZIPPER-MOUTH FACE…U+1F915 FACE WITH HEAD-BANDAGE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F917, 8)); // U+1F917 HUGGING FACE…U+1F91E HAND WITH INDEX AND MIDDLE FINGERS CROSSED - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F91F, 1)); // LOVE-YOU GESTURE - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F926, 1)); // FACE PALM - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F930, 3)); // PREGNANT WOMAN ~ PALMS UP TOGETHER - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F933, 4)); // SELFIE ~ MOTHER CHRISTMAS - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F937, 3)); // SHRUG ~ JUGGLING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F93C, 3)); // WRESTLERS ~ HANDBALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F9D1, 13)); // ADULT ~ ELF + CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F917, 2)); // U+1F917 HUGGING FACE…U+1F918 SIGN OF THE HORNS CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x26F9, 1)); // U+26F9 PERSON WITH BALL CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3CB, 1)); // U+1F3CB WEIGHT LIFTER CFCharacterSetCompact(cset); @@ -3576,16 +3510,12 @@ static inline bool __CFStringIsBaseForFitzpatrickModifiers(UTF32Char character) return false; } -static inline bool __CFStringIsTagSequence(UTF32Char character) { return ((character >= 0xE0020) && (character <= 0xE007F) ? true : false); } - -#pragma mark Gender Modifier Functions static const CFCharacterSetInlineBuffer *__CFStringGetGenderModifierBaseCharacterSet(void) { static CFCharacterSetInlineBuffer buffer; static dispatch_once_t initOnce; dispatch_once(&initOnce, ^{ /* - Unicode 8.0 ⛹U+26F9 PERSON WITH BALL // 0x26F9 🏃U+1F3C3 RUNNER // 0xD83C 0xDFC3 🏄U+1F3C4 SURFER // 0xD83C 0xDFC4 @@ -3612,27 +3542,6 @@ static const CFCharacterSetInlineBuffer *__CFStringGetGenderModifierBaseCharacte 🚴U+1F6B4 BICYCLIST // 0xD83D 0xDEB4 🚵U+1F6B5 MOUNTAIN BICYCLIST // 0xD83D 0xDEB5 🚶U+1F6B6 PEDESTRIAN // 0xD83D 0xDEB6 - - Unicode 9.0 - U+1F926 FACE PALM - U+1F937 SHRUG - U+1F938 PERSON DOING CARTWHEEL - U+1F939 JUGGLING - U+1F93C WRESTLERS - U+1F93D WATER POLO - U+1F93E HANDBALL - - Unicode 10.0 - U+1F9D6 PERSON IN STEAMY ROOM - U+1F9D7 PERSON CLIMBING - U+1F9D8 PERSON IN LOTUS POSITION - U+1F9D9 MAGE - U+1F9DA FAIRY - U+1F9DB VAMPIRE - U+1F9DC MERPERSON - U+1F9DD ELF - U+1F9DE GENIE - U+1F9DF ZOMBIE */ CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x26F9, 1)); // PERSON WITH BALL @@ -3661,10 +3570,6 @@ static const CFCharacterSetInlineBuffer *__CFStringGetGenderModifierBaseCharacte CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B4, 1)); // BICYCLIST CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B5, 1)); // MOUNTAIN BICYCLIST CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F6B6, 1)); // PEDESTRIAN - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F926, 1)); // FACE PALM - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F937, 3)); // SHRUG ~ JUGGLING - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F93C, 3)); // WRESTLERS ~ HANDBALL - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F9D6, 10)); // PERSON IN STEAMY ROOM ~ ZOMBIE CFCharacterSetCompact(cset); CFCharacterSetInitInlineBuffer(cset, &buffer); }); @@ -3700,77 +3605,6 @@ static inline bool __CFStringIsGenderModifierCluster(CFStringInlineBuffer *buffe return (__CFStringIsGenderModifier(character) && ((range.length == 1) || (0xFE0F == CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1)))); // Either modifier is alone or is followed by FEOF } -#pragma mark Profession Modifier Functions - -static inline bool __CFStringIsBaseForManOrWomanCluster(UTF16Char character) { - return ((character == 0xDC68) || (character == 0xDC69)); // Low surrogate chars representing MAN (U+1F468) and WOMAN (U+1F469) respectively -} - -static inline bool __CFStringIsProfessionBaseCluster(CFStringInlineBuffer *buffer, CFRange range) { - // The code here in this method follows the same structure as __CFStringIsGenderModifierBaseCluster() above in that it separates the high and low surrogate chars and passes the low surrogate char to __CFStringIsBaseForManOrWomanCluster(). - if (range.length > 1) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - if (CFUniCharIsSurrogateHighCharacter(character)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1); - if (CFUniCharIsSurrogateLowCharacter(otherCharacter)) { - return __CFStringIsBaseForManOrWomanCluster(otherCharacter); - } - } - } - return false; -} - -static const CFCharacterSetInlineBuffer *__CFStringGetProfessionModifierBaseCharacterSet(void) { - static CFCharacterSetInlineBuffer buffer; - static dispatch_once_t initOnce; - dispatch_once(&initOnce, ^{ - /* Unicode 9.0 - Supported profession modifiers */ - CFMutableCharacterSetRef cset = CFCharacterSetCreateMutable(NULL); - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2695, 1)); // ⚕U+2695 STAFF OF AESCULAPIUS // Health Worker - 0x2695 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F33E, 1)); // 🌾U+1F33E EAR OF RICE // Farmer - 0xD83C 0xDF3E - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F373, 1)); // 🍳U+1F373 COOKING // Cook - 0xD83C 0xDF73 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F393, 1)); // 🎓U+1F393 GRADUATION CAP // Student - 0xD83C 0xDF93 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3A4, 1)); // 🎤U+1F3A4 MICROPHONE // Singer - 0xD83C 0xDFA4 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3EB, 1)); // 🏫U+1F3EB SCHOOL // Teacher - 0xD83C 0xDFEB - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3ED, 1)); // 🏭U+1F3ED FACTORY // Factory Worker - 0xD83C 0XDFED - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4BB, 1)); // 💻U+1F4BB PERSONAL COMPUTER // Technologist - 0xD83D 0xDCBB - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F4BC, 1)); // 💼U+1F4BC BRIEFCASE // Office Worker - 0xD83D 0xDCBC - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F527, 1)); // 🔧U+1F527 WRENCH // Mechanic - 0xD83D 0xDD27 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F52C, 1)); // 🔬U+1F52C MICROSCOPE // Scientist - 0xD83D 0xDD2C - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F3A8, 1)); // 🎨U+1F3A8 ARTIST PALETTE // Artist - 0xD83C 0xDFA8 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F692, 1)); // 🚒U+1F692 FIRE ENGINE // Firefighter - 0xD83D 0xDE92 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2708, 1)); // ✈️U+2708 AIRPLANE // Pilot - 0x2708 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x1F680, 1)); // 🚀U+1F680 ROCKET // Astronaut - 0xD83D 0xDE80 - CFCharacterSetAddCharactersInRange(cset, CFRangeMake(0x2696, 1)); // ⚖️U+2696 SCALES // Judge - 0x2696 - CFCharacterSetCompact(cset); - CFCharacterSetInitInlineBuffer(cset, &buffer); - }); - return (const CFCharacterSetInlineBuffer *)&buffer; -} - -static inline bool __CFStringIsBaseForProfessionModifier(UTF32Char character) { - if (((character >= 0x2600) && (character < 0x3000)) || ((character >= 0x1F300) && (character < 0x1FA00))) { // Misc symbols, dingbats, & emoticons - return CFCharacterSetInlineBufferIsLongCharacterMember(__CFStringGetProfessionModifierBaseCharacterSet(), character); - } - return false; -} - -static inline bool __CFStringIsProfessionModifierCluster(CFStringInlineBuffer *buffer, CFRange range) { - UTF16Char character = CFStringGetCharacterFromInlineBuffer(buffer, range.location); - UTF32Char baseCharacter = character; - if (range.length > 1) { - if (CFUniCharIsSurrogateHighCharacter(character)) { - UTF16Char otherCharacter = CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1); - if (CFUniCharIsSurrogateLowCharacter(otherCharacter)) { - baseCharacter = CFUniCharGetLongCharacterForSurrogatePair(character, otherCharacter); - } - } - } - return __CFStringIsBaseForProfessionModifier(baseCharacter); -} - -#pragma mark Family Cluster Functions - static inline bool __CFStringIsFamilySequenceBaseCharacterHigh(UTF16Char character) { return (character == 0xD83D) ? true : false; } static inline bool __CFStringIsFamilySequenceBaseCharacterLow(UTF16Char character) { return (((character >= 0xDC66) && (character <= 0xDC69)) || (character == 0xDC8B) || (character == 0xDC41) || (character == 0xDDE8) ? true : false); } static inline bool __CFStringIsFamilySequenceCluster(CFStringInlineBuffer *buffer, CFRange range) { @@ -3784,8 +3618,6 @@ static inline bool __CFStringIsFamilySequenceCluster(CFStringInlineBuffer *buffe return false; } -#pragma mark Regional Indicator Functions - #define RI_SURROGATE_HI (0xD83C) static inline bool __CFStringIsRegionalIndicatorSurrogateLow(UTF16Char character) { return (character >= 0xDDE6) && (character <= 0xDDFF) ? true : false; } @@ -3793,7 +3625,6 @@ static inline bool __CFStringIsRegionalIndicatorAtIndex(CFStringInlineBuffer *bu return ((CFStringGetCharacterFromInlineBuffer(buffer, index) == RI_SURROGATE_HI) && __CFStringIsRegionalIndicatorSurrogateLow(CFStringGetCharacterFromInlineBuffer(buffer, index + 1))) ? true : false; } -#pragma mark White/Rainbow Flag Functions static inline bool __CFStringIsWavingWhiteFlagCluster(CFStringInlineBuffer *buffer, CFRange range) { return ((CFStringGetCharacterFromInlineBuffer(buffer, range.location) == RI_SURROGATE_HI) && (CFStringGetCharacterFromInlineBuffer(buffer, range.location + 1) == 0xDFF3)); } @@ -3845,7 +3676,7 @@ static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffe if (!__CFStringIsBaseForFitzpatrickModifiers(baseCharacter)) break; } else { - if (!CFUniCharIsMemberOfBitmap(character, bitmap) && !__CFStringIsTagSequence(character) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; + if (!CFUniCharIsMemberOfBitmap(character, bitmap) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; } --start; @@ -3953,7 +3784,7 @@ static CFRange _CFStringInlineBufferGetComposedRange(CFStringInlineBuffer *buffe step = 1; } - if ((!prevIsFitzpatrickBase || !__CFStringIsFitzpatrickModifiers(character)) && !CFUniCharIsMemberOfBitmap(character, bitmap) && !__CFStringIsTagSequence(character) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; + if ((!prevIsFitzpatrickBase || !__CFStringIsFitzpatrickModifiers(character)) && !CFUniCharIsMemberOfBitmap(character, bitmap) && (character != 0xFF9E) && (character != 0xFF9F) && ((character & 0x1FFFF0) != 0xF870)) break; prevIsFitzpatrickBase = __CFStringIsBaseForFitzpatrickModifiers(character); @@ -4136,6 +3967,11 @@ CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex ch if (range.location > 1) { CFIndex prev = range.location - 1; UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); + // if prevChar is still not zwj, try again + if ((prevCharacter != ZERO_WIDTH_JOINER) && (prev > 1)) { + prev--; + prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); + } if (prevCharacter == ZERO_WIDTH_JOINER) { aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); if (__CFStringIsWavingWhiteFlagCluster(&stringBuffer, aCluster)) { @@ -4168,41 +4004,14 @@ CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex ch if (range.location > 1) { CFIndex prev = range.location - 1; UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); - if (prevCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); - if (__CFStringIsGenderModifierBaseCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location; - } - if (currentIndex < range.location) { - range.length += range.location - currentIndex; - range.location = currentIndex; - } - } - } - } else if (__CFStringIsProfessionBaseCluster(&stringBuffer, range)) { - CFIndex end = range.location + range.length - 1; - if ((end + 1) < length) { - UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (endCharacter != ZERO_WIDTH_JOINER) { - end++; - endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); + // if prevChar is still not zwj, try again + if ((prevCharacter != ZERO_WIDTH_JOINER) && (prev > 1)) { + prev--; + prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); } - if (endCharacter == ZERO_WIDTH_JOINER) { - aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - if (__CFStringIsProfessionModifierCluster(&stringBuffer, aCluster)) { - currentIndex = aCluster.location + aCluster.length; - if ((aCluster.length > 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, currentIndex - 1))) --currentIndex; - } - if (currentIndex > (range.location + range.length)) range.length = currentIndex - range.location; - } - } - } else if (__CFStringIsProfessionModifierCluster(&stringBuffer, range)) { - if (range.location > 1) { - CFIndex prev = range.location - 1; - UTF32Char prevCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, prev); if (prevCharacter == ZERO_WIDTH_JOINER) { aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, prev - 1, type, bmpBitmap, csetType); - if (__CFStringIsProfessionBaseCluster(&stringBuffer, aCluster)) { + if (__CFStringIsGenderModifierBaseCluster(&stringBuffer, aCluster)) { currentIndex = aCluster.location; } if (currentIndex < range.location) { @@ -4215,14 +4024,13 @@ CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex ch // range is zwj CFIndex end = range.location + range.length - 1; UTF32Char endCharacter = CFStringGetCharacterFromInlineBuffer(&stringBuffer, end); - if (((end + 1) < length) && ((endCharacter == ZERO_WIDTH_JOINER) || (endCharacter == WHITE_SPACE_CHARACTER))) { + if (((end + 1) < length) && (endCharacter == ZERO_WIDTH_JOINER)) { // Get cluster before and after zwj. Range length of zwj cluster is always 1. CFRange rangeBeforeZWJ = _CFStringInlineBufferGetComposedRange(&stringBuffer, end - 1, type, bmpBitmap, csetType); aCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, end + 1, type, bmpBitmap, csetType); - if (((__CFStringIsWavingWhiteFlagCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsRainbowCluster(&stringBuffer, aCluster))) - || ((__CFStringIsGenderModifierBaseCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsGenderModifierCluster(&stringBuffer, aCluster))) - || ((__CFStringIsProfessionBaseCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsProfessionModifierCluster(&stringBuffer, aCluster)))) { + if (((__CFStringIsWavingWhiteFlagCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsRainbowCluster(&stringBuffer, aCluster))) || + ((__CFStringIsGenderModifierBaseCluster(&stringBuffer, rangeBeforeZWJ)) && (__CFStringIsGenderModifierCluster(&stringBuffer, aCluster)))) { range.location = rangeBeforeZWJ.location; range.length += rangeBeforeZWJ.length + aCluster.length; } @@ -4277,24 +4085,6 @@ CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex ch } } - // Gather the final grapheme extends - CFRange finalCluster; - - // Backwards - if ((range.location > 0) && (range.length == 1) && (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, range.location))) { - finalCluster = _CFStringInlineBufferGetComposedRange(&stringBuffer, range.location - 1, type, bmpBitmap, csetType); - if (range.location == (finalCluster.location + finalCluster.length)) { - range = finalCluster; - ++range.length; - } - } - // Forwards - if ((range.location + range.length) < length) { - if (ZERO_WIDTH_JOINER == CFStringGetCharacterFromInlineBuffer(&stringBuffer, range.location + range.length)) { - ++range.length; - } - } - return range; } @@ -4931,7 +4721,7 @@ CFIndex CFStringFindAndReplace(CFMutableStringRef string, CFStringRef stringToFi bool firstAlloc = (ranges == rangeBuffer) ? true : false; capacity = (capacity + 4) * 2; // Note that reallocate with NULL previous pointer is same as allocate - ranges = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, firstAlloc ? NULL : ranges, capacity * sizeof(CFRange), 0, NULL); + ranges = (CFRange *)CFAllocatorReallocate(kCFAllocatorSystemDefault, firstAlloc ? NULL : ranges, capacity * sizeof(CFRange), 0); if (firstAlloc) memmove(ranges, rangeBuffer, MAX_RANGES_ON_STACK * sizeof(CFRange)); } ranges[foundCount] = foundRange; @@ -5545,7 +5335,7 @@ void CFStringNormalize(CFMutableStringRef string, CFStringNormalizationForm theF mappedCharacters = (UTF32Char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, allocatedLength * sizeof(UTF32Char), 0); memmove(mappedCharacters, buffer, MAX_DECOMP_BUF * sizeof(UTF32Char)); } else { - mappedCharacters = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, mappedCharacters, allocatedLength * sizeof(UTF32Char), 0, NULL); + mappedCharacters = (UTF32Char *)CFAllocatorReallocate(kCFAllocatorSystemDefault, mappedCharacters, allocatedLength * sizeof(UTF32Char), 0); } } if (CFUniCharIsMemberOfBitmap(currentChar, ((currentChar < 0x10000) ? decompBMP : CFUniCharGetBitmapPtrForPlane(kCFUniCharCanonicalDecomposableCharacterSet, (currentChar >> 16))))) { // Vietnamese accent, etc. @@ -5573,7 +5363,7 @@ void CFStringNormalize(CFMutableStringRef string, CFStringNormalizationForm theF mappedCharacters = (UTF32Char *)CFAllocatorAllocate(kCFAllocatorSystemDefault, allocatedLength * sizeof(UTF32Char), 0); memmove(mappedCharacters, buffer, MAX_DECOMP_BUF * sizeof(UTF32Char)); } else { - mappedCharacters = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, mappedCharacters, allocatedLength * sizeof(UTF32Char), 0, NULL); + mappedCharacters = (UTF32Char *)CFAllocatorReallocate(kCFAllocatorSystemDefault, mappedCharacters, allocatedLength * sizeof(UTF32Char), 0); } } } @@ -6487,230 +6277,17 @@ reswtch:switch (ch) { /* These three functions are the external entry points for string formatting. */ void CFStringAppendFormatAndArguments(CFMutableStringRef outputString, CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) { - __CFStringAppendFormatCore(outputString, NULL, NULL, formatOptions, NULL, NULL, formatString, 0, NULL, 0, args, NULL); + __CFStringAppendFormatCore(outputString, NULL, NULL, formatOptions, NULL, formatString, 0, NULL, 0, args); } void _CFStringAppendFormatAndArgumentsAux2(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) { - __CFStringAppendFormatCore(outputString, copyDescFunc, contextDescFunc, formatOptions, NULL, NULL, formatString, 0, NULL, 0, args, NULL); + __CFStringAppendFormatCore(outputString, copyDescFunc, contextDescFunc, formatOptions, NULL, formatString, 0, NULL, 0, args); } void _CFStringAppendFormatAndArgumentsAux(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFDictionaryRef formatOptions, CFStringRef formatString, va_list args) { _CFStringAppendFormatAndArgumentsAux2(outputString, copyDescFunc, NULL, formatOptions, formatString, args); } -SInt32 __CFStringFindFormatSpecifiersInString(const uint8_t *cformat, const UniChar *uformat, CFIndex formatLen, CFFormatSpec *specs, CFStringRef *formatSpecs, CFIndex *numFormatSpecs) { - SInt32 curSpec, formatIdx; - /* Collect format specification information from the format string */ - for (curSpec = 0, formatIdx = 0; formatIdx < formatLen; curSpec++) { - SInt32 newFmtIdx; - specs[curSpec].loc = formatIdx; - specs[curSpec].len = 0; - specs[curSpec].size = 0; - specs[curSpec].type = 0; - specs[curSpec].flags = 0; - specs[curSpec].widthArg = -1; - specs[curSpec].precArg = -1; - specs[curSpec].mainArgNum = -1; - specs[curSpec].precArgNum = -1; - specs[curSpec].widthArgNum = -1; - specs[curSpec].configDictIndex = -1; - if (cformat) { - for (newFmtIdx = formatIdx; newFmtIdx < formatLen && '%' != cformat[newFmtIdx]; newFmtIdx++); - } else { - for (newFmtIdx = formatIdx; newFmtIdx < formatLen && '%' != uformat[newFmtIdx]; newFmtIdx++); - } - if (newFmtIdx != formatIdx) { /* Literal chunk */ - if (curSpec > -1) { - curSpec--; /* Skip by writing the next spec over this one */ - } - } else { - CFStringRef configKey = NULL; - newFmtIdx++; /* Skip % */ - __CFParseFormatSpec(uformat, cformat, &newFmtIdx, formatLen, &(specs[curSpec]), &configKey); - if (CFFormatLiteralType == specs[curSpec].type) { - if (curSpec > -1) { - curSpec--; /* Skip literal chunks by writing the next spec over this one*/ - } - } else { - specs[curSpec].len = newFmtIdx - formatIdx; - - // Copy the format string out - switch (specs[curSpec].type) { - case CFFormatLongType: - case CFFormatDoubleType: - case CFFormatPointerType: - { - if (formatSpecs && numFormatSpecs) { - char formatBuffer[128]; - SInt32 cidx, idx, loc; - loc = specs[curSpec].loc; - if (cformat) { - for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { - if ('$' == cformat[loc + cidx]) { - if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); - } - } else { - formatBuffer[idx] = cformat[loc + cidx]; - } - } - } else { - for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { - if ('$' == uformat[loc + cidx]) { - if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); - } - } else { - formatBuffer[idx] = (int8_t)uformat[loc + cidx]; - } - } - } - formatBuffer[idx] = '\0'; - formatSpecs[(*numFormatSpecs)++] = CFStringCreateWithCString(kCFAllocatorDefault, formatBuffer, kCFStringEncodingUTF8); - } - } - break; - default: - break; - } - } - } - formatIdx = newFmtIdx; - } - return curSpec; -} - -#define FORMAT_BUFFER_LEN 400 -#define VPRINTF_BUFFER_LEN 61 - -static void __CFStringSetUpFormatAndSpecBuffers(CFStringRef formatString, CFIndex formatLen, const uint8_t **cformat, const UniChar **uformat, UniChar **formatChars, UniChar *localFormatBuffer, CFFormatSpec **specs, CFFormatSpec *localSpecsBuffer, CFStringRef **formatSpecs, CFStringRef *localFormatSpecsBuffer) { - SInt32 formatIdx, sizeSpecs = 0; - CFAllocatorRef tmpAlloc = __CFGetDefaultAllocator(); - - if (!CF_IS_OBJC(__kCFStringTypeID, formatString) && !CF_IS_SWIFT(CFStringGetTypeID(), formatString)) { - __CFAssertIsString(formatString); - if (!__CFStrIsUnicode(formatString)) { - *cformat = (const uint8_t *)__CFStrContents(formatString); - if (*cformat) *cformat += __CFStrSkipAnyLengthByte(formatString); - } else { - *uformat = (const UniChar *)__CFStrContents(formatString); - } - } - if (!(*cformat) && !(*uformat)) { - *formatChars = (formatLen > FORMAT_BUFFER_LEN) ? (UniChar *)CFAllocatorAllocate(tmpAlloc, formatLen * sizeof(UniChar), 0) : localFormatBuffer; - if (*formatChars != localFormatBuffer && __CFOASafe) __CFSetLastAllocationEventName(*formatChars, "CFString (temp)"); - CFStringGetCharacters(formatString, CFRangeMake(0, formatLen), *formatChars); - *uformat = *formatChars; - } - if (*cformat) { - for (formatIdx = 0; formatIdx < formatLen; formatIdx++) if ('%' == (*cformat)[formatIdx]) sizeSpecs++; - } else { - for (formatIdx = 0; formatIdx < formatLen; formatIdx++) if ('%' == (*uformat)[formatIdx]) sizeSpecs++; - } - *specs = ((2 * sizeSpecs + 1) > VPRINTF_BUFFER_LEN) ? (CFFormatSpec *)CFAllocatorAllocate(tmpAlloc, (2 * sizeSpecs + 1) * sizeof(CFFormatSpec), 0) : localSpecsBuffer; - if (*specs != localSpecsBuffer && __CFOASafe) __CFSetLastAllocationEventName(*specs, "CFString (temp)"); - *formatSpecs = ((2 * sizeSpecs + 1) > VPRINTF_BUFFER_LEN) ? (CFStringRef *)CFAllocatorAllocate(tmpAlloc, (2 * sizeSpecs + 1) * sizeof(CFStringRef), 0) : localFormatSpecsBuffer; - if (*formatSpecs != localFormatSpecsBuffer && __CFOASafe) __CFSetLastAllocationEventName(*formatSpecs, "CFString (temp)"); -} - -static bool __CFStringValidateFormat(CFStringRef expected, CFStringRef untrustedFormat, CFErrorRef *errorPtr) { - bool verified = true; - SInt32 numSpecsUntrusted = 0, numSpecsExpected = 0; - CFIndex formatLenUntrusted = 0, formatLenExpected = 0, numFormatSpecsUntrusted = 0, numFormatSpecsExpected = 0; - - CFAllocatorRef tmpAlloc = __CFGetDefaultAllocator(); - - const uint8_t *cformatUntrusted = NULL; - const UniChar *uformatUntrusted = NULL; - const uint8_t *cformatExpected = NULL; - const UniChar *uformatExpected = NULL; - UniChar *formatCharsUntrusted = NULL; - UniChar *formatCharsExpected = NULL; - UniChar localFormatBufferUntrusted[FORMAT_BUFFER_LEN]; - UniChar localFormatBufferExpected[FORMAT_BUFFER_LEN]; - - CFFormatSpec *specsUntrusted = NULL; - CFFormatSpec *specsExpected = NULL; - CFFormatSpec localSpecsBufferUntrusted[VPRINTF_BUFFER_LEN]; - CFFormatSpec localSpecsBufferExpected[VPRINTF_BUFFER_LEN]; - - CFStringRef *formatSpecsUntrusted = NULL; - CFStringRef *formatSpecsExpected = NULL; - CFStringRef localFormatSpecsBufferUntrusted[VPRINTF_BUFFER_LEN]; - CFStringRef localFormatSpecsBufferExpected[VPRINTF_BUFFER_LEN]; - - /* Set up */ - - // Untrusted - formatLenUntrusted = CFStringGetLength(untrustedFormat); - __CFStringSetUpFormatAndSpecBuffers(untrustedFormat, formatLenUntrusted, &cformatUntrusted, &uformatUntrusted, &formatCharsUntrusted, localFormatBufferUntrusted, &specsUntrusted, localSpecsBufferUntrusted, &formatSpecsUntrusted, localFormatSpecsBufferUntrusted); - - // Expected - formatLenExpected = CFStringGetLength(expected); - __CFStringSetUpFormatAndSpecBuffers(expected, formatLenExpected, &cformatExpected, &uformatExpected, &formatCharsExpected, localFormatBufferExpected, &specsExpected, localSpecsBufferExpected, &formatSpecsExpected, localFormatSpecsBufferExpected); - - /* Get info about format specifiers in both strings */ - numSpecsUntrusted = __CFStringFindFormatSpecifiersInString(cformatUntrusted, uformatUntrusted, formatLenUntrusted, specsUntrusted, formatSpecsUntrusted, &numFormatSpecsUntrusted); - numSpecsExpected = __CFStringFindFormatSpecifiersInString(cformatExpected, uformatExpected, formatLenExpected, specsExpected, formatSpecsExpected, &numFormatSpecsExpected); - - if ((numSpecsUntrusted == numSpecsExpected) && (numFormatSpecsUntrusted == numFormatSpecsExpected)) { - CFIndex idx; - for (idx = 0; idx < numSpecsExpected; idx++) { - if ((specsUntrusted[idx].type != specsExpected[idx].type) || (specsUntrusted[idx].size != specsExpected[idx].size)) { - verified = false; - break; - } - } - if (verified) { - for (idx = 0; idx < numFormatSpecsExpected; idx++) { - CFComparisonResult comp = CFStringCompare(formatSpecsUntrusted[idx], formatSpecsExpected[idx], 0); - if (comp != kCFCompareEqualTo) { - if (specsUntrusted[idx].numericFormatStyle != specsExpected[idx].numericFormatStyle) { - verified = false; - break; - } - } - } - } - } else { - // If the untrusted string doesn't have any format specifiers in it, we're still ok. - if (numSpecsUntrusted != 0) { - verified = false; - } - } - - if (!verified) { - if (errorPtr) { -#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_WINDOWS - CFStringRef debugMsg = CFStringCreateWithFormat(tmpAlloc, NULL, CFSTR("Format '%@' does not match expected '%@'"), untrustedFormat, expected); - CFMutableDictionaryRef userInfo = CFDictionaryCreateMutable(tmpAlloc, 0, &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CFDictionarySetValue(userInfo, kCFErrorDebugDescriptionKey, debugMsg); - *errorPtr = CFErrorCreate(tmpAlloc, kCFErrorDomainCocoa, /*NSFormattingError*/ 2048, userInfo); - CFRelease(userInfo); - CFRelease(debugMsg); -#endif - } - } - - if (formatCharsUntrusted && (formatCharsUntrusted != localFormatBufferUntrusted)) CFAllocatorDeallocate(tmpAlloc, formatCharsUntrusted); - if (formatCharsExpected && (formatCharsExpected != localFormatBufferExpected)) CFAllocatorDeallocate(tmpAlloc, formatCharsExpected); - if (specsUntrusted != localSpecsBufferUntrusted) CFAllocatorDeallocate(tmpAlloc, specsUntrusted); - if (specsExpected != localSpecsBufferExpected) CFAllocatorDeallocate(tmpAlloc, specsExpected); - - // Free allocated strings - CFIndex idx; - for (idx = 0; idx < numFormatSpecsUntrusted; idx++) { - if (formatSpecsUntrusted[idx]) { CFRelease(formatSpecsUntrusted[idx]); } - } - for (idx = 0; idx < numFormatSpecsExpected; idx++) { - if (formatSpecsExpected[idx]) { CFRelease(formatSpecsExpected[idx]); } - } - - if (formatSpecsUntrusted != localFormatSpecsBufferUntrusted) CFAllocatorDeallocate(tmpAlloc, formatSpecsUntrusted); - if (formatSpecsExpected != localFormatSpecsBufferExpected) CFAllocatorDeallocate(tmpAlloc, formatSpecsExpected); - - return verified; -} /* __CFStringAppendFormatCore(): The core for all string formatting. @@ -6720,23 +6297,24 @@ static bool __CFStringValidateFormat(CFStringRef expected, CFStringRef untrusted contextDescFunc: Callback for doing context-based formatting. Can be NULL. <> formatOptions: Locale specific info. Used to be a CFDictionary, now CFLocale, but either is still possible. If !NULL, localized formatting is assumed. stringsDictConfig: Only used for recursive calls when doing stringsDict formatting. Otherwise NULL. <> - validFormatSpecifiers: Only used to validate the format specifiers in the formatString. A string that contains an in order sequence of the valid format specifiers. formatString: The actual format string. initialArgPosition: Only used for recursive calls when doing stringsDict formatting. Otherwise 0. <> origValues: Only used for recursive calls when doing stringsDict formatting. Otherwise NULL. <> originalValuesSize: Only used for recursive calls when doing stringsDict formatting. Otherwise 0. <> - args: The arguments to be formatted. - errorPtr: Only used when validating the formatString against valid format specfiers. Nil unless the validation fails. + args: Finally, the arguments to be formatted. ??? %s depends on handling of encodings by __CFStringAppendBytes */ -static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef validFormatSpecifiers, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args, CFErrorRef *errorPtr) { +static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFStringRef (*copyDescFunc)(void *, const void *), CFStringRef (*contextDescFunc)(void *, const void *, const void *, bool, bool *), CFDictionaryRef formatOptions, CFDictionaryRef stringsDictConfig, CFStringRef formatString, CFIndex initialArgPosition, const void *origValues, CFIndex originalValuesSize, va_list args) { SInt32 numSpecs, sizeSpecs, sizeArgNum, formatIdx, curSpec, argNum; CFIndex formatLen; +#define FORMAT_BUFFER_LEN 400 const uint8_t *cformat = NULL; const UniChar *uformat = NULL; UniChar *formatChars = NULL; UniChar localFormatBuffer[FORMAT_BUFFER_LEN]; + +#define VPRINTF_BUFFER_LEN 61 CFFormatSpec localSpecsBuffer[VPRINTF_BUFFER_LEN]; CFFormatSpec *specs; CFPrintValue localValuesBuffer[VPRINTF_BUFFER_LEN]; @@ -6749,7 +6327,6 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString CFAllocatorRef tmpAlloc = NULL; bool localizedFormatting = formatOptions && (CFGetTypeID(formatOptions) == CFLocaleGetTypeID()); - CFDictionaryRef configDict = NULL; intmax_t dummyLocation; // A place for %n to do its thing in; should be the widest possible int value numSpecs = 0; @@ -6761,13 +6338,6 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString configs = NULL; - /* Validate expected format specifiers against untrusted format string */ - if (validFormatSpecifiers && !configDict) { - if(!__CFStringValidateFormat(validFormatSpecifiers, formatString, errorPtr)) { - return; - } - } - formatLen = CFStringGetLength(formatString); if (!CF_IS_OBJC(__kCFStringTypeID, formatString) && !CF_IS_SWIFT(CFStringGetTypeID(), formatString)) { __CFAssertIsString(formatString); @@ -7006,9 +6576,7 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString if (cformat) { for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { if ('$' == cformat[loc + cidx]) { - if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); - } + for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); } else { formatBuffer[idx] = cformat[loc + cidx]; } @@ -7016,9 +6584,7 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString } else { for (idx = 0, cidx = 0; cidx < specs[curSpec].len; idx++, cidx++) { if ('$' == uformat[loc + cidx]) { - if (idx > -1) { - for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); - } + for (idx--; '0' <= formatBuffer[idx] && formatBuffer[idx] <= '9'; idx--); } else { formatBuffer[idx] = (int8_t)uformat[loc + cidx]; } @@ -7312,10 +6878,9 @@ static void __CFStringAppendFormatCore(CFMutableStringRef outputString, CFString CFRelease(str); } } - + free(specsContext); - #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); diff --git a/CoreFoundation/String.subproj/CFString.h b/CoreFoundation/String.subproj/CFString.h index 2793bfbe24..35bb233062 100644 --- a/CoreFoundation/String.subproj/CFString.h +++ b/CoreFoundation/String.subproj/CFString.h @@ -1,7 +1,7 @@ /* CFString.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -157,7 +157,8 @@ struct __CFConstStr { uintptr_t _cfisa; uint32_t _swift_strong_rc; uint32_t _swift_weak_rc; - uint64_t _cfinfoa; + uint8_t _cfinfo[4]; + uint8_t _pad[4]; } _base; uint8_t *_ptr; #if defined(__LP64__) && defined(__BIG_ENDIAN__) @@ -175,13 +176,13 @@ struct __CFConstStr { #if __BIG_ENDIAN__ #define CFSTR(cStr) ({ \ - static struct __CFConstStr str CONST_STRING_LITERAL_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x00000000C8070000}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \ - (CFStringRef)&str; \ +static struct __CFConstStr str CONST_STRING_LITERAL_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, {0x00, 0x00, 0x07, 0xc8}, {0x00, 0x00, 0x00, 0x00}}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \ +(CFStringRef)&str; \ }) #else #define CFSTR(cStr) ({ \ - static struct __CFConstStr str CONST_STRING_LITERAL_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x07C8}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \ - (CFStringRef)&str; \ +static struct __CFConstStr str CONST_STRING_LITERAL_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, {0xc8, 0x07, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, (uint8_t *)(cStr), sizeof(cStr) - 1}; \ +(CFStringRef)&str; \ }) #endif @@ -413,9 +414,9 @@ typedef CF_OPTIONS(CFOptionFlags, CFStringCompareFlags) { 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 */ - kCFCompareDiacriticInsensitive API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 128, /* If specified, ignores diacritics (o-umlaut == o) */ - kCFCompareWidthInsensitive API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 256, /* If specified, ignores width differences ('a' == UFF41) */ - kCFCompareForcedOrdering API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.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) */ + 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) */ }; /* The main comparison routine; compares specified range of the first string to (the full range of) the second string. @@ -425,7 +426,7 @@ typedef CF_OPTIONS(CFOptionFlags, CFStringCompareFlags) { rangeToCompare applies to the first string; that is, only the substring of theString1 specified by rangeToCompare is compared against all of theString2. */ CF_EXPORT -CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef theString1, CFStringRef theString2, CFRange rangeToCompare, CFStringCompareFlags compareOptions, CFLocaleRef locale) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CFComparisonResult CFStringCompareWithOptionsAndLocale(CFStringRef theString1, CFStringRef theString2, CFRange rangeToCompare, CFStringCompareFlags compareOptions, CFLocaleRef locale) CF_AVAILABLE(10_5, 2_0); /* Comparison convenience. Uses the current user locale (the return value from CFLocaleCopyCurrent()) if kCFCompareLocalized. Refer to CFStringCompareWithOptionsAndLocale() for more info. */ @@ -446,7 +447,7 @@ CFComparisonResult CFStringCompare(CFStringRef theString1, CFStringRef theString Only the substring of theString specified by rangeToSearch is searched for stringToFind. */ CF_EXPORT -Boolean CFStringFindWithOptionsAndLocale(CFStringRef theString, CFStringRef stringToFind, CFRange rangeToSearch, CFStringCompareFlags searchOptions, CFLocaleRef locale, CFRange *result) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +Boolean CFStringFindWithOptionsAndLocale(CFStringRef theString, CFStringRef stringToFind, CFRange rangeToSearch, CFStringCompareFlags searchOptions, CFLocaleRef locale, CFRange *result) CF_AVAILABLE(10_5, 2_0); /* Find convenience. Uses the current user locale (the return value from CFLocaleCopyCurrent()) if kCFCompareLocalized. Refer to CFStringFindWithOptionsAndLocale() for more info. */ @@ -500,7 +501,7 @@ CF_EXPORT CFRange CFStringGetRangeOfComposedCharactersAtIndex(CFStringRef theStr @param theSet The CFCharacterSet against which the membership of characters is checked. If this parameter is not a valid CFCharacterSet, the behavior is undefined. - @param rangeToSearch The range of characters within the string to search. If + @param range The range of characters within the string to search. If the range location or end point (defined by the location plus length minus 1) are outside the index space of the string (0 to N-1 inclusive, where N is the length of the @@ -537,7 +538,7 @@ void CFStringGetLineBounds(CFStringRef theString, CFRange range, CFIndex *lineBe /* Same as CFStringGetLineBounds(), however, will only look for paragraphs. Won't stop at Unicode NextLine or LineSeparator characters. */ CF_EXPORT -void CFStringGetParagraphBounds(CFStringRef string, CFRange range, CFIndex *parBeginIndex, CFIndex *parEndIndex, CFIndex *contentsEndIndex) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +void CFStringGetParagraphBounds(CFStringRef string, CFRange range, CFIndex *parBeginIndex, CFIndex *parEndIndex, CFIndex *contentsEndIndex) CF_AVAILABLE(10_5, 2_0); /*! @function CFStringGetHyphenationLocationBeforeIndex @@ -565,10 +566,10 @@ void CFStringGetParagraphBounds(CFStringRef string, CFRange range, CFIndex *parB one exists; else kCFNotFound */ CF_EXPORT -CFIndex CFStringGetHyphenationLocationBeforeIndex(CFStringRef string, CFIndex location, CFRange limitRange, CFOptionFlags options, CFLocaleRef locale, UTF32Char *character) API_AVAILABLE(macos(10.7), ios(4.2), watchos(2.0), tvos(9.0)); +CFIndex CFStringGetHyphenationLocationBeforeIndex(CFStringRef string, CFIndex location, CFRange limitRange, CFOptionFlags options, CFLocaleRef locale, UTF32Char *character) CF_AVAILABLE(10_7, 4_2); CF_EXPORT -Boolean CFStringIsHyphenationAvailableForLocale(CFLocaleRef locale) API_AVAILABLE(macos(10.7), ios(4.3), watchos(2.0), tvos(9.0)); +Boolean CFStringIsHyphenationAvailableForLocale(CFLocaleRef locale) CF_AVAILABLE(10_7, 4_3); /*** Exploding and joining strings with a separator string ***/ @@ -715,7 +716,7 @@ CF_EXPORT void CFStringNormalize(CFMutableStringRef theString, CFStringNormaliza the effect of kCFCompareNonliteral. @param theString The string which is to be folded. If this parameter is not a valid mutable CFString, the behavior is undefined. - @param theFlags The equivalency flags which describes the character folding form. + @param theFlag The equivalency flags which describes the character folding form. Only those flags containing the word "insensitive" are recognized here; other flags are ignored. Folding with kCFCompareCaseInsensitive removes case distinctions in accordance with the mapping specified by ftp://ftp.unicode.org/Public/UNIDATA/CaseFolding.txt. Folding with @@ -728,7 +729,7 @@ CF_EXPORT void CFStringNormalize(CFMutableStringRef theString, CFStringNormaliza */ CF_EXPORT -void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, CFLocaleRef theLocale) API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +void CFStringFold(CFMutableStringRef theString, CFStringCompareFlags theFlags, CFLocaleRef theLocale) CF_AVAILABLE(10_5, 2_0); /* Perform string transliteration. The transformation represented by transform is applied to the given range of string, modifying it in place. Only the specified range will be modified, but the transform may look at portions of the string outside that range for context. NULL range pointer causes the whole string to be transformed. On return, range is modified to reflect the new range corresponding to the original range. reverse indicates that the inverse transform should be used instead, if it exists. If the transform is successful, true is returned; if unsuccessful, false. Reasons for the transform being unsuccessful include an invalid transform identifier, or attempting to reverse an irreversible transform. @@ -754,7 +755,7 @@ CF_EXPORT const CFStringRef kCFStringTransformLatinCyrillic; CF_EXPORT const CFStringRef kCFStringTransformLatinGreek; CF_EXPORT const CFStringRef kCFStringTransformToXMLHex; CF_EXPORT const CFStringRef kCFStringTransformToUnicodeName; -CF_EXPORT const CFStringRef kCFStringTransformStripDiacritics API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFStringTransformStripDiacritics CF_AVAILABLE(10_5, 2_0); /*** General encoding related functionality ***/ diff --git a/CoreFoundation/String.subproj/CFStringDefaultEncoding.h b/CoreFoundation/String.subproj/CFStringDefaultEncoding.h index 87c920efca..c79305ee79 100644 --- a/CoreFoundation/String.subproj/CFStringDefaultEncoding.h +++ b/CoreFoundation/String.subproj/CFStringDefaultEncoding.h @@ -1,7 +1,7 @@ /* CFStringDefaultEncoding.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/String.subproj/CFStringEncodingExt.h b/CoreFoundation/String.subproj/CFStringEncodingExt.h index a32e4bc9c0..2ea2b26e4e 100644 --- a/CoreFoundation/String.subproj/CFStringEncodingExt.h +++ b/CoreFoundation/String.subproj/CFStringEncodingExt.h @@ -1,7 +1,7 @@ /* CFStringEncodingExt.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -126,7 +126,7 @@ typedef CF_ENUM(CFIndex, CFStringEncodings) { kCFStringEncodingJIS_X0208_90 = 0x0622, kCFStringEncodingJIS_X0212_90 = 0x0623, kCFStringEncodingJIS_C6226_78 = 0x0624, - kCFStringEncodingShiftJIS_X0213 API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)) = 0x0628, /* Shift-JIS format encoding of JIS X0213 planes 1 and 2*/ + 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 */ @@ -171,8 +171,8 @@ typedef CF_ENUM(CFIndex, CFStringEncodings) { kCFStringEncodingEBCDIC_US = 0x0C01, /* basic EBCDIC-US */ kCFStringEncodingEBCDIC_CP037 = 0x0C02, /* code page 037, extended EBCDIC (Latin-1 set) for US,Canada... */ - kCFStringEncodingUTF7 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 0x04000100, /* kTextEncodingUnicodeDefault + kUnicodeUTF7Format RFC2152 */ - kCFStringEncodingUTF7_IMAP API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)) = 0x0A10, /* UTF-7 (IMAP folder variant) RFC3501 */ + 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) */ diff --git a/CoreFoundation/String.subproj/CFStringEncodings.c b/CoreFoundation/String.subproj/CFStringEncodings.c index 90e5141bd3..c5ccea910c 100644 --- a/CoreFoundation/String.subproj/CFStringEncodings.c +++ b/CoreFoundation/String.subproj/CFStringEncodings.c @@ -1,7 +1,7 @@ /* CFStringEncodings.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -910,7 +910,7 @@ Boolean _CFStringGetFileSystemRepresentation(CFStringRef string, uint8_t *buffer void _CFStringGetUserDefaultEncoding(UInt32 *oScriptValue, UInt32 *oRegionValue) { char *stringValue; char buffer[__kCFMaxDefaultEncodingFileLength]; - int uid = _CFGetEUID(); + int uid = getuid(); if ((stringValue = (char *)__CFgetenv(__kCFUserEncodingEnvVariableName)) != NULL) { if ((uid == strtol_l(stringValue, &stringValue, 0, NULL)) && (':' == *stringValue)) { @@ -1012,7 +1012,7 @@ void _CFStringGetInstallationEncodingAndRegion(uint32_t *encoding, uint32_t *reg if (stringValue) { *encoding = strtol_l(stringValue, &stringValue, 0, NULL); // We force using MacRoman for Arabic/Hebrew users When changing language to Arabic and Hebrew, set the default user encoding to MacRoman, not MacArabic/MacHebrew - if ((*encoding == kCFStringEncodingMacArabic) || (*encoding == kCFStringEncodingMacHebrew) || (*encoding == kCFStringEncodingMacDevanagari)) *encoding = kCFStringEncodingMacRoman; + if ((*encoding == kCFStringEncodingMacArabic) || (*encoding == kCFStringEncodingMacHebrew)) *encoding = kCFStringEncodingMacRoman; if (*stringValue == ':') *region = strtol_l(++stringValue, NULL, 0, NULL); } } diff --git a/CoreFoundation/String.subproj/CFStringScanner.c b/CoreFoundation/String.subproj/CFStringScanner.c index 1137ab09c7..775d50b514 100644 --- a/CoreFoundation/String.subproj/CFStringScanner.c +++ b/CoreFoundation/String.subproj/CFStringScanner.c @@ -1,7 +1,7 @@ /* CFStringScanner.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -219,7 +219,7 @@ CF_PRIVATE Boolean __CFStringScanDouble(CFStringInlineBuffer *buf, CFTypeRef loc charPtr = (char *)CFAllocatorAllocate(tmpAlloc, capacity * sizeof(char), 0); memmove(charPtr, localCharBuffer, numChars * sizeof(char)); } else { - charPtr = __CFSafelyReallocateWithAllocator(tmpAlloc, charPtr, capacity * sizeof(char), 0, NULL); + charPtr = (char *)CFAllocatorReallocate(tmpAlloc, charPtr, capacity * sizeof(char), 0); } } charPtr[numChars++] = (char)ch; diff --git a/CoreFoundation/String.subproj/CFStringUtilities.c b/CoreFoundation/String.subproj/CFStringUtilities.c index bfc21456f4..501a98740d 100644 --- a/CoreFoundation/String.subproj/CFStringUtilities.c +++ b/CoreFoundation/String.subproj/CFStringUtilities.c @@ -1,7 +1,7 @@ /* CFStringUtilities.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -54,14 +54,14 @@ const CFStringEncoding* CFStringGetListOfAvailableEncodings() { CFStringRef CFStringGetNameOfEncoding(CFStringEncoding theEncoding) { static CFMutableDictionaryRef mappingTable = NULL; - static os_unfair_lock mappingTableLock = OS_UNFAIR_LOCK_INIT; + static OSSpinLock mappingTableLock = OS_SPINLOCK_INIT; CFStringRef theName = NULL; if (mappingTable) { - os_unfair_lock_lock(&mappingTableLock); + OSSpinLockLock(&mappingTableLock); theName = (CFStringRef)CFDictionaryGetValue(mappingTable, (const void*)(uintptr_t)theEncoding); - os_unfair_lock_unlock(&mappingTableLock); + OSSpinLockUnlock(&mappingTableLock); } if (!theName) { @@ -72,7 +72,7 @@ CFStringRef CFStringGetNameOfEncoding(CFStringEncoding theEncoding) { } if (theName) { - os_unfair_lock_lock(&mappingTableLock); + OSSpinLockLock(&mappingTableLock); CFStringRef result = NULL; if (!mappingTable) { @@ -82,10 +82,10 @@ CFStringRef CFStringGetNameOfEncoding(CFStringEncoding theEncoding) { } if (!result) { // If not, add it in CFDictionaryAddValue(mappingTable, (const void*)(uintptr_t)theEncoding, (const void*)theName); - os_unfair_lock_unlock(&mappingTableLock); + OSSpinLockUnlock(&mappingTableLock); CFRelease(theName); } else { // Otherwise use the one already in there - os_unfair_lock_unlock(&mappingTableLock); + OSSpinLockUnlock(&mappingTableLock); CFRelease(theName); theName = result; } @@ -636,10 +636,10 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * #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) * MIN(range1.length, range2.length)) < 0) ? kCFCompareLessThan : kCFCompareGreaterThan); + compResult = ((memcmp(characters1, characters2, sizeof(UniChar) * range1.length) < 0) ? kCFCompareLessThan : kCFCompareGreaterThan); } } else { UniChar *buffer1 = NULL; @@ -665,7 +665,7 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * if (0 == buffer1Len) { buffer1 = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UTF16Char) * bufferSize, 0); } else if (buffer1Len < range1.length) { - buffer1 = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, buffer1, sizeof(UTF16Char) * bufferSize, 0, NULL); + buffer1 = (UniChar *)CFAllocatorReallocate(kCFAllocatorSystemDefault, buffer1, sizeof(UTF16Char) * bufferSize, 0); } buffer1Len = bufferSize; } @@ -690,7 +690,7 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer * if (0 == buffer2Len) { buffer2 = (UniChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UTF16Char) * bufferSize, 0); } else if (buffer2Len < range2.length) { - buffer2 = __CFSafelyReallocateWithAllocator(kCFAllocatorSystemDefault, buffer2, sizeof(UTF16Char) * bufferSize, 0, NULL); + buffer2 = (UniChar *)CFAllocatorReallocate(kCFAllocatorSystemDefault, buffer2, sizeof(UTF16Char) * bufferSize, 0); } buffer2Len = bufferSize; } diff --git a/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c b/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c index 22af14b61c..ca84018432 100644 --- a/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFBuiltinConverters.c @@ -1,7 +1,7 @@ /* CFBuiltinConverters.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFICUConverters.c b/CoreFoundation/StringEncodings.subproj/CFICUConverters.c index a6445149f2..432c65be34 100644 --- a/CoreFoundation/StringEncodings.subproj/CFICUConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFICUConverters.c @@ -1,7 +1,7 @@ /* CFICUConverters.c - Copyright (c) 2004-2017, Apple Inc. and the Swift project authors + Copyright (c) 2004-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFICUConverters.h b/CoreFoundation/StringEncodings.subproj/CFICUConverters.h index c2f7883a94..a49ac3231b 100644 --- a/CoreFoundation/StringEncodings.subproj/CFICUConverters.h +++ b/CoreFoundation/StringEncodings.subproj/CFICUConverters.h @@ -2,9 +2,9 @@ CFICUConverters.h CoreFoundation - Copyright (c) 2007-2017, Apple Inc. and the Swift project authors + Copyright (c) 2007-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c b/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c index b3b8688b61..f4786a1930 100644 --- a/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c +++ b/CoreFoundation/StringEncodings.subproj/CFPlatformConverters.c @@ -1,7 +1,7 @@ /* CFPlatformConverters.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c index 924d257eaa..124cc36544 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.c @@ -1,7 +1,7 @@ /* CFStringEncodingConverter.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -580,7 +580,7 @@ static const _CFEncodingConverter *__CFGetConverter(uint32_t encoding) { const _CFEncodingConverter **commonConverterSlot = NULL; static _CFEncodingConverter *commonConverters[3] = {NULL, NULL, NULL}; // UTF8, MacRoman/WinLatin1, and the default encoding* static CFMutableDictionaryRef mappingTable = NULL; - static os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; + static OSSpinLock lock = OS_SPINLOCK_INIT; switch (encoding) { case kCFStringEncodingUTF8: commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[0]); break; @@ -598,15 +598,15 @@ static const _CFEncodingConverter *__CFGetConverter(uint32_t encoding) { default: if (CFStringGetSystemEncoding() == encoding) commonConverterSlot = (const _CFEncodingConverter **)&(commonConverters[2]); break; } - os_unfair_lock_lock(&lock); + OSSpinLockLock(&lock); converter = ((NULL == commonConverterSlot) ? ((NULL == mappingTable) ? NULL : (const _CFEncodingConverter *)CFDictionaryGetValue(mappingTable, (const void *)(uintptr_t)encoding)) : *commonConverterSlot); - os_unfair_lock_unlock(&lock); + OSSpinLockUnlock(&lock); if (NULL == converter) { const CFStringEncodingConverter *definition = __CFStringEncodingConverterGetDefinition(encoding); if (NULL != definition) { - os_unfair_lock_lock(&lock); + OSSpinLockLock(&lock); converter = ((NULL == commonConverterSlot) ? ((NULL == mappingTable) ? NULL : (const _CFEncodingConverter *)CFDictionaryGetValue(mappingTable, (const void *)(uintptr_t)encoding)) : *commonConverterSlot); if (NULL == converter) { @@ -620,7 +620,7 @@ static const _CFEncodingConverter *__CFGetConverter(uint32_t encoding) { *commonConverterSlot = converter; } } - os_unfair_lock_unlock(&lock); + OSSpinLockUnlock(&lock); } } diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h index 17640282d5..7ca356e9ed 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverter.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverter.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h index 58dfb1897d..0d6dd61225 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterExt.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverterExt.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h index 4cb64f4d5e..4228932bfe 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingConverterPriv.h @@ -1,7 +1,7 @@ /* CFStringEncodingConverterPriv.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c index aabc3f128d..6991e914d0 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.c @@ -1,7 +1,7 @@ /* CFStringEncodingDatabase.c - Copyright (c) 2005-2017, Apple Inc. and the Swift project authors + Copyright (c) 2005-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h index bab845af04..4394583337 100644 --- a/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h +++ b/CoreFoundation/StringEncodings.subproj/CFStringEncodingDatabase.h @@ -2,9 +2,9 @@ CFStringEncodingDatabase.h CoreFoundation - Copyright (c) 2007-2017, Apple Inc. and the Swift project authors + Copyright (c) 2007-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUniChar.c b/CoreFoundation/StringEncodings.subproj/CFUniChar.c index 127e49a49f..700b687773 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniChar.c +++ b/CoreFoundation/StringEncodings.subproj/CFUniChar.c @@ -1,7 +1,7 @@ /* CFUniChar.c - Copyright (c) 2001-2017, Apple Inc. and the Swift project authors + Copyright (c) 2001-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUniChar.h b/CoreFoundation/StringEncodings.subproj/CFUniChar.h index ad702d810b..e7f38d1c4d 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniChar.h +++ b/CoreFoundation/StringEncodings.subproj/CFUniChar.h @@ -1,7 +1,7 @@ /* CFUniChar.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h b/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h index d2ded5cfe9..140ef842d9 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h +++ b/CoreFoundation/StringEncodings.subproj/CFUniCharPriv.h @@ -1,7 +1,7 @@ /* CFUniCharPriv.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c index 68f5242aec..977e178897 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.c @@ -1,7 +1,7 @@ /* CFUnicodeDecomposition.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h index 5414930e30..14bf62d60d 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodeDecomposition.h @@ -3,9 +3,9 @@ CoreFoundation Created by aki on Wed Oct 03 2001. - Copyright (c) 2001-2017, Apple Inc. and the Swift project authors + Copyright (c) 2001-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c index 26a73bcc75..459487ed36 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.c @@ -1,7 +1,7 @@ /* CFUnicodePrecomposition.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h index 34acabf7e9..fc19f083bf 100644 --- a/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h +++ b/CoreFoundation/StringEncodings.subproj/CFUnicodePrecomposition.h @@ -3,9 +3,9 @@ CoreFoundation Created by aki on Wed Oct 03 2001. - Copyright (c) 2001-2017, Apple Inc. and the Swift project authors + Copyright (c) 2001-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/URL.subproj/CFURL.c b/CoreFoundation/URL.subproj/CFURL.c index 0696b3ea46..13e40d9cf2 100644 --- a/CoreFoundation/URL.subproj/CFURL.c +++ b/CoreFoundation/URL.subproj/CFURL.c @@ -1,7 +1,7 @@ /* CFURL.c - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -27,9 +27,11 @@ #include #if __has_include() #include -#elif __has_include() +#else +#if !TARGET_OS_ANDROID #include #endif +#endif #include #endif @@ -87,8 +89,6 @@ static uint numURLsWithBaseURL = 0; // number of URLs with a baseURL static uint numNonUTF8EncodedURLs = 0; // number of URLs that don't have UTF8 encoding #endif -#define STACK_BUFFER_SIZE 1024 - /* The bit flags in myURL->_flags */ // component bits #define HAS_SCHEME (0x00000001) @@ -150,6 +150,8 @@ CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType); #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 @@ -182,7 +184,7 @@ struct __CFURL { CFStringRef _string; // Never NULL CFURLRef _base; struct _CFURLAdditionalData* _extra; - _Atomic(void *)_resourceInfo; // For use by CoreServicesInternal to cache property values. Retained and released by CFURL. + void *_resourceInfo; // For use by CoreServicesInternal to cache property values. Retained and released by CFURL. #if DEPLOYMENT_RUNTIME_SWIFT CFRange _ranges[9]; // constant length (9) array of ranges in Swift #else @@ -224,7 +226,7 @@ CF_INLINE UInt32 _getAdditionalDataFlags(const struct __CFURL* url) CF_INLINE void* _getResourceInfo ( const struct __CFURL* url ) { if ( url ) { - return atomic_load(&((struct __CFURL*)url)->_resourceInfo); + return url->_resourceInfo; } else { return NULL; @@ -316,8 +318,7 @@ CF_INLINE void _setAdditionalDataFlags(struct __CFURL* url, UInt32 additionalDat CF_INLINE void _setResourceInfo ( struct __CFURL* url, void* resourceInfo ) { // Must be atomic - void *old = NULL; - if ( url && atomic_compare_exchange_strong_explicit(&url->_resourceInfo, &old, resourceInfo, memory_order_seq_cst, memory_order_relaxed)) { + if ( url && OSAtomicCompareAndSwapPtrBarrier( NULL, resourceInfo, &url->_resourceInfo )) { CFRetain( resourceInfo ); } } @@ -333,7 +334,6 @@ CF_INLINE void _setSchemeTypeInFlags(UInt32 *flags, UInt32 schemeType) *flags = (*flags & ~SCHEME_TYPE_MASK) + (schemeType << SCHEME_SHIFT); } -static Boolean _fileSystemRepresentationHasFileIDPrefix(const UInt8 *buffer, CFIndex bufLen); static Boolean _pathHasFileIDPrefix(CFStringRef path); static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef basePath, Boolean baseIsDir, CFURLPathStyle fsType, CFAllocatorRef alloc) CF_RETURNS_RETAINED; static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef baseURL, UInt32 *theFlags, CFRange *packedRanges, uint8_t *numberOfRanges); @@ -931,21 +931,9 @@ static CFStringRef CreateStringFromFileSystemRepresentationByAddingPercentEscape // 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) CF_RETURNS_RETAINED { CFStringRef result = NULL; - CFIndex strlength = CFStringGetLength(str); - CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(((strlength != 0) ? strlength : 1), kCFStringEncodingUTF8); - STACK_BUFFER_DECL(char, stackBuffer, STACK_BUFFER_SIZE); - char *bufferPtr; - if ( bufferSize <= STACK_BUFFER_SIZE ) { - bufferPtr = stackBuffer; - } - else { - bufferPtr = (char *)malloc(bufferSize); - } - if ( CFStringGetCString(str, bufferPtr, bufferSize, kCFStringEncodingUTF8) ) { - result = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)bufferPtr, strlen(bufferPtr), FALSE, FALSE, !preserveSlashes, NULL); - } - if ( bufferPtr != stackBuffer ) { - free(bufferPtr); + STACK_BUFFER_DECL(char, buffer, PATH_MAX); + if ( CFStringGetCString(str, buffer, PATH_MAX, kCFStringEncodingUTF8) ) { + result = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)buffer, strlen(buffer), FALSE, FALSE, !preserveSlashes, NULL); } return result; } @@ -984,7 +972,7 @@ static CFStringRef UnescapeAllWithUTF8(CFAllocatorRef alloc, CFStringRef origina { CFStringRef result = NULL; CFIndex strLength = CFStringGetLength(originalString); - CFIndex maxBufferSize = CFStringGetMaximumSizeForEncoding(((strLength != 0) ? strLength : 1), kCFStringEncodingUTF8); + CFIndex maxBufferSize = CFStringGetMaximumSizeForEncoding(strLength, kCFStringEncodingUTF8); CFIndex stackBufferSize = 2096; STACK_BUFFER_DECL(UInt8, escapedStackBuf, stackBufferSize *2); UInt8 *escapedBuf; @@ -1259,16 +1247,16 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorR if (numBytesUsed == capacityOfBytes) { if (bytes == byteBuffer) { - bytes = (uint8_t *)malloc(16 * sizeof(uint8_t)); + bytes = (uint8_t *)CFAllocatorAllocate(alloc, 16 * sizeof(uint8_t), 0); memmove(bytes, byteBuffer, capacityOfBytes); capacityOfBytes = 16; } else { void *oldbytes = bytes; int oldcap = capacityOfBytes; capacityOfBytes = 2*capacityOfBytes; - bytes = (uint8_t *)malloc(capacityOfBytes * sizeof(uint8_t)); + bytes = (uint8_t *)CFAllocatorAllocate(alloc, capacityOfBytes * sizeof(uint8_t), 0); memmove(bytes, oldbytes, oldcap); - free(oldbytes); + CFAllocatorDeallocate(alloc, oldbytes); } } percentLoc ++; @@ -1321,7 +1309,7 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorR } if (escapedStr) CFRelease(escapedStr); - if (bytes != byteBuffer) free(bytes); + if (bytes != byteBuffer) CFAllocatorDeallocate(alloc, bytes); if (failed) { if (newStr) CFRelease(newStr); return NULL; @@ -1352,7 +1340,10 @@ CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef all CFMutableStringRef newString = NULL; CFIndex idx, length; CFStringInlineBuffer buf; - STACK_BUFFER_DECL(UniChar, charBuffer, STACK_BUFFER_SIZE); + enum { + kCharBufferMax = 4096, + }; + STACK_BUFFER_DECL(UniChar, charBuffer, kCharBufferMax); CFIndex charBufferIndex = 0; if (!originalString) return NULL; @@ -1390,7 +1381,7 @@ CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef all CFStringDelete(newString, CFRangeMake(idx, length-idx)); } // make sure charBuffer has enough room - if ( charBufferIndex >= (STACK_BUFFER_SIZE - kMaxPercentEncodedUniChars) ) { + if ( charBufferIndex >= (kCharBufferMax - kMaxPercentEncodedUniChars) ) { // make room CFStringAppendCharacters(newString, charBuffer, charBufferIndex); charBufferIndex = 0; @@ -1435,7 +1426,7 @@ CF_EXPORT CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef all } } else if (newString) { charBuffer[charBufferIndex++] = ch; - if ( charBufferIndex == STACK_BUFFER_SIZE ) { + if ( charBufferIndex == kCharBufferMax ) { CFStringAppendCharacters(newString, charBuffer, charBufferIndex); charBufferIndex = 0; } @@ -1489,7 +1480,6 @@ static Boolean __CFURLEqual(CFTypeRef cf1, CFTypeRef cf2) { static CFHashCode __CFURLHash(CFTypeRef cf) { CFHashCode result; - __CFGenericValidateType(cf, CFURLGetTypeID()); if ( cf ) { // use the CFHashCode of the URL @@ -1572,7 +1562,6 @@ static CFStringRef __CFURLCopyFormattingDescription(CFTypeRef cf, CFDictionary static CFStringRef __CFURLCopyDescription(CFTypeRef cf) { CFURLRef url = (CFURLRef)cf; - __CFGenericValidateType(url, CFURLGetTypeID()); CFStringRef result; CFAllocatorRef alloc = CFGetAllocator(url); Boolean isDataURL = false; @@ -1621,14 +1610,12 @@ static void __CFURLDeallocate(CFTypeRef cf) { numDealloced ++; #endif if (url->_string) CFRelease(url->_string); - ((struct __CFURL *)url)->_string = (void *)0xdeadbeef; // 28124664: catch anyone using URL after it was released if (url->_base) CFRelease(url->_base); CFStringRef sanitizedString = _getSanitizedString(url); if (sanitizedString) CFRelease(sanitizedString); if ( url->_extra != NULL ) CFAllocatorDeallocate( alloc, url->_extra ); - void *resourceInfo = _getResourceInfo(url); - if (resourceInfo) CFRelease(resourceInfo); - atomic_store(&((struct __CFURL *)url)->_resourceInfo, (void *)0xdeadbeef); // 20362546: catch anyone using URL after it was released + if (_getResourceInfo(url)) CFRelease(_getResourceInfo(url)); + ((struct __CFURL *)url)->_resourceInfo = (void *)0xdeadbeef; // 20362546: catch anyone using URL after it was released } static CFTypeID __kCFURLTypeID = _kCFRuntimeNotATypeID; @@ -1669,7 +1656,6 @@ CF_PRIVATE void CFShowURL(CFURLRef url) { fprintf(stdout, "ObjC bridged object}\n"); return; } - __CFGenericValidateType(url, CFURLGetTypeID()); fprintf(stdout, "\n\tRelative string: "); CFShow(url->_string); fprintf(stdout, "\tBase URL: "); @@ -1716,7 +1702,7 @@ static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, UInt8 *in *freeCharacters = false; } else { - buf = (char *)malloc(length); + buf = (char *)CFAllocatorAllocate(alloc, length, 0); *freeCharacters = true; } CFStringGetBytes(string, rg, kCFStringEncodingISOLatin1, 0, false, (uint8_t *)buf, length, NULL); @@ -1729,7 +1715,7 @@ static void constructBuffers(CFAllocatorRef alloc, CFStringRef string, UInt8 *in *freeCharacters = false; } else { - buf = (UniChar *)malloc(length * sizeof(UniChar)); + buf = (UniChar *)CFAllocatorAllocate(alloc, length * sizeof(UniChar), 0); *freeCharacters = true; } CFStringGetCharacters(string, rg, buf); @@ -1754,9 +1740,10 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef Boolean useCString, freeCharacters; const char *cstring = NULL; const UniChar *ustring = NULL; - STACK_BUFFER_DECL(UInt8, stackBuffer, STACK_BUFFER_SIZE); + CFIndex stackBufferSize = 4096; + STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize); - constructBuffers(alloc, string, stackBuffer, STACK_BUFFER_SIZE, &cstring, &ustring, &useCString, &freeCharacters); + constructBuffers(alloc, string, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters); if (useCString) { _parseComponentsCString(alloc, baseURL, cfStringLength, cstring, theFlags, packedRanges, numberOfRanges); @@ -1766,7 +1753,7 @@ static void _parseComponents(CFAllocatorRef alloc, CFStringRef string, CFURLRef } if (freeCharacters) { - free(useCString ? (void *)cstring : (void *)ustring); + CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring); } } @@ -1797,11 +1784,12 @@ 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 - STACK_BUFFER_DECL(UInt8, stackBuffer, STACK_BUFFER_SIZE); + CFIndex stackBufferSize = 4096; + STACK_BUFFER_DECL(UInt8, stackBuffer, stackBufferSize); CFMutableStringRef sanitizedString = NULL; UInt32 additionalDataFlags = 0; - constructBuffers(alloc, url->_string, stackBuffer, STACK_BUFFER_SIZE, &cstring, &ustring, &useCString, &freeCharacters); + constructBuffers(alloc, url->_string, stackBuffer, stackBufferSize, &cstring, &ustring, &useCString, &freeCharacters); if (!(url->_flags & IS_DECOMPOSABLE)) { // Impossible to have a problem character in the scheme base = _rangeForComponent(url->_flags, url->_ranges, HAS_SCHEME).length + 1; @@ -1841,7 +1829,7 @@ static void computeSanitizedString(CFURLRef url) { CFRelease(sanitizedString); } if (freeCharacters) { - free(useCString ? (void *)cstring : (void *)ustring); + CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring); } } @@ -1873,7 +1861,7 @@ static CFStringRef correctedComponent(CFStringRef comp, UInt32 compFlag, CFStrin result = (CFMutableStringRef)comp; } if (freeCharacters) { - free(useCString ? (void *)cstring : (void *)ustring); + CFAllocatorDeallocate(alloc, useCString ? (void *)cstring : (void *)ustring); } return result; } @@ -1903,7 +1891,7 @@ static struct __CFURL * _CFURLAlloc(CFAllocatorRef allocator, uint8_t numberOfRa url->_string = NULL; url->_base = NULL; url->_extra = NULL; - atomic_store(&url->_resourceInfo, NULL); + url->_resourceInfo = NULL; } return url; } @@ -2064,7 +2052,7 @@ static CFURLRef _CFURLCreateWithURLString(CFAllocatorRef allocator, CFStringRef } } #if DEBUG_URL_INITIALIZER_LOGGING - CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithURLString (in) string '%@', checkForLegalCharacters %@, baseURL %@\n\t_CFURLCreateWithURLString (out) result %@, resultBaseURL %@"), input_string, input_checkForLegalCharacters ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFURLGetString(result) : CFSTR("(null)"), result ? (result->_base ? CFURLGetString(result->_base) : CFSTR("(null)")) : CFSTR("(null)") ); + CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithURLString (in) string '%@', checkForLegalCharacters %@, baseURL %@\n\t_CFURLCreateWithURLString (out) result %@"), input_string, input_checkForLegalCharacters ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result); if ( input_string ) { CFRelease(input_string); } @@ -2085,7 +2073,7 @@ Boolean _CFURLInitWithURLString(CFURLRef url, CFStringRef string, Boolean checkF container->_encoding = result->_encoding; container->_string = result->_string; container->_extra = result->_extra; - atomic_store(&container->_resourceInfo, atomic_load(&result->_resourceInfo)); + container->_resourceInfo = result->_resourceInfo; container->_base = result->_base; uint8_t numberOfRanges = _countRanges(result); if (numberOfRanges > 0) { @@ -2236,7 +2224,7 @@ static CFURLRef _CFURLCreateWithFileSystemPath(CFAllocatorRef allocator, CFStrin #if DEBUG_URL_INITIALIZER_LOGGING #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated" - CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithFileSystemPath (in) fileSystemPath '%@', pathStyle %@, isDirectory %@, baseURL %@\n\t_CFURLCreateWithFileSystemPath (out) result %@, resultBaseURL %@"), input_fileSystemPath, input_pathStyle == kCFURLPOSIXPathStyle ? CFSTR("POSIX") : input_pathStyle == kCFURLHFSPathStyle ? CFSTR("HFS"): CFSTR("Windows"), input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? result->_string : CFSTR("(null)"), result ? (result->_base ? CFURLGetString(result->_base) : CFSTR("(null)")) : CFSTR("(null)") ); + CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithFileSystemPath (in) fileSystemPath '%@', pathStyle %@, isDirectory %@, baseURL %@\n\t_CFURLCreateWithFileSystemPath (out) result %@"), input_fileSystemPath, input_pathStyle == kCFURLPOSIXPathStyle ? CFSTR("POSIX") : input_pathStyle == kCFURLHFSPathStyle ? CFSTR("HFS"): CFSTR("Windows"), input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result); #pragma GCC diagnostic pop if ( input_fileSystemPath ) { CFRelease(input_fileSystemPath); @@ -2264,12 +2252,10 @@ static CFURLRef _CFURLCreateWithFileSystemRepresentation(CFAllocatorRef allocato Boolean isAbsolute = bufLen && (*buffer == '/'); Boolean addedPercentEncoding; Boolean releaseBaseURL = false; - Boolean isFileReferencePath = false; if ( isAbsolute ) { // if buffer contains an absolute path, ignore baseURL (if provided) baseURL = NULL; - isFileReferencePath = _fileSystemRepresentationHasFileIDPrefix(buffer, bufLen); } else if ( baseURL == NULL ) { // if buffer contains a relative path and no baseURL is provided, use the current working directory @@ -2290,25 +2276,16 @@ static CFURLRef _CFURLCreateWithFileSystemRepresentation(CFAllocatorRef allocato #endif // hard coded parse if ( isAbsolute ) { - UInt32 flags = IS_DECOMPOSABLE | HAS_SCHEME | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH; - flags |= (isDirectory ? IS_DIRECTORY : 0); - if ( isFileReferencePath ) { - // if the URL is a file reference URL, don't set IS_CANONICAL_FILE_URL or POSIX_AND_URL_PATHS_MATCH - flags |= PATH_HAS_FILE_ID; - } - else { - flags |= IS_CANONICAL_FILE_URL | (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH); - } - _setSchemeTypeInFlags(&flags, kHasFileScheme); - if ( AddAuthorityToFileURL() ) { - result->_flags = flags | HAS_HOST; + result->_flags = (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH ) | (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_SCHEME | HAS_HOST | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | IS_CANONICAL_FILE_URL; + _setSchemeTypeInFlags(&result->_flags, kHasFileScheme); result->_ranges[0] = CFRangeMake(0, 4); // scheme "file" result->_ranges[1] = CFRangeMake(7, 9); // host "localhost" result->_ranges[2] = CFRangeMake(16, CFStringGetLength(urlString)- 16); } else { - result->_flags = flags; + result->_flags = (addedPercentEncoding ? 0 : POSIX_AND_URL_PATHS_MATCH ) | (isDirectory ? IS_DIRECTORY : 0) | IS_DECOMPOSABLE | HAS_SCHEME | HAS_PATH | ORIGINAL_AND_URL_STRINGS_MATCH | IS_CANONICAL_FILE_URL; + _setSchemeTypeInFlags(&result->_flags, kHasFileScheme); result->_ranges[0] = CFRangeMake(0, 4); // scheme "file" result->_ranges[1] = CFRangeMake(7, CFStringGetLength(urlString)- 7); } @@ -2334,7 +2311,7 @@ static CFURLRef _CFURLCreateWithFileSystemRepresentation(CFAllocatorRef allocato result = (struct __CFURL *)CFRetain(baseURL); } #if DEBUG_URL_INITIALIZER_LOGGING - CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithFileSystemRepresentation (in) buffer '%*s', isDirectory %@, baseURL %@\n\t_CFURLCreateWithFileSystemRepresentation (out) result %@, resultBaseURL %@"), (int)input_bufLen, input_buffer, input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result ? CFURLGetString(result) : CFSTR("(null)"), result ? (result->_base ? CFURLGetString(result->_base) : CFSTR("(null)")) : CFSTR("(null)") ); + CFLog(kCFLogLevelError, CFSTR("_CFURLCreateWithFileSystemRepresentation (in) buffer '%*s', isDirectory %@, baseURL %@\n\t_CFURLCreateWithFileSystemRepresentation (out) result %@"), input_bufLen, input_buffer, input_isDirectory ? CFSTR("YES") : CFSTR("NO"), input_baseURL, result); if ( input_baseURL ) { CFRelease(input_baseURL); } @@ -2445,7 +2422,7 @@ Boolean _CFURLInitAbsoluteURLWithBytes(CFURLRef url, const UInt8 *relativeURLByt container->_encoding = result->_encoding; container->_string = result->_string; container->_extra = result->_extra; - atomic_store(&container->_resourceInfo, atomic_load(&result->_resourceInfo)); + container->_resourceInfo = result->_resourceInfo; container->_base = result->_base; uint8_t numberOfRanges = _countRanges(result); if (numberOfRanges > 0) { @@ -2815,15 +2792,15 @@ static CFMutableStringRef resolveAbsoluteURLString(CFAllocatorRef alloc, CFStrin CFMutableStringRef result = NULL; CFIndex bufLen = CFStringGetLength(baseString) + CFStringGetLength(relString); // Overkill, but guarantees we never allocate again if ( bufLen <= 1024 ) { - STACK_BUFFER_DECL(UniChar, buf, bufLen ? bufLen : 1); + STACK_BUFFER_DECL(UniChar, buf, bufLen); result = resolveAbsoluteURLStringBuffer(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges, buf); return ( result ); } else { - UniChar *buf = (UniChar *)malloc(bufLen * sizeof(UniChar)); + UniChar *buf = (UniChar *)CFAllocatorAllocate(alloc, bufLen * sizeof(UniChar), 0); if ( buf ) { result = resolveAbsoluteURLStringBuffer(alloc, relString, relFlags, relRanges, baseString, baseFlags, baseRanges, buf); - free(buf); + CFAllocatorDeallocate(alloc, buf); } return ( result ); } @@ -2912,7 +2889,6 @@ CFStringEncoding _CFURLGetEncoding(CFURLRef url) { Boolean CFURLCanBeDecomposed(CFURLRef anURL) { anURL = _CFURLFromNSURL(anURL); - __CFGenericValidateType(anURL, CFURLGetTypeID()); return ((anURL->_flags & IS_DECOMPOSABLE) != 0); } @@ -3107,7 +3083,6 @@ static CFRange _netLocationRange(UInt32 flags, const CFRange *ranges) { CFStringRef CFURLCopyNetLocation(CFURLRef anURL) { anURL = _CFURLFromNSURL(anURL); - __CFGenericValidateType(anURL, CFURLGetTypeID()); if (anURL->_flags & NET_LOCATION_MASK) { // We provide the net location CFRange netRg = _netLocationRange(anURL->_flags, anURL->_ranges); @@ -3138,7 +3113,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); - __CFGenericValidateType(anURL, CFURLGetTypeID()); return _retainedComponentString(anURL, HAS_PATH, false, false); } @@ -3615,7 +3589,6 @@ CFRange CFURLGetByteRangeForComponent(CFURLRef url, CFURLComponentType component CFRange byteRange; CFAssert2(component > 0 && component < 13, __kCFLogAssertion, "%s(): passed invalid component %ld", __PRETTY_FUNCTION__, component); url = _CFURLFromNSURL(url); - __CFGenericValidateType(url, CFURLGetTypeID()); if (!(url->_flags & IS_DECOMPOSABLE)) { // Special-case this because non-decomposable URLs have a slightly strange flags setup @@ -3885,7 +3858,6 @@ static CFURLRef composeFromRFC2396(CFAllocatorRef alloc, const CFURLComponentsRF CF_EXPORT Boolean _CFURLCopyComponents(CFURLRef url, CFURLComponentDecomposition decompositionType, void *components) { url = _CFURLFromNSURL(url); - __CFGenericValidateType(url, CFURLGetTypeID()); switch (decompositionType) { case kCFURLComponentDecompositionNonHierarchical: return decomposeToNonHierarchical(url, (CFURLComponentsNonHierarchical *)components); @@ -4002,24 +3974,11 @@ static CFStringRef WindowsPathToURLPath(CFStringRef path, CFAllocatorRef alloc, static CFStringRef POSIXPathToURLPath(CFStringRef path, CFAllocatorRef alloc, Boolean isDirectory, Boolean isAbsolute, Boolean *posixAndUrlPathsMatch) CF_RETURNS_RETAINED { Boolean addedPercentEncoding = false; CFStringRef pathString = NULL; - CFIndex strLength = CFStringGetLength(path); - CFIndex bufferSize = strLength ? CFStringGetMaximumSizeOfFileSystemRepresentation(path) : 1; - STACK_BUFFER_DECL(char, stackBuffer, STACK_BUFFER_SIZE); - char *bufferPtr; - if ( bufferSize <= STACK_BUFFER_SIZE ) { - bufferPtr = stackBuffer; - } - else { - bufferPtr = (char *)malloc(bufferSize); - } - if ( CFStringGetFileSystemRepresentation(path, bufferPtr, bufferSize) ) { - pathString = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)bufferPtr, strlen(bufferPtr), isDirectory, isAbsolute, false /* windowsPath */, &addedPercentEncoding); + STACK_BUFFER_DECL(char, buffer, PATH_MAX); + if ( CFStringGetFileSystemRepresentation(path, buffer, PATH_MAX) ) { + pathString = CreateStringFromFileSystemRepresentationByAddingPercentEscapes(kCFAllocatorDefault, (const UInt8 *)buffer, strlen(buffer), isDirectory, isAbsolute, false /* windowsPath */, &addedPercentEncoding); } - - if ( bufferPtr != stackBuffer ) { - free(bufferPtr); - } - + if ( posixAndUrlPathsMatch ) { *posixAndUrlPathsMatch = !addedPercentEncoding; } @@ -4300,9 +4259,8 @@ static CFStringRef _resolveFileSystemPaths(CFStringRef relativePath, CFStringRef CFURLRef _CFURLCreateCurrentDirectoryURL(CFAllocatorRef allocator) { CFURLRef url = NULL; - // CFMaxPathSize is OK here since we're getting the path from the file system - uint8_t buf[CFMaxPathSize]; - if (_CFGetCurrentDirectory((char *)buf, CFMaxPathSize)) { + uint8_t buf[CFMaxPathSize + 1]; + if (_CFGetCurrentDirectory((char *)buf, CFMaxPathLength)) { url = CFURLCreateFromFileSystemRepresentation(allocator, buf, strlen((char *)buf), true); } return url; @@ -4333,7 +4291,7 @@ void _CFURLInitWithFileSystemPathRelativeToBase(CFURLRef url, CFStringRef fileSy container->_encoding = result->_encoding; container->_string = result->_string; container->_extra = result->_extra; - atomic_store(&container->_resourceInfo, atomic_load(&result->_resourceInfo)); + container->_resourceInfo = result->_resourceInfo; container->_base = result->_base; uint8_t numberOfRanges = _countRanges(result); if (numberOfRanges > 0) { @@ -4342,25 +4300,17 @@ void _CFURLInitWithFileSystemPathRelativeToBase(CFURLRef url, CFStringRef fileSy CFAllocatorDeallocate(allocator, result); } - -static Boolean _fileSystemRepresentationHasFileIDPrefix(const UInt8 *buffer, CFIndex bufLen) -{ - // buffer is not guaranteed to be a nul terminated string, so bufLen must be compared against FILE_ID_PREAMBLE_LENGTH to make sure strncmp doesn't go off the end of buffer - return ( buffer && - (bufLen >= FILE_ID_PREAMBLE_LENGTH) && - (strncmp((const char *)buffer, FILE_ID_PREAMBLE, FILE_ID_PREAMBLE_LENGTH) == 0) ); -} - -static Boolean _pathHasFileIDPrefix(CFStringRef path) +static Boolean _pathHasFileIDPrefix( CFStringRef path ) { - // path is not NULL, path has prefix "/.file/id=". + // path is not NULL, path has prefix "/.file/" and has at least one character following the prefix. #ifdef __CONSTANT_STRINGS__ static const #endif - CFStringRef fileIDPreamble = CFSTR(FILE_ID_PREAMBLE); - return ( path && CFStringHasPrefix(path, fileIDPreamble) ); + CFStringRef fileIDPrefix = CFSTR( "/" FILE_ID_PREFIX "/" ); + return path && CFStringHasPrefix( path, fileIDPrefix ) && CFStringGetLength( path ) > CFStringGetLength( fileIDPrefix ); } + CF_EXPORT CFStringRef CFURLCopyFileSystemPath(CFURLRef anURL, CFURLPathStyle pathStyle) { #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated" @@ -4377,21 +4327,9 @@ CF_EXPORT CFStringRef CFURLCopyFileSystemPath(CFURLRef anURL, CFURLPathStyle pat // We can grope the ivars isCanonicalFileURL = ((anURL->_flags & IS_CANONICAL_FILE_URL) != 0); if ( isCanonicalFileURL ) { - CFIndex strLength = CFStringGetLength(CFURLGetString(anURL)); - CFIndex bufferSize = CFStringGetMaximumSizeForEncoding(((strLength != 0) ? strLength : 1), kCFStringEncodingUTF8); - STACK_BUFFER_DECL(UInt8, stackBuffer, STACK_BUFFER_SIZE); - UInt8 *bufferPtr; - if ( bufferSize <= STACK_BUFFER_SIZE ) { - bufferPtr = stackBuffer; - } - else { - bufferPtr = (UInt8 *)malloc(bufferSize); - } - if ( CanonicalFileURLStringToFileSystemRepresentation(anURL->_string, bufferPtr, bufferSize) ) { - result = CFStringCreateWithBytes(alloc, bufferPtr, strlen((char *)bufferPtr), kCFStringEncodingUTF8, false); - } - if ( bufferPtr != stackBuffer ) { - free(bufferPtr); + STACK_BUFFER_DECL(UInt8, buffer, PATH_MAX + 1); + if ( CanonicalFileURLStringToFileSystemRepresentation(anURL->_string, buffer, PATH_MAX + 1) ) { + result = CFStringCreateWithBytes(alloc, buffer, strlen((char *)buffer), kCFStringEncodingUTF8, false); } } } @@ -4424,8 +4362,6 @@ CFStringRef CFURLCreateStringWithFileSystemPath(CFAllocatorRef allocator, CFURLR } if (relPath == NULL) { - // make sure we have a CFURL before getting the URL's encoding - anURL = _CFURLFromNSURL(anURL); CFStringRef urlPath = CFURLCopyPath(anURL); CFStringEncoding enc = anURL->_encoding; if (urlPath) { @@ -4506,7 +4442,7 @@ Boolean CFURLGetFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBas // else fall back to slower way. path = CFURLCreateStringWithFileSystemPath(alloc, url, kCFURLPOSIXPathStyle, resolveAgainstBase); if (path) { - Boolean convResult = CFStringGetFileSystemRepresentation(path, (char *)buffer, bufLen); + Boolean convResult = _CFStringGetFileSystemRepresentation(path, buffer, bufLen); CFRelease(path); return convResult; } @@ -4730,17 +4666,10 @@ CFURLRef CFURLCreateCopyAppendingPathComponent(CFAllocatorRef allocator, CFURLRe else { newString = CFStringCreateMutableCopy(allocator, 0, url->_string); if ( newString ) { - if ( _CFURLIsFileURL(url) ) { - // use file system encoding if this is a file URL - newComp = POSIXPathToURLPath(pathComponent, allocator, false, false, NULL); - } - else { - // use the URL's encoding if this isn't a file URL #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - newComp = CFURLCreateStringByAddingPercentEscapes(allocator, pathComponent, NULL, CFSTR(";?"), url->_encoding); + newComp = CFURLCreateStringByAddingPercentEscapes(allocator, pathComponent, NULL, CFSTR(";?"), url->_encoding); #pragma GCC diagnostic pop - } if ( newComp ) { pathRg = _rangeForComponent(url->_flags, url->_ranges, HAS_PATH); if ( (!pathRg.length || CFStringGetCharacterAtIndex(url->_string, pathRg.location + pathRg.length - 1) != '/') && (CFStringGetCharacterAtIndex(newComp, 0) != '/') ) { @@ -4881,18 +4810,10 @@ CFURLRef CFURLCreateCopyAppendingPathExtension(CFAllocatorRef allocator, CFURLRe newString = CFStringCreateMutableCopy(allocator, 0, url->_string); if ( newString ) { CFStringInsert(newString, rg.location + rg.length, CFSTR(".")); - CFStringRef newExt; - if ( _CFURLIsFileURL(url) ) { - // use file system encoding if this is a file URL - newExt = POSIXPathToURLPath(extension, allocator, false, false, NULL); - } - else { - // use the URL's encoding if this isn't a file URL #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" - newExt = CFURLCreateStringByAddingPercentEscapes(allocator, extension, NULL, CFSTR(";?/"), url->_encoding); + CFStringRef newExt = CFURLCreateStringByAddingPercentEscapes(allocator, extension, NULL, CFSTR(";?/"), url->_encoding); #pragma GCC diagnostic pop - } if ( newExt ) { CFStringInsert(newString, rg.location + rg.length + 1, newExt); CFRelease(newExt); diff --git a/CoreFoundation/URL.subproj/CFURL.h b/CoreFoundation/URL.subproj/CFURL.h index 11c96516d8..d473136a7c 100644 --- a/CoreFoundation/URL.subproj/CFURL.h +++ b/CoreFoundation/URL.subproj/CFURL.h @@ -1,7 +1,7 @@ /* CFURL.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -20,7 +20,7 @@ CF_EXTERN_C_BEGIN typedef CF_ENUM(CFIndex, CFURLPathStyle) { kCFURLPOSIXPathStyle = 0, - kCFURLHFSPathStyle API_DEPRECATED("Carbon File Manager is deprecated, use kCFURLPOSIXPathStyle where possible", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)), /* The use of kCFURLHFSPathStyle is deprecated. The Carbon File Manager, which uses HFS style paths, is deprecated. HFS style paths are unreliable because they can arbitrarily refer to multiple volumes if those volumes have identical volume names. You should instead use kCFURLPOSIXPathStyle wherever possible. */ + kCFURLHFSPathStyle CF_ENUM_DEPRECATED(10_0, 10_9, 2_0, 7_0), /* The use of kCFURLHFSPathStyle is deprecated. The Carbon File Manager, which uses HFS style paths, is deprecated. HFS style paths are unreliable because they can arbitrarily refer to multiple volumes if those volumes have identical volume names. You should instead use kCFURLPOSIXPathStyle wherever possible. */ kCFURLWindowsPathStyle }; @@ -385,7 +385,7 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapes(CFAllocatorRef allocator, /* As above, but allows you to specify the encoding to use when interpreting percent-escapes */ CF_EXPORT -CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorRef allocator, CFStringRef origString, CFStringRef charsToLeaveEscaped, CFStringEncoding encoding) API_DEPRECATED("Use [NSString stringByRemovingPercentEncoding] or CFURLCreateStringByReplacingPercentEscapes() instead, which always uses the recommended UTF-8 encoding.", macos(10.0,10.11), ios(2.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorRef allocator, CFStringRef origString, CFStringRef charsToLeaveEscaped, CFStringEncoding encoding) CF_DEPRECATED(10_0, 10_11, 2_0, 9_0, "Use [NSString stringByRemovingPercentEncoding] or CFURLCreateStringByReplacingPercentEscapes() instead, which always uses the recommended UTF-8 encoding."); /* Creates a copy or originalString, replacing certain characters with */ /* the equivalent percent-escape sequence based on the encoding specified. */ @@ -400,7 +400,7 @@ CFStringRef CFURLCreateStringByReplacingPercentEscapesUsingEncoding(CFAllocatorR /* in an otherwise correct URL string, do: */ /* newString = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, origString, NULL, NULL, kCFStringEncodingUTF8); */ CF_EXPORT -CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) API_DEPRECATED("Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid).", macos(10.0,10.11), ios(2.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding) CF_DEPRECATED(10_0, 10_11, 2_0, 9_0, "Use [NSString stringByAddingPercentEncodingWithAllowedCharacters:] instead, which always uses the recommended UTF-8 encoding, and which encodes for a specific URL component or subcomponent (since each URL component or subcomponent has different rules for what characters are valid)."); #if (TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || CF_BUILDING_CF || NSBUILDINGFOUNDATION @@ -416,7 +416,7 @@ CF_IMPLICIT_BRIDGING_DISABLED The URL specifying the resource. */ CF_EXPORT -Boolean CFURLIsFileReferenceURL(CFURLRef url) API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +Boolean CFURLIsFileReferenceURL(CFURLRef url) CF_AVAILABLE(10_9, 7_0); /* CFURLCreateFileReferenceURL @@ -439,7 +439,7 @@ Boolean CFURLIsFileReferenceURL(CFURLRef url) API_AVAILABLE(macos(10.9), ios(7.0 Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* @@ -463,7 +463,7 @@ CFURLRef CFURLCreateFileReferenceURL(CFAllocatorRef allocator, CFURLRef url, CFE Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -CFURLRef CFURLCreateFilePathURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFURLRef CFURLCreateFilePathURL(CFAllocatorRef allocator, CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); CF_IMPLICIT_BRIDGING_ENABLED #endif @@ -506,7 +506,7 @@ CF_IMPLICIT_BRIDGING_DISABLED Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -Boolean CFURLCopyResourcePropertyForKey(CFURLRef url, CFStringRef key, void *propertyValueTypeRefPtr, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean CFURLCopyResourcePropertyForKey(CFURLRef url, CFStringRef key, void *propertyValueTypeRefPtr, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* @@ -530,7 +530,7 @@ Boolean CFURLCopyResourcePropertyForKey(CFURLRef url, CFStringRef key, void *pro Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -CFDictionaryRef CFURLCopyResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFDictionaryRef CFURLCopyResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* @@ -556,7 +556,7 @@ CFDictionaryRef CFURLCopyResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -Boolean CFURLSetResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean CFURLSetResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* @@ -580,11 +580,11 @@ Boolean CFURLSetResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -Boolean CFURLSetResourcePropertiesForKeys(CFURLRef url, CFDictionaryRef keyedPropertyValues, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean CFURLSetResourcePropertiesForKeys(CFURLRef url, CFDictionaryRef keyedPropertyValues, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); CF_EXPORT -const CFStringRef kCFURLKeysOfUnsetValuesKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLKeysOfUnsetValuesKey CF_AVAILABLE(10_7, 5_0); /* 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. */ @@ -604,7 +604,7 @@ const CFStringRef kCFURLKeysOfUnsetValuesKey API_AVAILABLE(macos(10.7), ios(5.0) Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -void CFURLClearResourcePropertyCacheForKey(CFURLRef url, CFStringRef key) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +void CFURLClearResourcePropertyCacheForKey(CFURLRef url, CFStringRef key) CF_AVAILABLE(10_6, 4_0); /* @@ -621,7 +621,7 @@ void CFURLClearResourcePropertyCacheForKey(CFURLRef url, CFStringRef key) API_AV Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -void CFURLClearResourcePropertyCache(CFURLRef url) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +void CFURLClearResourcePropertyCache(CFURLRef url) CF_AVAILABLE(10_6, 4_0); /* @@ -642,7 +642,7 @@ void CFURLClearResourcePropertyCache(CFURLRef url) API_AVAILABLE(macos(10.6), io Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -void CFURLSetTemporaryResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +void CFURLSetTemporaryResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue) CF_AVAILABLE(10_6, 4_0); /* @@ -664,7 +664,7 @@ void CFURLSetTemporaryResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTy Symbol is present in iOS 4, but performs no operation. */ CF_EXPORT -Boolean CFURLResourceIsReachable(CFURLRef url, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean CFURLResourceIsReachable(CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); CF_IMPLICIT_BRIDGING_ENABLED @@ -672,151 +672,151 @@ CF_IMPLICIT_BRIDGING_ENABLED /* Properties of File System Resources */ CF_EXPORT -const CFStringRef kCFURLNameKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLNameKey CF_AVAILABLE(10_6, 4_0); /* The resource name provided by the file system (Read-write, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLLocalizedNameKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLLocalizedNameKey CF_AVAILABLE(10_6, 4_0); /* Localized or extension-hidden name as displayed to users (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLIsRegularFileKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsRegularFileKey CF_AVAILABLE(10_6, 4_0); /* True for regular files (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsDirectoryKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsDirectoryKey CF_AVAILABLE(10_6, 4_0); /* True for directories (Read-only, CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsSymbolicLinkKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsSymbolicLinkKey CF_AVAILABLE(10_6, 4_0); /* True for symlinks (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsVolumeKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsVolumeKey CF_AVAILABLE(10_6, 4_0); /* True for the root directory of a volume (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsPackageKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsPackageKey CF_AVAILABLE(10_6, 4_0); /* 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 kCFURLIsApplicationKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsApplicationKey CF_AVAILABLE(10_11, 9_0); /* True if resource is an application (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLApplicationIsScriptableKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +const CFStringRef kCFURLApplicationIsScriptableKey CF_AVAILABLE(10_11, NA); /* True if the resource is scriptable. Only applies to applications. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsSystemImmutableKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsSystemImmutableKey CF_AVAILABLE(10_6, 4_0); /* True for system-immutable resources (Read-write, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsUserImmutableKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsUserImmutableKey CF_AVAILABLE(10_6, 4_0); /* True for user-immutable resources (Read-write, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsHiddenKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsHiddenKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLHasHiddenExtensionKey CF_AVAILABLE(10_6, 4_0); /* True for resources whose filename extension is removed from the localized name property (Read-write, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLCreationDateKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLCreationDateKey CF_AVAILABLE(10_6, 4_0); /* The date the resource was created (Read-write, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLContentAccessDateKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); - /* The date the resource was last accessed (Read-write, value type CFDate) */ +const CFStringRef kCFURLContentAccessDateKey CF_AVAILABLE(10_6, 4_0); + /* The date the resource was last accessed (Read-only, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLContentModificationDateKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLContentModificationDateKey CF_AVAILABLE(10_6, 4_0); /* The time the resource content was last modified (Read-write, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLAttributeModificationDateKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLAttributeModificationDateKey CF_AVAILABLE(10_6, 4_0); /* The time the resource's attributes were last modified (Read-only, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLLinkCountKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLLinkCountKey CF_AVAILABLE(10_6, 4_0); /* Number of hard links to the resource (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLParentDirectoryURLKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLParentDirectoryURLKey CF_AVAILABLE(10_6, 4_0); /* The resource's parent directory, if any (Read-only, value type CFURL) */ CF_EXPORT -const CFStringRef kCFURLVolumeURLKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeURLKey CF_AVAILABLE(10_6, 4_0); /* URL of the volume on which the resource is stored (Read-only, value type CFURL) */ CF_EXPORT -const CFStringRef kCFURLTypeIdentifierKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLTypeIdentifierKey CF_AVAILABLE(10_6, 4_0); /* Uniform type identifier (UTI) for the resource (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLLocalizedTypeDescriptionKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLLocalizedTypeDescriptionKey CF_AVAILABLE(10_6, 4_0); /* User-visible type or "kind" description (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLLabelNumberKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLLabelNumberKey CF_AVAILABLE(10_6, 4_0); /* The label number assigned to the resource (Read-write, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLLabelColorKey API_DEPRECATED("Use NSURLLabelColorKey", macosx(10.6, 10.12), ios(4.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)); +const CFStringRef kCFURLLabelColorKey API_DEPRECATED("Use NSURLLabelColorKey", macosx(10.6, 10.12), ios(4.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)); /* not implemented */ CF_EXPORT -const CFStringRef kCFURLLocalizedLabelKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLLocalizedLabelKey CF_AVAILABLE(10_6, 4_0); /* The user-visible label text (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLEffectiveIconKey API_DEPRECATED("Use NSURLEffectiveIconKey", macosx(10.6, 10.12), ios(4.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)); +const CFStringRef kCFURLEffectiveIconKey API_DEPRECATED("Use NSURLEffectiveIconKey", macosx(10.6, 10.12), ios(4.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)); /* not implemented */ CF_EXPORT -const CFStringRef kCFURLCustomIconKey API_DEPRECATED("Use NSURLCustomIconKey", macosx(10.6, 10.12), ios(4.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0)); +const CFStringRef kCFURLCustomIconKey API_DEPRECATED("Use NSURLCustomIconKey", macosx(10.6, 10.12), ios(4.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0)); /* not implemented */ CF_EXPORT -const CFStringRef kCFURLFileResourceIdentifierKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceIdentifierKey CF_AVAILABLE(10_7, 5_0); /* An identifier which can be used to compare two file system objects for equality using CFEqual (i.e, two object identifiers are equal if they have the same file system path or if the paths are linked to same inode on the same file system). This identifier is not persistent across system restarts. (Read-only, value type CFType) */ CF_EXPORT -const CFStringRef kCFURLVolumeIdentifierKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIdentifierKey CF_AVAILABLE(10_7, 5_0); /* An identifier that can be used to identify the volume the file system object is on. Other objects on the same volume will have the same volume identifier and can be compared using for equality using CFEqual. This identifier is not persistent across system restarts. (Read-only, value type CFType) */ CF_EXPORT -const CFStringRef kCFURLPreferredIOBlockSizeKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLPreferredIOBlockSizeKey CF_AVAILABLE(10_7, 5_0); /* The optimal block size when reading or writing this file's data, or NULL if not available. (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLIsReadableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsReadableKey CF_AVAILABLE(10_7, 5_0); /* true if this process (as determined by EUID) can read the resource. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsWritableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsWritableKey CF_AVAILABLE(10_7, 5_0); /* true if this process (as determined by EUID) can write to the resource. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLIsExecutableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsExecutableKey CF_AVAILABLE(10_7, 5_0); /* true if this process (as determined by EUID) can execute a file resource or search a directory resource. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLFileSecurityKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileSecurityKey CF_AVAILABLE(10_7, 5_0); /* The file system object's security information encapsulated in a CFFileSecurity object. (Read-write, value type CFFileSecurity) */ CF_EXPORT -const CFStringRef kCFURLIsExcludedFromBackupKey API_AVAILABLE(macos(10.8), ios(5.1), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsExcludedFromBackupKey CF_AVAILABLE(10_8, 5_1); /* true if resource should be excluded from backups, false otherwise (Read-write, value type CFBoolean). This property is only useful for excluding cache and other application support files which are not needed in a backup. Some operations commonly made to user documents will cause this property to be reset to false and so this property should not be used on user documents. */ CF_EXPORT -const CFStringRef kCFURLTagNamesKey API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos); +const CFStringRef kCFURLTagNamesKey CF_AVAILABLE(10_9, NA); /* The array of Tag names (Read-write, value type CFArray of CFString) */ CF_EXPORT -const CFStringRef kCFURLPathKey API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)); +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 @@ -824,226 +824,212 @@ const CFStringRef kCFURLCanonicalPathKey API_AVAILABLE(macosx(10.12), ios(10.0), /* the URL's path as a canonical absolute file system path (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLIsMountTriggerKey API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)); +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 kCFURLGenerationIdentifierKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLGenerationIdentifierKey CF_AVAILABLE(10_10, 8_0); /* An opaque generation identifier which can be compared using CFEqual() to determine if the data in a document has been modified. For URLs which refer to the same file inode, the generation identifier will change when the data in the file's data fork is changed (changes to extended attributes or other file system metadata do not change the generation identifier). For URLs which refer to the same directory inode, the generation identifier will change when direct children of that directory are added, removed or renamed (changes to the data of the direct children of that directory will not change the generation identifier). The generation identifier is persistent across system restarts. The generation identifier is tied to a specific document on a specific volume and is not transferred when the document is copied to another volume. This property is not supported by all volumes. (Read-only, value type CFType) */ CF_EXPORT -const CFStringRef kCFURLDocumentIdentifierKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLDocumentIdentifierKey CF_AVAILABLE(10_10, 8_0); /* The document identifier -- a value assigned by the kernel to a document (which can be either a file or directory) and is used to identify the document regardless of where it gets moved on a volume. The document identifier survives "safe save” operations; i.e it is sticky to the path it was assigned to (-replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error: is the preferred safe-save API). The document identifier is persistent across system restarts. The document identifier is not transferred when the file is copied. Document identifiers are only unique within a single volume. This property is not supported by all volumes. (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLAddedToDirectoryDateKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLAddedToDirectoryDateKey CF_AVAILABLE(10_10, 8_0); /* The date the resource was created, or renamed into or within its parent directory. Note that inconsistent behavior may be observed when this attribute is requested on hard-linked items. This property is not supported by all volumes. (Read-only, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLQuarantinePropertiesKey API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos); +const CFStringRef kCFURLQuarantinePropertiesKey CF_AVAILABLE(10_10, NA); /* The quarantine properties as defined in LSQuarantine.h. To remove quarantine information from a file, pass kCFNull as the value when setting this property. (Read-write, value type CFDictionary) */ CF_EXPORT -const CFStringRef kCFURLFileResourceTypeKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeKey CF_AVAILABLE(10_7, 5_0); /* Returns the file system object type. (Read-only, value type CFString) */ /* The file system object type values returned for the kCFURLFileResourceTypeKey */ CF_EXPORT -const CFStringRef kCFURLFileResourceTypeNamedPipe API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeNamedPipe CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeCharacterSpecial API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeCharacterSpecial CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeDirectory API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeDirectory CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeBlockSpecial API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeBlockSpecial CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeRegular API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeRegular CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeSymbolicLink API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeSymbolicLink CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeSocket API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeSocket CF_AVAILABLE(10_7, 5_0); CF_EXPORT -const CFStringRef kCFURLFileResourceTypeUnknown API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileResourceTypeUnknown CF_AVAILABLE(10_7, 5_0); /* File Properties */ CF_EXPORT -const CFStringRef kCFURLFileSizeKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileSizeKey CF_AVAILABLE(10_6, 4_0); /* Total file size in bytes (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLFileAllocatedSizeKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLFileAllocatedSizeKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) */ CF_EXPORT -const CFStringRef kCFURLTotalFileAllocatedSizeKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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) */ CF_EXPORT -const CFStringRef kCFURLIsAliasFileKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsAliasFileKey CF_AVAILABLE(10_6, 4_0); /* true if the resource is a Finder alias file or a symlink, false otherwise ( Read-only, value type CFBooleanRef) */ CF_EXPORT -const CFStringRef kCFURLFileProtectionKey API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); +const CFStringRef kCFURLFileProtectionKey CF_AVAILABLE_IOS(9_0); /* The protection level for this file */ /* The protection level values returned for the kCFURLFileProtectionKey */ CF_EXPORT -const CFStringRef kCFURLFileProtectionNone API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); // The file has no special protections associated with it. It can be read from or written to at any time. +const CFStringRef kCFURLFileProtectionNone CF_AVAILABLE_IOS(9_0); // The file has no special protections associated with it. It can be read from or written to at any time. CF_EXPORT -const CFStringRef kCFURLFileProtectionComplete API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); // The file is stored in an encrypted format on disk and cannot be read from or written to while the device is locked or booting. +const CFStringRef kCFURLFileProtectionComplete CF_AVAILABLE_IOS(9_0); // The file is stored in an encrypted format on disk and cannot be read from or written to while the device is locked or booting. CF_EXPORT -const CFStringRef kCFURLFileProtectionCompleteUnlessOpen API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); // The file is stored in an encrypted format on disk. Files can be created while the device is locked, but once closed, cannot be opened again until the device is unlocked. If the file is opened when unlocked, you may continue to access the file normally, even if the user locks the device. There is a small performance penalty when the file is created and opened, though not when being written to or read from. This can be mitigated by changing the file protection to kCFURLFileProtectionComplete when the device is unlocked. +const CFStringRef kCFURLFileProtectionCompleteUnlessOpen CF_AVAILABLE_IOS(9_0); // The file is stored in an encrypted format on disk. Files can be created while the device is locked, but once closed, cannot be opened again until the device is unlocked. If the file is opened when unlocked, you may continue to access the file normally, even if the user locks the device. There is a small performance penalty when the file is created and opened, though not when being written to or read from. This can be mitigated by changing the file protection to kCFURLFileProtectionComplete when the device is unlocked. CF_EXPORT -const CFStringRef kCFURLFileProtectionCompleteUntilFirstUserAuthentication API_AVAILABLE(ios(9.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos); // The file is stored in an encrypted format on disk and cannot be accessed until after the device has booted. After the user unlocks the device for the first time, your app can access the file and continue to access it even if the user subsequently locks the device. +const CFStringRef kCFURLFileProtectionCompleteUntilFirstUserAuthentication CF_AVAILABLE_IOS(9_0); // The file is stored in an encrypted format on disk and cannot be accessed until after the device has booted. After the user unlocks the device for the first time, your app can access the file and continue to access it even if the user subsequently locks the device. /* Volume Properties */ /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeLocalizedFormatDescriptionKey CF_AVAILABLE(10_6, 4_0); /* The user-visible volume format (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLVolumeTotalCapacityKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeTotalCapacityKey CF_AVAILABLE(10_6, 4_0); /* Total volume capacity in bytes (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLVolumeAvailableCapacityKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeAvailableCapacityKey CF_AVAILABLE(10_6, 4_0); /* Total free space in bytes (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLVolumeAvailableCapacityForImportantUsageKey API_AVAILABLE(macos(10.13), ios(11.0)) API_UNAVAILABLE(watchos, tvos); - /* Total available capacity in bytes for "Important" resources, including space expected to be cleared by purging non-essential and cached resources. "Important" means something that the user or application clearly expects to be present on the local system, but is ultimately replaceable. This would include items that the user has explicitly requested via the UI, and resources that an application requires in order to provide functionality. - - Examples: A video that the user has explicitly requested to watch but has not yet finished watching or an audio file that the user has requested to download. - - This value should not be used in determining if there is room for an irreplaceable resource. In the case of irreplaceable resources, always attempt to save the resource regardless of available capacity and handle failure as gracefully as possible. (Read-only, value type CFNumber) */ - -CF_EXPORT -const CFStringRef kCFURLVolumeAvailableCapacityForOpportunisticUsageKey API_AVAILABLE(macos(10.13), ios(11.0)) API_UNAVAILABLE(watchos, tvos); - /* Total available capacity in bytes for "Opportunistic" resources, including space expected to be cleared by purging non-essential and cached resources. "Opportunistic" means something that the user is likely to want but does not expect to be present on the local system, but is ultimately non-essential and replaceable. This would include items that will be created or downloaded without an explicit request from the user on the current device. - - Examples: A background download of a newly available episode of a TV series that a user has been recently watching, a piece of content explicitly requested on another device, or a new document saved to a network server by the current user from another device. (Read-only, value type CFNumber) */ - -CF_EXPORT -const CFStringRef kCFURLVolumeResourceCountKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeResourceCountKey CF_AVAILABLE(10_6, 4_0); /* Total number of resources on the volume (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsPersistentIDsKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsPersistentIDsKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsSymbolicLinksKey CF_AVAILABLE(10_6, 4_0); /* true if the volume format supports symbolic links (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsHardLinksKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsHardLinksKey CF_AVAILABLE(10_6, 4_0); /* true if the volume format supports hard links (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsJournalingKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsJournalingKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsJournalingKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsSparseFilesKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsZeroRunsKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsCaseSensitiveNamesKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsCasePreservedNamesKey CF_AVAILABLE(10_6, 4_0); /* 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 API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsRootDirectoryDatesKey CF_AVAILABLE(10_7, 5_0); /* true if the volume supports reliable storage of times for the root directory. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsVolumeSizesKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsVolumeSizesKey CF_AVAILABLE(10_7, 5_0); /* true if the volume supports returning volume size values (kCFURLVolumeTotalCapacityKey and kCFURLVolumeAvailableCapacityKey). (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsRenamingKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsRenamingKey CF_AVAILABLE(10_7, 5_0); /* true if the volume can be renamed. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsAdvisoryFileLockingKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsAdvisoryFileLockingKey CF_AVAILABLE(10_7, 5_0); /* true if the volume implements whole-file flock(2) style advisory locks, and the O_EXLOCK and O_SHLOCK flags of the open(2) call. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeSupportsExtendedSecurityKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeSupportsExtendedSecurityKey CF_AVAILABLE(10_7, 5_0); /* true if the volume implements extended security (ACLs). (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsBrowsableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsBrowsableKey CF_AVAILABLE(10_7, 5_0); /* true if the volume should be visible via the GUI (i.e., appear on the Desktop as a separate volume). (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeMaximumFileSizeKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeMaximumFileSizeKey CF_AVAILABLE(10_7, 5_0); /* The largest file size (in bytes) supported by this file system, or NULL if this cannot be determined. (Read-only, value type CFNumber) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsEjectableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsEjectableKey CF_AVAILABLE(10_7, 5_0); /* true if the volume's media is ejectable from the drive mechanism under software control. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsRemovableKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsRemovableKey CF_AVAILABLE(10_7, 5_0); /* true if the volume's media is removable from the drive mechanism. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsInternalKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsInternalKey CF_AVAILABLE(10_7, 5_0); /* true if the volume's device is connected to an internal bus, false if connected to an external bus, or NULL if not available. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsAutomountedKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsAutomountedKey CF_AVAILABLE(10_7, 5_0); /* true if the volume is automounted. Note: do not mistake this with the functionality provided by kCFURLVolumeSupportsBrowsingKey. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsLocalKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsLocalKey CF_AVAILABLE(10_7, 5_0); /* true if the volume is stored on a local device. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeIsReadOnlyKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeIsReadOnlyKey CF_AVAILABLE(10_7, 5_0); /* true if the volume is read-only. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLVolumeCreationDateKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeCreationDateKey CF_AVAILABLE(10_7, 5_0); /* The volume's creation date, or NULL if this cannot be determined. (Read-only, value type CFDate) */ CF_EXPORT -const CFStringRef kCFURLVolumeURLForRemountingKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeURLForRemountingKey CF_AVAILABLE(10_7, 5_0); /* The CFURL needed to remount a network volume, or NULL if not available. (Read-only, value type CFURL) */ CF_EXPORT -const CFStringRef kCFURLVolumeUUIDStringKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeUUIDStringKey CF_AVAILABLE(10_7, 5_0); /* The volume's persistent UUID as a string, or NULL if a persistent UUID is not available for the volume. (Read-only, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLVolumeNameKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeNameKey CF_AVAILABLE(10_7, 5_0); /* The name of the volume (Read-write, settable if kCFURLVolumeSupportsRenamingKey is true and permissions allow, value type CFString) */ CF_EXPORT -const CFStringRef kCFURLVolumeLocalizedNameKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLVolumeLocalizedNameKey CF_AVAILABLE(10_7, 5_0); /* The user-presentable name of the volume (Read-only, value type CFString) */ CF_EXPORT @@ -1070,72 +1056,64 @@ CF_EXPORT const CFStringRef kCFURLVolumeSupportsExclusiveRenamingKey API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); /* true if the volume supports renamex_np(2)'s RENAME_EXCL option (Read-only, value type CFBoolean) */ -CF_EXPORT -const CFStringRef kCFURLVolumeSupportsImmutableFilesKey API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - /* true if the volume supports making files immutable with the kCFURLIsUserImmutableKey or kCFURLIsSystemImmutableKey properties (Read-only, value type CFBoolean) */ - -CF_EXPORT -const CFStringRef kCFURLVolumeSupportsAccessPermissionsKey API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - /* true if the volume supports setting POSIX access permissions with the kCFURLFileSecurityKey property (Read-only, value type CFBoolean) */ - /* UbiquitousItem Properties */ CF_EXPORT -const CFStringRef kCFURLIsUbiquitousItemKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLIsUbiquitousItemKey CF_AVAILABLE(10_7, 5_0); /* true if this item is synced to the cloud, false if it is only a local file. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemHasUnresolvedConflictsKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemHasUnresolvedConflictsKey CF_AVAILABLE(10_7, 5_0); /* true if this item has conflicts outstanding. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemIsDownloadedKey API_DEPRECATED("Use kCFURLUbiquitousItemDownloadingStatusKey instead", macos(10.7,10.9), ios(5.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLUbiquitousItemIsDownloadedKey CF_DEPRECATED(10_7, 10_9, 5_0, 7_0, "Use kCFURLUbiquitousItemDownloadingStatusKey instead"); /* Equivalent to NSURLUbiquitousItemDownloadingStatusKey == NSURLUbiquitousItemDownloadingStatusCurrent. Has never behaved as documented in earlier releases, hence deprecated. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemIsDownloadingKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemIsDownloadingKey CF_AVAILABLE(10_7, 5_0); /* true if data is being downloaded for this item. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemIsUploadedKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemIsUploadedKey CF_AVAILABLE(10_7, 5_0); /* true if there is data present in the cloud for this item. (Read-only, value type CFBoolean) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemIsUploadingKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +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 API_DEPRECATED("Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead", macos(10.7,10.8), ios(5.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLUbiquitousItemPercentDownloadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0, "Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead"); /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentDownloadedKey on NSMetadataItem instead */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemPercentUploadedKey API_DEPRECATED("Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead", macos(10.7,10.8), ios(5.0,6.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLUbiquitousItemPercentUploadedKey CF_DEPRECATED(10_7, 10_8, 5_0, 6_0, "Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead"); /* Use NSMetadataQuery and NSMetadataUbiquitousItemPercentUploadedKey on NSMetadataItem instead */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemDownloadingStatusKey API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemDownloadingStatusKey CF_AVAILABLE(10_9, 7_0); /* Returns the download status of this item. (Read-only, value type CFString). Possible values below. */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemDownloadingErrorKey API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemDownloadingErrorKey CF_AVAILABLE(10_9, 7_0); /* returns the error when downloading the item from iCloud failed. See the NSUbiquitousFile section in FoundationErrors.h. (Read-only, value type CFError) */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemUploadingErrorKey API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemUploadingErrorKey CF_AVAILABLE(10_9, 7_0); /* returns the error when uploading the item to iCloud failed. See the NSUbiquitousFile section in FoundationErrors.h. (Read-only, value type CFError) */ /* The values returned for kCFURLUbiquitousItemDownloadingStatusKey */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemDownloadingStatusNotDownloaded API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemDownloadingStatusNotDownloaded CF_AVAILABLE(10_9, 7_0); /* this item has not been downloaded yet. Use NSFileManager's startDownloadingUbiquitousItemAtURL:error: to download it */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemDownloadingStatusDownloaded API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemDownloadingStatusDownloaded CF_AVAILABLE(10_9, 7_0); /* there is a local version of this item available. The most current version will get downloaded as soon as possible. */ CF_EXPORT -const CFStringRef kCFURLUbiquitousItemDownloadingStatusCurrent API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +const CFStringRef kCFURLUbiquitousItemDownloadingStatusCurrent CF_AVAILABLE(10_9, 7_0); /* there is a local version of this item and it is the most up-to-date version known to this device. */ @@ -1147,7 +1125,7 @@ typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkCreationOptions) { // deprecated kCFURLBookmarkCreationPreferFileIDResolutionMask CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0, "kCFURLBookmarkCreationPreferFileIDResolutionMask does nothing and has no effect on bookmark resolution" ) = ( 1UL << 8 ), -} API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_6, 4_0); typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkResolutionOptions) { kCFURLBookmarkResolutionWithoutUIMask = ( 1UL << 8 ), // don't perform any user interaction during bookmark resolution @@ -1156,7 +1134,7 @@ typedef CF_OPTIONS(CFOptionFlags, CFURLBookmarkResolutionOptions) { kCFBookmarkResolutionWithoutUIMask = kCFURLBookmarkResolutionWithoutUIMask, kCFBookmarkResolutionWithoutMountingMask = kCFURLBookmarkResolutionWithoutMountingMask, -} API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_6, 4_0); typedef CFOptionFlags CFURLBookmarkFileCreationOptions; @@ -1165,49 +1143,49 @@ CF_IMPLICIT_BRIDGING_DISABLED /* Returns bookmark data for the URL, created with specified options and resource properties. If this function returns NULL, the optional error is populated. */ CF_EXPORT -CFDataRef CFURLCreateBookmarkData ( CFAllocatorRef allocator, CFURLRef url, CFURLBookmarkCreationOptions options, CFArrayRef resourcePropertiesToInclude, CFURLRef relativeToURL, CFErrorRef* error ) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFDataRef CFURLCreateBookmarkData ( CFAllocatorRef allocator, CFURLRef url, CFURLBookmarkCreationOptions options, CFArrayRef resourcePropertiesToInclude, CFURLRef relativeToURL, CFErrorRef* error ) CF_AVAILABLE(10_6, 4_0); /* Return a URL that refers to a location specified by resolving bookmark data. If this function returns NULL, the optional error is populated. */ CF_EXPORT -CFURLRef CFURLCreateByResolvingBookmarkData ( CFAllocatorRef allocator, CFDataRef bookmark, CFURLBookmarkResolutionOptions options, CFURLRef relativeToURL, CFArrayRef resourcePropertiesToInclude, Boolean* isStale, CFErrorRef* error ) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFURLRef CFURLCreateByResolvingBookmarkData ( CFAllocatorRef allocator, CFDataRef bookmark, CFURLBookmarkResolutionOptions options, CFURLRef relativeToURL, CFArrayRef resourcePropertiesToInclude, Boolean* isStale, CFErrorRef* error ) CF_AVAILABLE(10_6, 4_0); /* Returns the resource propertyies identified by a specified array of keys contained in specified bookmark data. 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 in the bookmark data. */ CF_EXPORT -CFDictionaryRef CFURLCreateResourcePropertiesForKeysFromBookmarkData ( CFAllocatorRef allocator, CFArrayRef resourcePropertiesToReturn, CFDataRef bookmark ) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFDictionaryRef CFURLCreateResourcePropertiesForKeysFromBookmarkData ( CFAllocatorRef allocator, CFArrayRef resourcePropertiesToReturn, CFDataRef bookmark ) CF_AVAILABLE(10_6, 4_0); /* Returns the resource property identified by a given resource key contained in specified bookmark data. If this function returns NULL, it means the resource property is not available in the bookmark data. */ CF_EXPORT -CFTypeRef CFURLCreateResourcePropertyForKeyFromBookmarkData( CFAllocatorRef allocator, CFStringRef resourcePropertyKey, CFDataRef bookmark ) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CFTypeRef CFURLCreateResourcePropertyForKeyFromBookmarkData( CFAllocatorRef allocator, CFStringRef resourcePropertyKey, CFDataRef bookmark ) CF_AVAILABLE(10_6, 4_0); /* Returns bookmark data derived from an alias file referred to by fileURL. If fileURL refers to an alias file created prior to OS X v10.6 that contains Alias Manager information but no bookmark data, this method synthesizes bookmark data for the file. If this method returns NULL, the optional error is populated. */ CF_EXPORT -CFDataRef CFURLCreateBookmarkDataFromFile(CFAllocatorRef allocator, CFURLRef fileURL, CFErrorRef *errorRef ) API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0)); +CFDataRef CFURLCreateBookmarkDataFromFile(CFAllocatorRef allocator, CFURLRef fileURL, CFErrorRef *errorRef ) CF_AVAILABLE(10_6, 5_0); /* Creates an alias file on disk at a specified location with specified bookmark data. The bookmark data must have been created with the kCFURLBookmarkCreationSuitableForBookmarkFile option. fileURL must either refer to an existing file (which will be overwritten), or to location in an existing directory. If this method returns FALSE, the optional error is populated. */ CF_EXPORT -Boolean CFURLWriteBookmarkDataToFile( CFDataRef bookmarkRef, CFURLRef fileURL, CFURLBookmarkFileCreationOptions options, CFErrorRef *errorRef ) API_AVAILABLE(macos(10.6), ios(5.0), watchos(2.0), tvos(9.0)); +Boolean CFURLWriteBookmarkDataToFile( CFDataRef bookmarkRef, CFURLRef fileURL, CFURLBookmarkFileCreationOptions options, CFErrorRef *errorRef ) CF_AVAILABLE(10_6, 5_0); /* Returns bookmark data derived from an alias record. */ CF_EXPORT -CFDataRef CFURLCreateBookmarkDataFromAliasRecord ( CFAllocatorRef allocatorRef, CFDataRef aliasRecordDataRef ) API_AVAILABLE(macos(10.6)) API_UNAVAILABLE(ios, watchos, tvos); +CFDataRef CFURLCreateBookmarkDataFromAliasRecord ( CFAllocatorRef allocatorRef, CFDataRef aliasRecordDataRef ) CF_AVAILABLE_MAC(10_6); CF_IMPLICIT_BRIDGING_ENABLED /* 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 must call CFURLStopAccessingSecurityScopedResource(). Each call to CFURLStartAccessingSecurityScopedResource() must be balanced with a call to CFURLStopAccessingSecurityScopedResource() (Note: this is not reference counted). */ CF_EXPORT -Boolean CFURLStartAccessingSecurityScopedResource(CFURLRef url) API_AVAILABLE(macos(10.7), ios(8.0), watchos(2.0), tvos(9.0)); // On OSX, available in MacOS X 10.7.3 and later +Boolean CFURLStartAccessingSecurityScopedResource(CFURLRef url) CF_AVAILABLE(10_7, 8_0); // On OSX, available in MacOS X 10.7.3 and later /* Revokes the access granted to the url by a prior successful call to CFURLStartAccessingSecurityScopedResource(). */ CF_EXPORT -void CFURLStopAccessingSecurityScopedResource(CFURLRef url) API_AVAILABLE(macos(10.7), ios(8.0), watchos(2.0), tvos(9.0)); // On OSX, available in MacOS X 10.7.3 and later +void CFURLStopAccessingSecurityScopedResource(CFURLRef url) CF_AVAILABLE(10_7, 8_0); // On OSX, available in MacOS X 10.7.3 and later #endif /* TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE */ diff --git a/CoreFoundation/URL.subproj/CFURL.inc.h b/CoreFoundation/URL.subproj/CFURL.inc.h index 0d3a97ddc0..870a22faf8 100644 --- a/CoreFoundation/URL.subproj/CFURL.inc.h +++ b/CoreFoundation/URL.subproj/CFURL.inc.h @@ -1,7 +1,7 @@ /* CFURL.inc.h - Copyright (c) 2012-2017, Apple Inc. and the Swift project authors + Copyright (c) 2012-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/URL.subproj/CFURLAccess.c b/CoreFoundation/URL.subproj/CFURLAccess.c index 71808f1a23..d78df24c85 100644 --- a/CoreFoundation/URL.subproj/CFURLAccess.c +++ b/CoreFoundation/URL.subproj/CFURLAccess.c @@ -1,7 +1,7 @@ /* CFURLAccess.c - Copyright (c) 1999-2017, Apple Inc. and the Swift project authors + Copyright (c) 1999-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors diff --git a/CoreFoundation/URL.subproj/CFURLAccess.h b/CoreFoundation/URL.subproj/CFURLAccess.h index 28aa9d243d..ce7c6db1fd 100644 --- a/CoreFoundation/URL.subproj/CFURLAccess.h +++ b/CoreFoundation/URL.subproj/CFURLAccess.h @@ -1,7 +1,7 @@ /* CFURLAccess.h - Copyright (c) 1998-2017, Apple Inc. and the Swift project authors + Copyright (c) 1998-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -49,7 +49,7 @@ large files. */ /* Deprecated -- see top of this file for suggested replacement classes */ CF_EXPORT -Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *resourceData, CFDictionaryRef *properties, CFArrayRef desiredProperties, SInt32 *errorCode) API_DEPRECATED("For resource data, use the CFReadStream API. For file resource properties, use CFURLCopyResourcePropertiesForKeys.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +Boolean CFURLCreateDataAndPropertiesFromResource(CFAllocatorRef alloc, CFURLRef url, CFDataRef *resourceData, CFDictionaryRef *properties, CFArrayRef desiredProperties, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "For resource data, use the CFReadStream API. For file resource properties, use CFURLCopyResourcePropertiesForKeys."); /* Attempts to write the given data and properties to the given URL. If dataToWrite is NULL, only properties are written out (use @@ -61,21 +61,21 @@ CFURLCreateDataAndPropertiesFromResource(), above. */ /* Deprecated -- see top of this file for suggested replacement classes */ CF_EXPORT -Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef dataToWrite, CFDictionaryRef propertiesToWrite, SInt32 *errorCode) API_DEPRECATED("For resource data, use the CFWriteStream API. For file resource properties, use CFURLSetResourcePropertiesForKeys.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +Boolean CFURLWriteDataAndPropertiesToResource(CFURLRef url, CFDataRef dataToWrite, CFDictionaryRef propertiesToWrite, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "For resource data, use the CFWriteStream API. For file resource properties, use CFURLSetResourcePropertiesForKeys."); /* Destroys the resource indicated by url. Returns success or failure; errorCode set as above. */ /* Deprecated -- see top of this file for suggested replacement classes */ CF_EXPORT -Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) API_DEPRECATED("Use CFURLGetFileSystemRepresentation and removefile(3) instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +Boolean CFURLDestroyResource(CFURLRef url, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLGetFileSystemRepresentation and removefile(3) instead."); /* Convenience method which calls through to CFURLCreateDataAndPropertiesFromResource(). Returns NULL on error and sets errorCode accordingly. */ /* Deprecated -- see top of this file for suggested replacement classes */ CF_EXPORT -CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) API_DEPRECATED("For file resource properties, use CFURLCopyResourcePropertyForKey.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CFTypeRef CFURLCreatePropertyFromResource(CFAllocatorRef alloc, CFURLRef url, CFStringRef property, SInt32 *errorCode) CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "For file resource properties, use CFURLCopyResourcePropertyForKey."); /* Common error codes (returned only by the older APIs that predate CFError) */ @@ -89,26 +89,26 @@ typedef CF_ENUM(CFIndex, CFURLError) { kCFURLUnknownPropertyKeyError = -16L, kCFURLPropertyKeyUnavailableError = -17L, kCFURLTimeoutError = -18L -} API_DEPRECATED("Use CFError codes instead", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +} CF_ENUM_DEPRECATED(10_0, 10_9, 2_0, 7_0); /* Older property keys */ CF_EXPORT -const CFStringRef kCFURLFileExists API_DEPRECATED("Use CFURLResourceIsReachable instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFileExists CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLResourceIsReachable instead."); CF_EXPORT -const CFStringRef kCFURLFileDirectoryContents API_DEPRECATED("Use the CFURLEnumerator API instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFileDirectoryContents CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use the CFURLEnumerator API instead."); CF_EXPORT -const CFStringRef kCFURLFileLength API_DEPRECATED("Use CFURLCopyResourcePropertyForKey with kCFURLFileSizeKey instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFileLength CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLCopyResourcePropertyForKey with kCFURLFileSizeKey instead."); CF_EXPORT -const CFStringRef kCFURLFileLastModificationTime API_DEPRECATED("Use CFURLCopyResourcePropertyForKey with kCFURLContentModificationDateKey instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFileLastModificationTime CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLCopyResourcePropertyForKey with kCFURLContentModificationDateKey instead."); CF_EXPORT -const CFStringRef kCFURLFilePOSIXMode API_DEPRECATED("Use CFURLCopyResourcePropertyForKey with kCFURLFileSecurityKey and then the CFFileSecurity API instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFilePOSIXMode CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLCopyResourcePropertyForKey with kCFURLFileSecurityKey and then the CFFileSecurity API instead."); CF_EXPORT -const CFStringRef kCFURLFileOwnerID API_DEPRECATED("Use CFURLCopyResourcePropertyForKey with kCFURLFileSecurityKey and then the CFFileSecurity API instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLFileOwnerID CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use CFURLCopyResourcePropertyForKey with kCFURLFileSecurityKey and then the CFFileSecurity API instead."); CF_EXPORT -const CFStringRef kCFURLHTTPStatusCode API_DEPRECATED("Use NSHTTPURLResponse methods instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLHTTPStatusCode CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use NSHTTPURLResponse methods instead."); CF_EXPORT -const CFStringRef kCFURLHTTPStatusLine API_DEPRECATED("Use NSHTTPURLResponse methods instead.", macos(10.0,10.9), ios(2.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +const CFStringRef kCFURLHTTPStatusLine CF_DEPRECATED(10_0, 10_9, 2_0, 7_0, "Use NSHTTPURLResponse methods instead."); /* The value of kCFURLFileExists is a CFBoolean */ /* The value of kCFURLFileDirectoryContents is a CFArray containing CFURLs. An empty array means the directory exists, but is empty */ diff --git a/CoreFoundation/URL.subproj/CFURLPriv.h b/CoreFoundation/URL.subproj/CFURLPriv.h index 733b12b5a2..23a580e37f 100644 --- a/CoreFoundation/URL.subproj/CFURLPriv.h +++ b/CoreFoundation/URL.subproj/CFURLPriv.h @@ -1,7 +1,7 @@ /* CFURLPriv.h - Copyright (c) 2008-2017, Apple Inc. and the Swift project authors + Copyright (c) 2008-2016, Apple Inc. and the Swift project authors - Portions Copyright (c) 2014-2017, Apple Inc. and the Swift project authors + Portions Copyright (c) 2014-2016 Apple Inc. and the Swift project authors Licensed under Apache License v2.0 with Runtime Library Exception See http://swift.org/LICENSE.txt for license information See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors @@ -45,320 +45,295 @@ enum { kCFURLWriteUnsupportedSchemeError = 518, // Write error (unsupported URL scheme) kCFURLWriteOutOfSpaceError = 640, // Write error (out of storage space) kCFURLWriteVolumeReadOnlyError = 642, // Write error (readonly volume) -} API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); +} CF_ENUM_AVAILABLE(10_5, 2_0); /* Private File System Property Keys */ -CF_EXPORT const CFStringRef _kCFURLPathKey API_DEPRECATED("Use the kCFURLPathKey or NSURLPathKey public property keys instead", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLPathKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLPathKey or NSURLPathKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIDKey CF_AVAILABLE(10_6, 4_0); /* Volume ID (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLInodeNumberKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLInodeNumberKey CF_AVAILABLE(10_6, 4_0); /* 64-bit inode number (the inode number from the file system) (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLFileIDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLFileIDKey CF_AVAILABLE(10_6, 4_0); /* 64-bit file ID (for tracking a file by ID. This may or may not be the inode number) (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLParentDirectoryIDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.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) */ -CF_EXPORT const CFStringRef _kCFURLDistinctLocalizedNameKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLDistinctLocalizedNameKey CF_AVAILABLE(10_6, 4_0); /* The localized name, if it is distinct from the real name. Otherwise, NULL (CFString) */ -CF_EXPORT const CFStringRef _kCFURLNameExtensionKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLNameExtensionKey CF_AVAILABLE(10_6, 4_0); /* The name extension (CFString) */ -CF_EXPORT const CFStringRef _kCFURLFinderInfoKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLFinderInfoKey CF_AVAILABLE(10_6, 4_0); /* A 16-byte Finder Info structure immediately followed by a 16-byte Extended Finder Info structure (CFData) */ -CF_EXPORT const CFStringRef _kCFURLIsUserNoDumpKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsUserNoDumpKey CF_AVAILABLE(10_11, 9_0); /* True if resource's UF_NODUMP flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsUserAppendKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsUserAppendKey CF_AVAILABLE(10_11, 9_0); /* True if resource's UF_APPEND flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsUserOpaqueKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsUserOpaqueKey CF_AVAILABLE(10_11, 9_0); /* True if resource's UF_OPAQUE flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsCompressedKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsCompressedKey CF_AVAILABLE(10_6, 4_0); /* True if resource's data is transparently compressed by the system on its storage device (UF_COMPRESSED flag is set) (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsUserTrackedKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsUserTrackedKey CF_AVAILABLE(10_11, 9_0); /* True if resource's UF_TRACKED flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsUserDataVaultKey API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - /* True if resource's UF_DATAVAULT flag is set (CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLIsSystemArchivedKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsSystemArchivedKey CF_AVAILABLE(10_11, 9_0); /* True if resource's SF_ARCHIVED flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsSystemAppendKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsSystemAppendKey CF_AVAILABLE(10_11, 9_0); /* True if resource's SF_APPEND flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsRestrictedKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsRestrictedKey CF_AVAILABLE(10_11, 9_0); /* True if resource is restricted (SF_RESTRICTED flag is set) (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsSystemNoUnlinkKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLIsSystemNoUnlinkKey CF_AVAILABLE(10_11, 9_0); /* True if resource's SF_NOUNLINK flag is set (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsApplicationKey API_DEPRECATED("Use kCFURLIsApplicationKey (API) instead", macos(10.6,10.11), ios(4.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLIsApplicationKey CF_DEPRECATED(10_6, 10_11, 4_0, 9_0, "Use kCFURLIsApplicationKey (API) instead"); /* Deprecated and scheduled for removal in 10.12/10.0 - Use the kCFURLIsApplicationKey or NSURLIsApplicationKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLApplicationIsAppletKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLApplicationIsAppletKey CF_AVAILABLE(10_11, NA); /* The item is an OSA or Automator applet. Only applies to applications. (Read-only, value type CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLApplicationHasSupportedFormatKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLApplicationHasSupportedFormatKey CF_AVAILABLE(10_11, NA); /* The item is an application that can be executed on the current system. (Read-only, value type CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLCanSetHiddenExtensionKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLCanSetHiddenExtensionKey CF_AVAILABLE(10_6, 4_0); /* True if the filename extension can be hidden or unhidden (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLIsReadableKey API_DEPRECATED("Use the kCFURLIsReadableKey or NSURLIsReadableKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLIsReadableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsReadableKey or NSURLIsReadableKey public property keys */ -/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanReadKey API_DEPRECATED("Not supported", macos(10.0,10.6), ios(2.0,4.0), watchos(2.0,2.0), tvos(9.0,9.0)); +/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanReadKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0); -CF_EXPORT const CFStringRef _kCFURLIsWriteableKey API_DEPRECATED("Use the kCFURLIsWritableKey or NSURLIsWritableKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLIsWriteableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsWritableKey or NSURLIsWritableKey public property keys */ -/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanWriteKey API_DEPRECATED("Not supported", macos(10.0,10.6), ios(2.0,4.0), watchos(2.0,2.0), tvos(9.0,9.0)); +/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanWriteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0); -CF_EXPORT const CFStringRef _kCFURLIsExecutableKey API_DEPRECATED("Use the kCFURLIsExecutableKey or NSURLIsExecutableKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLIsExecutableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLIsExecutableKey or NSURLIsExecutableKey public property keys */ -/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanExecuteKey API_DEPRECATED("Not supported", macos(10.0,10.6), ios(2.0,4.0), watchos(2.0,2.0), tvos(9.0,9.0)); +/* never implemented and scheduled for removal in 10.10/8.0 */CF_EXPORT const CFStringRef _kCFURLUserCanExecuteKey CF_DEPRECATED(10_0, 10_6, 2_0, 4_0); -CF_EXPORT const CFStringRef _kCFURLParentDirectoryIsVolumeRootKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLParentDirectoryIsVolumeRootKey CF_AVAILABLE(10_6, 4_0); /* True if the parent directory is the root of a volume (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLFileSecurityKey API_DEPRECATED("Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLFileSecurityKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLFileSizeOfResourceForkKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLFileSizeOfResourceForkKey CF_AVAILABLE(10_6, 4_0); /* Size in bytes of the resource fork (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLFileAllocatedSizeOfResourceForkKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLFileAllocatedSizeOfResourceForkKey CF_AVAILABLE(10_6, 4_0); /* Size in bytes of the blocks allocated for the resource fork (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLEffectiveIconImageDataKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLEffectiveIconImageDataKey CF_AVAILABLE(10_6, 4_0); /* Icon image data, i.e. raw pixel data (CFData) */ -CF_EXPORT const CFStringRef _kCFURLTypeBindingKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLTypeBindingKey CF_AVAILABLE(10_10, 8_0); /* Type binding for icon (Read-only, value type CFData) */ -CF_EXPORT const CFStringRef _kCFURLCustomIconImageDataKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLCustomIconImageDataKey CF_AVAILABLE(10_6, 4_0); /* Icon image data of the item's custom icon, if any (CFData) */ -CF_EXPORT const CFStringRef _kCFURLEffectiveIconFlattenedReferenceDataKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLEffectiveIconFlattenedReferenceDataKey CF_AVAILABLE(10_6, 4_0); /* Icon flattened reference, suitable for cheaply sharing the effective icon reference across processess (CFData) */ -CF_EXPORT const CFStringRef _kCFURLBundleIdentifierKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLBundleIdentifierKey CF_AVAILABLE(10_6, 4_0); /* If resource is a bundle, the bundle identifier (CFString) */ -CF_EXPORT const CFStringRef _kCFURLVersionKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVersionKey CF_AVAILABLE(10_6, 4_0); /* If resource is a bundle, the bundle version (CFBundleVersion) as a string (CFString) */ -CF_EXPORT const CFStringRef _kCFURLShortVersionStringKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLShortVersionStringKey CF_AVAILABLE(10_6, 4_0); /* If resource is a bundle, the bundle short version (CFBundleShortVersionString) as a string (CFString) */ -CF_EXPORT const CFStringRef _kCFURLOwnerIDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); - /* 32-bit owner ID (uid_t). (CFNumber) Note: Almost all clients should use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetOwner() instead of this. */ - -CF_EXPORT const CFStringRef _kCFURLGroupIDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); - /* 32-bit group ID (gid_t) (CFNumber) Note: Almost all clients should use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetGroup() instead of this. */ +CF_EXPORT const CFStringRef _kCFURLOwnerIDKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); + /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetOwner() */ -CF_EXPORT const CFStringRef _kCFURLStatModeKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); - /* 32-bit group ID (mode_t) (CFNumber) Note: Almost all clients should use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetMode() instead of this. */ +CF_EXPORT const CFStringRef _kCFURLGroupIDKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); + /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetGroup() */ -/* To determine which dictionary to request from _kCFURLLocalizedNameDictionaryKey or _kCFURLLocalizedNameWithExtensionsHiddenDictionaryKey, you can consult _LSGetShowAllExtensionsPreference() on macOS. On iOS, extensions are always hidden. */ +CF_EXPORT const CFStringRef _kCFURLStatModeKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); + /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused - Use the kCFURLFileSecurityKey or NSURLFileSecurityKey public property keys and CFFileSecurityGetMode() */ -CF_EXPORT const CFStringRef _kCFURLLocalizedNameDictionaryKey API_AVAILABLE(macos(10.7), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLLocalizedNameDictionaryKey CF_AVAILABLE(10_7, 9_0); /* For items with localized display names, the dictionary of all available localizations. The keys are the cannonical locale strings for the available localizations. (CFDictionary) */ -CF_EXPORT const CFStringRef _kCFURLLocalizedNameWithExtensionsHiddenDictionaryKey API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - /* For items with localized display names, the dictionary of all available localizations with extensions hidden if safe. The keys are the cannonical locale strings for the available localizations. (CFDictionary) */ - -CF_EXPORT const CFStringRef _kCFURLLocalizedTypeDescriptionDictionaryKey API_AVAILABLE(macos(10.7), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLLocalizedTypeDescriptionDictionaryKey CF_AVAILABLE(10_7, 9_0); /* The dictionary of all available localizations of the item kind string. The keys are the cannonical locale strings for the available localizations. (CFDictionary) */ -CF_EXPORT const CFStringRef _kCFURLApplicationCategoriesKey API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLApplicationCategoriesKey CF_AVAILABLE(10_7, NA); /* The array of category UTI strings associated with the url. (CFArray) */ -CF_EXPORT const CFStringRef _kCFURLApplicationHighResolutionModeIsMagnifiedKey API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLApplicationHighResolutionModeIsMagnifiedKey CF_AVAILABLE(10_7, NA); /* True if the app runs with magnified 1x graphics on a 2x display (Per-user, CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLCanSetApplicationHighResolutionModeIsMagnifiedKey API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +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 API_AVAILABLE(macos(10.8)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLWriterBundleIdentifierKey CF_AVAILABLE(10_8, NA); /* The bundle identifier of the process writing to this object (Read-write, value type CFString) */ -CF_EXPORT const CFStringRef _kCFURLApplicationNapIsDisabledKey API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLApplicationNapIsDisabledKey CF_AVAILABLE(10_9, NA); /* True if app nap is disabled (Applications only, Per-user, CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLCanSetApplicationNapIsDisabledKey API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLCanSetApplicationNapIsDisabledKey CF_AVAILABLE(10_9, NA); /* True if the ApplicationNapIsDisabled property value can be changed (Applications only, Read only, CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLCanSetStrongBindingKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLCanSetStrongBindingKey CF_AVAILABLE(10_11, NA); /* True if the strong binding can be changed (Read only, CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLStrongBindingKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLStrongBindingKey CF_AVAILABLE(10_11, NA); /* The application to which the file is strongly bound (Read-write, value type CFURL) */ -CF_EXPORT const CFStringRef _kCFURLArchitecturesValidOnCurrentSystemKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLArchitecturesValidOnCurrentSystemKey CF_AVAILABLE(10_11, 9_0); /* Array of CFStringRefs, each element an architecture identifier. The array includes the list of executable architectures found in the application bundle's executable that can be executed on the current system. (Read-only, value type CFArray of CFStrings) */ CF_EXPORT -const CFStringRef _kCFURLApplicationArchitecturesKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +const CFStringRef _kCFURLApplicationArchitecturesKey CF_AVAILABLE(10_11, 9_0); /* The complete list of executable architectures found in the application bundle's executable (Read-only, value type CFArray of CFString) */ -CF_EXPORT const CFStringRef _kCFURLFaultLogicalFileIsHiddenKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLFaultLogicalFileIsHiddenKey CF_AVAILABLE(10_11, 9_0); /* True if the fault logical file is hidden. (Read only, CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLLocalizedNameComponentsKey API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); - /* An array containing the base name of the file and (if present) the extension to be used for display. Does not include extra Unicode visual ordering characters added by the system. For Finder use. (Read-only, value type CFArray of CFStrings) */ /* Additional volume properties */ -CF_EXPORT const CFStringRef _kCFURLVolumeRefNumKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeRefNumKey CF_AVAILABLE(10_6, 4_0); /* The Carbon File Manager's FSVolumeRefNum for the resource volume (CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLVolumeUUIDStringKey API_DEPRECATED("Use the kCFURLVolumeUUIDStringKey or NSURLVolumeUUIDStringKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeUUIDStringKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeUUIDStringKey or NSURLVolumeUUIDStringKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeCreationDateKey API_DEPRECATED("Use the kCFURLVolumeCreationDateKey or NSURLVolumeCreationDateKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeCreationDateKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeCreationDateKey or NSURLVolumeCreationDateKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsLocalKey API_DEPRECATED("Use the kCFURLVolumeIsLocalKey or NSURLVolumeIsLocalKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsLocalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsLocalKey or NSURLVolumeIsLocalKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsAutomountKey API_DEPRECATED("Use the kCFURLVolumeIsAutomountedKey or NSURLVolumeIsAutomountedKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsAutomountKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsAutomountedKey or NSURLVolumeIsAutomountedKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeDontBrowseKey API_DEPRECATED("Use the kCFURLVolumeIsBrowsableKey or NSURLVolumeIsBrowsableKey public property keys (Note: value is inverse of _kCFURLVolumeDontBrowseKey)", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeDontBrowseKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsBrowsableKey or NSURLVolumeIsBrowsableKey public property keys (Note: value is inverse of _kCFURLVolumeDontBrowseKey) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsReadOnlyKey API_DEPRECATED("Use the kCFURLVolumeIsReadOnlyKey or NSURLVolumeIsReadOnlyKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsReadOnlyKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsReadOnlyKey or NSURLVolumeIsReadOnlyKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsQuarantinedKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsQuarantinedKey CF_AVAILABLE(10_6, 4_0); /* Mounted quarantined (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsEjectableKey API_DEPRECATED("Use the kCFURLVolumeIsEjectableKey or NSURLVolumeIsEjectableKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsEjectableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsEjectableKey or NSURLVolumeIsEjectableKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsRemovableKey API_DEPRECATED("Use the kCFURLVolumeIsRemovableKey or NSURLVolumeIsRemovableKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsRemovableKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsRemovableKey or NSURLVolumeIsRemovableKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsInternalKey API_DEPRECATED("Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key)", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsInternalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsExternalKey API_DEPRECATED("Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key)", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsExternalKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeIsInternalKey or NSURLVolumeIsInternalKey public property keys (Note: this has slightly different behavior than the public VolumeIsInternal key) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsDiskImageKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsDiskImageKey CF_AVAILABLE(10_6, 4_0); /* Volume is a mounted disk image (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLDiskImageBackingURLKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLDiskImageBackingURLKey CF_AVAILABLE(10_6, 4_0); /* If volume is a mounted disk image, the URL of the backing disk image (CFURL) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsFileVaultKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsFileVaultKey CF_AVAILABLE(10_6, 4_0); /* Volume uses File Vault encryption (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsiDiskKey API_DEPRECATED("No supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsiDiskKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */ -CF_EXPORT const CFStringRef _kCFURLVolumeiDiskUserNameKey API_DEPRECATED("Not supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeiDiskUserNameKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsLocaliDiskMirrorKey API_DEPRECATED("Not supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsLocaliDiskMirrorKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsiPodKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsiPodKey CF_AVAILABLE(10_6, 4_0); /* Volume is on an iPod (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsCDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsCDKey CF_AVAILABLE(10_6, 4_0); /* Volume is a CD (audio or CD-ROM). (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsDVDKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsDVDKey CF_AVAILABLE(10_6, 4_0); /* Volume is a DVD (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsDeviceFileSystemKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsDeviceFileSystemKey CF_AVAILABLE(10_7, 5_0); /* Volume is devfs (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsHFSStandardKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeIsHFSStandardKey CF_AVAILABLE(10_6, 4_0); /* Volume is HFS standard (which includes AFP volumes). Directory IDs, but not file IDs, can be looked up. (CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconFamilyNameKey API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconFamilyNameKey CF_AVAILABLE(10_9, NA); /* Volume's IOMediaIconFamilyName. (CFStringRef) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconBundleIdentifierKey API_AVAILABLE(macos(10.9)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeIOMediaIconBundleIdentifierKey CF_AVAILABLE(10_9, NA); /* Volume's IOMediaIconBundleIdentifier. (CFStringRef) */ -CF_EXPORT const CFStringRef _kCFURLVolumeQuarantinePropertiesKey API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeQuarantinePropertiesKey CF_AVAILABLE(10_10, NA); /* The quarantine properties for the volume on which the resource resides as defined in LSQuarantine.h.=To remove quarantine information from a volume, pass kCFNull as the value when setting this property. (Read-write, value type CFDictionary) */ -CF_EXPORT const CFStringRef _kCFURLVolumeOpenFolderURLKey API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeOpenFolderURLKey CF_AVAILABLE(10_10, NA); /* Returns a URL to the folder the Finder should open when a HFS volume is mounted, or NULL if there is none. (Read-only, value type CFURL) */ -CF_EXPORT const CFStringRef _kCFURLResolvedFromBookmarkDataKey API_DEPRECATED("Not supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLResolvedFromBookmarkDataKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal later in 10.9/7.0 since it is unused (*/ -CF_EXPORT const CFStringRef _kCFURLVolumeMountPointStringKey API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeMountPointStringKey CF_AVAILABLE(10_6, 4_0); /* the volume mountpoint string (Read-only, value type CFString) */ -CF_EXPORT const CFStringRef _kCFURLVolumeDeviceIDKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLVolumeDeviceIDKey CF_AVAILABLE(10_11, 9_0); /* the volume's dev_t (Read-only, value type CFNumber) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsTimeMachineKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeIsTimeMachineKey CF_AVAILABLE(10_11, NA); /* Volume is the Time Machine volume (Read-write, value type CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsAirportKey API_AVAILABLE(macos(10.11)) API_UNAVAILABLE(ios, watchos, tvos); +CF_EXPORT const CFStringRef _kCFURLVolumeIsAirportKey CF_AVAILABLE(10_11, NA); /* Volume is an airport volume (Read-write, value type CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLVolumeIsVideoDiskKey API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos); - /* Volume is video disk (Read-only, value type CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLVolumeIsDVDVideoKey API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos); - /* Volume is DVD video (Read-only, value type CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLVolumeIsBDVideoKey API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos); - /* Volume is BD video (Read-only, value type CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLVolumeIsMobileTimeMachineKey API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos); - /* Volume is mobile time machine (Read-only, value type CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLVolumeIsNetworkOpticalKey API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos); - /* Volume is network optical (Read-only, value type CFBoolean) */ - -CF_EXPORT const CFStringRef _kCFURLCompleteMountURLKey API_DEPRECATED("Use the kCFURLVolumeURLForRemountingKey or NSURLVolumeURLForRemountingKey public property keys", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +CF_EXPORT const CFStringRef _kCFURLCompleteMountURLKey CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the kCFURLVolumeURLForRemountingKey or NSURLVolumeURLForRemountingKey public property keys */ -CF_EXPORT const CFStringRef _kCFURLUbiquitousItemDownloadRequestedKey API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLUbiquitousItemDownloadRequestedKey CF_AVAILABLE(10_9, 7_0); /* Is this Ubiquity item scheduled for download? (this is also true for items that are already downloaded). Use startDownloadingUbiquitousItemAtURL:error: to make this true (Read-only, value type CFBoolean) */ -CF_EXPORT const CFStringRef _kCFURLCloudDocsPlaceholderDictionaryKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLCloudDocsPlaceholderDictionaryKey CF_AVAILABLE(10_10, 8_0); /* Returns the placeholder dictionary for a side-fault file (Read-only, value type CFDictionary) */ -CF_EXPORT const CFStringRef _kCFURLCloudDocsPlaceholderLogicalNameKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef _kCFURLCloudDocsPlaceholderLogicalNameKey CF_AVAILABLE(10_10, 8_0); /* Returns the placeholder dictionary for a side-fault file (Read-only, value type CFString) */ // Temporary holding place for future API. -CF_EXPORT const CFStringRef kCFURLUbiquitousItemDownloadRequestedKey API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFURLUbiquitousItemDownloadRequestedKey CF_AVAILABLE(10_9, 7_0); /* Is this Ubiquity item scheduled for download? (this is also true for items that are already downloaded). Use startDownloadingUbiquitousItemAtURL:error: to make this true (Read-only, value type CFBoolean) */ -CF_EXPORT const CFStringRef kCFURLUbiquitousItemContainerDisplayNameKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFURLUbiquitousItemContainerDisplayNameKey CF_AVAILABLE(10_10, 8_0); /* Returns the localized name of the ubiquity container that contains this item (Read-only, value type CFString) */ CF_EXPORT const CFStringRef kCFURLUbiquitousItemIsSharedKey; // true if the ubiquitous item is shared. (Read-only, value type boolean NSNumber) -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemCurrentUserRoleKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // Replaced by kCFURLUbiquitousSharedItemCurrentUserRoleKey. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleOwner API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // the current user is the owner of this shared item. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleParticipant API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // the current user is a participant of this shared item. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemCurrentUserRoleKey CF_AVAILABLE(10_11, 9_0); // Replaced by kCFURLUbiquitousSharedItemCurrentUserRoleKey. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleOwner CF_AVAILABLE(10_11, 9_0); // the current user is the owner of this shared item. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleParticipant CF_AVAILABLE(10_11, 9_0); // the current user is a participant of this shared item. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemOwnerNameComponentsKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // returns a NSPersonNameComponents, or nil if the current user. (Read-only, value type NSPersonNameComponents) +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemOwnerNameComponentsKey CF_AVAILABLE(10_11, 9_0); // returns a NSPersonNameComponents, or nil if the current user. (Read-only, value type NSPersonNameComponents) CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemMostRecentEditorNameComponentsKey API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // returns a NSPersonNameComponents for the most recent editro fo the file, or nil if the current user. (Read-only, value type NSPersonNameComponents) CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemCurrentUserPermissionsKey API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // returns the permissions for a participant of this shared item, or nil if not shared. (Read-only, value type NSString). Possible values below. @@ -366,18 +341,18 @@ CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemPermissionsReadOnly API_AV CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemPermissionsReadWrite API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); // participants are allowed to both read and write this item // Deprecated. Will be removed. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // Replaced by kCFURLUbiquitousSharedItemCurrentUserRoleKey. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemOwnerNameKey API_DEPRECATED("Replaced by kCFURLUbiquitousSharedItemOwnerNameComponentsKey", macos(10.11,10.11), ios(9.0,9.0), watchos(2.0,2.0), tvos(9.0,9.0)); -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemPermissionsKey API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); // returns the permissions for a participant of this shared item, or nil if not shared. (Read-only, value type NSString). Possible values below. -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemReadOnlyPermissions API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemReadWritePermissions API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemRoleKey CF_AVAILABLE(10_11, 9_0); // Replaced by kCFURLUbiquitousSharedItemCurrentUserRoleKey. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemOwnerNameKey CF_DEPRECATED(10_11, 10_11, 9_0, 9_0); // Replaced by kCFURLUbiquitousSharedItemOwnerNameComponentsKey. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemPermissionsKey CF_AVAILABLE(10_11, 9_0); // returns the permissions for a participant of this shared item, or nil if not shared. (Read-only, value type NSString). Possible values below. +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemReadOnlyPermissions CF_AVAILABLE(10_11, 9_0); +CF_EXPORT const CFStringRef kCFURLUbiquitousSharedItemReadWritePermissions CF_AVAILABLE(10_11, 9_0); // these keys are defined here, not in CFURL.h, because they return NSImage values which can only be used by Foundation -CF_EXPORT const CFStringRef kCFURLThumbnailDictionaryKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); -CF_EXPORT const CFStringRef kCFURLThumbnailKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFURLThumbnailDictionaryKey CF_AVAILABLE(10_10, 8_0); +CF_EXPORT const CFStringRef kCFURLThumbnailKey CF_AVAILABLE(10_10, 8_0); // The values of thumbnails in the dictionary returned by NSURLThumbnailDictionaryKey -CF_EXPORT const CFStringRef kCFThumbnail1024x1024SizeKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CF_EXPORT const CFStringRef kCFThumbnail1024x1024SizeKey CF_AVAILABLE(10_10, 8_0); // This private key is only for the use of CFURLPromises and the URL cache code in CoreServicesInternal CF_EXPORT const CFStringRef _kCFURLPromisePhysicalURLKey API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); @@ -400,7 +375,7 @@ enum { kCFURLResourceHasHiddenExtension = 0x00000100, kCFURLResourceIsApplication = 0x00000200, kCFURLResourceIsCompressed = 0x00000400, - kCFURLResourceIsSystemCompressed API_DEPRECATED("Use kCFURLResourceIsCompressed instead", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)) + kCFURLResourceIsSystemCompressed CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0) = 0x00000400, /* Deprecated and scheduled for removal in 10.10/8.0 - Use kCFURLResourceIsCompressed */ kCFURLCanSetHiddenExtension = 0x00000800, kCFURLResourceIsReadable = 0x00001000, @@ -420,7 +395,7 @@ typedef unsigned long long CFURLResourcePropertyFlags; returns false. A valid output error must be released by the caller. */ CF_EXPORT -Boolean _CFURLGetResourcePropertyFlags(CFURLRef url, CFURLResourcePropertyFlags mask, CFURLResourcePropertyFlags *flags, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean _CFURLGetResourcePropertyFlags(CFURLRef url, CFURLResourcePropertyFlags mask, CFURLResourcePropertyFlags *flags, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); #if TARGET_OS_MAC || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) /* @@ -470,7 +445,7 @@ typedef struct _CFURLFilePropertyValues _CFURLFilePropertyValues; returns false. A valid output error must be released by the caller. */ CF_EXPORT -Boolean _CFURLCopyResourcePropertyValuesAndFlags( CFURLRef url, CFURLFilePropertyBitmap requestProperties, CFURLFilePropertyBitmap *actualProperties, struct _CFURLFilePropertyValues *properties, CFURLResourcePropertyFlags propertyFlagsMask, CFURLResourcePropertyFlags *propertyFlags, CFErrorRef *error) API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean _CFURLCopyResourcePropertyValuesAndFlags( CFURLRef url, CFURLFilePropertyBitmap requestProperties, CFURLFilePropertyBitmap *actualProperties, struct _CFURLFilePropertyValues *properties, CFURLResourcePropertyFlags propertyFlagsMask, CFURLResourcePropertyFlags *propertyFlags, CFErrorRef *error) CF_AVAILABLE(10_7, 4_0); #endif /* @@ -488,10 +463,10 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) { kCFURLVolumeIsExternal = 0x100LL, kCFURLVolumeIsDiskImage = 0x200LL, kCFURLVolumeIsFileVault = 0x400LL, - kCFURLVolumeIsLocaliDiskMirror API_DEPRECATED("iDisk no longer supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)) + kCFURLVolumeIsLocaliDiskMirror CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0) = 0x800LL, // Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks kCFURLVolumeIsiPod = 0x1000LL, - kCFURLVolumeIsiDisk API_DEPRECATED("iDisk no longer supported", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)) + kCFURLVolumeIsiDisk CF_ENUM_DEPRECATED(10_6, 10_9, 4_0, 7_0) = 0x2000LL, // Deprecated and scheduled for removal in 10.10/8.0 - there are no more iDisks kCFURLVolumeIsCD = 0x4000LL, kCFURLVolumeIsDVD = 0x8000LL, @@ -514,9 +489,9 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) { = 0x1000000LL, kCFURLVolumeIsBeingUnmounted CF_ENUM_AVAILABLE_MAC(10_9) = 0x2000000LL, - kCFURLVolumeIsRootFileSystem API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) + kCFURLVolumeIsRootFileSystem CF_ENUM_AVAILABLE_MAC(10_11) = 0x4000000LL, - kCFURLVolumeIsEncrypted API_AVAILABLE(macos(10.11), ios(9.0), watchos(2.0), tvos(9.0)) + kCFURLVolumeIsEncrypted CF_ENUM_AVAILABLE_MAC(10_11) = 0x8000000LL, // IMPORTANT: The values of the following flags must stay in sync with the @@ -568,7 +543,7 @@ typedef CF_OPTIONS(unsigned long long, CFURLVolumePropertyFlags) { returns false. A valid output error must be released by the caller. */ CF_EXPORT -Boolean _CFURLGetVolumePropertyFlags(CFURLRef url, CFURLVolumePropertyFlags mask, CFURLVolumePropertyFlags *flags, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean _CFURLGetVolumePropertyFlags(CFURLRef url, CFURLVolumePropertyFlags mask, CFURLVolumePropertyFlags *flags, CFErrorRef *error) CF_AVAILABLE(10_6, 4_0); /* _CFURLCopyResourcePropertyForKeyFromCache works like CFURLCopyResourcePropertyForKey @@ -581,7 +556,7 @@ Boolean _CFURLGetVolumePropertyFlags(CFURLRef url, CFURLVolumePropertyFlags mask Only for use by DesktopServices! */ CF_EXPORT -Boolean _CFURLCopyResourcePropertyForKeyFromCache(CFURLRef url, CFStringRef key, void *cfTypeRefValue) API_AVAILABLE(macos(10.8), ios(8.3), watchos(2.0), tvos(9.0)); +Boolean _CFURLCopyResourcePropertyForKeyFromCache(CFURLRef url, CFStringRef key, void *cfTypeRefValue) CF_AVAILABLE(10_8, 8_3); /* _CFURLCopyResourcePropertiesForKeysFromCache works like CFURLCopyResourcePropertiesForKeys only it never causes I/O. If the property values requested are cached (or known @@ -592,7 +567,7 @@ Boolean _CFURLCopyResourcePropertyForKeyFromCache(CFURLRef url, CFStringRef key, Only for use by DesktopServices! */ CF_EXPORT -CFDictionaryRef _CFURLCopyResourcePropertiesForKeysFromCache(CFURLRef url, CFArrayRef keys) API_AVAILABLE(macos(10.8), ios(8.3), watchos(2.0), tvos(9.0)); +CFDictionaryRef _CFURLCopyResourcePropertiesForKeysFromCache(CFURLRef url, CFArrayRef keys) CF_AVAILABLE(10_8, 8_3); /* _CFURLCacheResourcePropertyForKey works like CFURLCopyResourcePropertyForKey only it does not return the property value -- it just ensures the value is cached. @@ -603,7 +578,7 @@ CFDictionaryRef _CFURLCopyResourcePropertiesForKeysFromCache(CFURLRef url, CFArr Only for use by DesktopServices! */ CF_EXPORT -Boolean _CFURLCacheResourcePropertyForKey(CFURLRef url, CFStringRef key, CFErrorRef *error) API_AVAILABLE(macos(10.8), ios(8.3), watchos(2.0), tvos(9.0)); +Boolean _CFURLCacheResourcePropertyForKey(CFURLRef url, CFStringRef key, CFErrorRef *error) CF_AVAILABLE(10_8, 8_3); /* _CFURLCacheResourcePropertiesForKeys works like CFURLCopyResourcePropertiesForKeys only it does not return the property values -- it just ensures the values is cached. @@ -614,7 +589,7 @@ Boolean _CFURLCacheResourcePropertyForKey(CFURLRef url, CFStringRef key, CFError Only for use by DesktopServices! */ CF_EXPORT -Boolean _CFURLCacheResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) API_AVAILABLE(macos(10.8), ios(8.3), watchos(2.0), tvos(9.0)); +Boolean _CFURLCacheResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFErrorRef *error) CF_AVAILABLE(10_8, 8_3); /* _CFURLCreateDisplayPathComponentsArray() @@ -648,22 +623,22 @@ Boolean _CFURLCacheResourcePropertiesForKeys(CFURLRef url, CFArrayRef keys, CFEr A CFArray or NULL if an error occurred. */ CF_EXPORT -CFArrayRef _CFURLCreateDisplayPathComponentsArray(CFURLRef url, CFErrorRef *error) API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)); +CFArrayRef _CFURLCreateDisplayPathComponentsArray(CFURLRef url, CFErrorRef *error) CF_AVAILABLE(10_7, 4_0); /* Returns true for URLs that locate file system resources. */ CF_EXPORT -Boolean _CFURLIsFileURL(CFURLRef url) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +Boolean _CFURLIsFileURL(CFURLRef url) CF_AVAILABLE(10_6, 4_0); /* Deprecated and scheduled for removal in 10.10/8.0 - Use the public API CFURLIsFileReferenceURL() */ CF_EXPORT -Boolean _CFURLIsFileReferenceURL(CFURLRef url) API_DEPRECATED("Use CFURLIsFileReferenceURL() instead", macos(10.6,10.9), ios(4.0,7.0), watchos(2.0,2.0), tvos(9.0,9.0)); +Boolean _CFURLIsFileReferenceURL(CFURLRef url) CF_DEPRECATED(10_6, 10_9, 4_0, 7_0); /* For use by Core Services */ CF_EXPORT -void *__CFURLResourceInfoPtr(CFURLRef url) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +void *__CFURLResourceInfoPtr(CFURLRef url) CF_AVAILABLE(10_6, 4_0); CF_EXPORT -void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0)); +void __CFURLSetResourceInfoPtr(CFURLRef url, void *ptr) CF_AVAILABLE(10_6, 4_0); struct FSCatalogInfo; @@ -671,7 +646,7 @@ struct HFSUniStr255; /* _CFURLGetCatalogInfo is used by LaunchServices */ CF_EXPORT -SInt32 _CFURLGetCatalogInfo(CFURLRef url, UInt32 whichInfo, struct FSCatalogInfo *catalogInfo, struct HFSUniStr255 *name) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +SInt32 _CFURLGetCatalogInfo(CFURLRef url, UInt32 whichInfo, struct FSCatalogInfo *catalogInfo, struct HFSUniStr255 *name) CF_AVAILABLE(10_7, 5_0); /* _CFURLReplaceObject SPI */ @@ -686,34 +661,34 @@ enum { /* _CFURLReplaceObject is the underlying implementation for -[NSFileManager replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error:] with one additional argument: newName. The optional newName argument can be used to rename the replacement (for example, when replacing "document.rtf" with "document.rtfd") while still preserving the document's metadata. If newName is used, there must be a file or directory at originalItemURL -- if originalItemURL does not exist and newName is not NULL, an error will be returned. */ CF_EXPORT -Boolean _CFURLReplaceObject( CFAllocatorRef allocator, CFURLRef originalItemURL, CFURLRef newItemURL, CFStringRef newName, CFStringRef backupItemName, CFOptionFlags options, CFURLRef *resultingURL, CFErrorRef *error ) API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); +Boolean _CFURLReplaceObject( CFAllocatorRef allocator, CFURLRef originalItemURL, CFURLRef newItemURL, CFStringRef newName, CFStringRef backupItemName, CFOptionFlags options, CFURLRef *resultingURL, CFErrorRef *error ) CF_AVAILABLE(10_7, 5_0); CF_EXPORT -Boolean _CFURLIsProtectedDirectory(CFURLRef directoryURL) API_AVAILABLE(macos(10.10)) API_UNAVAILABLE(ios, watchos, tvos); +Boolean _CFURLIsProtectedDirectory(CFURLRef directoryURL) CF_AVAILABLE(10_10, NA); /* _CFURLAttachSecurityScopeToFileURL attaches a sandbox extension to the file URL object. The URL object will then be security-scoped and will be usable with the NSURL's -startAccessingSecurityScopedResource method and CFURL's CFURLStartAccessingSecurityScopedResource() function. The URL object must be a file URL. If the URL object already has a sandbox extension attached, the new extension replaces the previous sandbox extension. If NULL is passed for the sandboxExtension, the sandbox extension (if any) is removed from the URL object. Callers would be responsible for ensuring the sandbox extension matches the URL's file system path. Note: The sandbox extension is a C-string INCLUDING the terminating nul character stored in a CFData object. */ CF_EXPORT -void _CFURLAttachSecurityScopeToFileURL(CFURLRef url, CFDataRef sandboxExtension) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +void _CFURLAttachSecurityScopeToFileURL(CFURLRef url, CFDataRef sandboxExtension) CF_AVAILABLE(10_10, 8_0); /* _CFURLCopySecurityScopeFromFileURL copies the sandbox extension attached to the file URL object. If the URL is not a file URL or doesn't have a sandbox extension, NULL will be returned. */ CF_EXPORT -CFDataRef _CFURLCopySecurityScopeFromFileURL(CFURLRef url) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CFDataRef _CFURLCopySecurityScopeFromFileURL(CFURLRef url) CF_AVAILABLE(10_10, 8_0); CF_EXPORT -void _CFURLSetPermanentResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +void _CFURLSetPermanentResourcePropertyForKey(CFURLRef url, CFStringRef key, CFTypeRef propertyValue) CF_AVAILABLE(10_10, 8_0); // Returns a string describing the bookmark data. For debugging purposes only. CF_EXPORT -CFStringRef _CFURLBookmarkCopyDescription(CFDataRef bookmarkRef) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CFStringRef _CFURLBookmarkCopyDescription(CFDataRef bookmarkRef) CF_AVAILABLE(10_10, 8_0); #if TARGET_OS_MAC || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) // private CFURLBookmarkCreationOptions enum { - kCFURLBookmarkCreationWithFileProvider API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)) = ( 1UL << 26 ), // private option to create bookmarks with file provider string. The file provider string overrides the rest of the bookmark data at resolution time. + kCFURLBookmarkCreationWithFileProvider CF_ENUM_AVAILABLE(10_10, 8_0) = ( 1UL << 26 ), // private option to create bookmarks with file provider string. The file provider string overrides the rest of the bookmark data at resolution time. kCFURLBookmarkOperatingInsideScopedBookmarksAgent = (1UL << 27), // private option used internally by ScopedBookmarkAgent to prevent recursion between the agent and the framework code. Available 10_7, NA kCFURLBookmarkCreationAllowCreationIfResourceDoesNotExistMask = ( 1UL << 28 ), // allow creation of a bookmark to a file: scheme with a CFURLRef of item which may not exist. If the filesystem item does not exist, the created bookmark contains essentially no properties beyond the url string. Available 10_7, 5_0. kCFURLBookmarkCreationDoNotIncludeSandboxExtensionsMask = ( 1UL << 29 ), // If set, sandbox extensions are not included in created bookmarks. Ordinarily, bookmarks (except those created suitable for putting into a bookmark file) will have a sandbox extension added for the item. Available 10_7, NA. @@ -731,7 +706,7 @@ enum { // private CFURLBookmarkResolutionOptions enum { - kCFBookmarkResolutionPerformRelativeResolutionFirstMask API_AVAILABLE(macos(10.8), ios(6.0), watchos(2.0), tvos(9.0)) = ( 1UL << 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. + kCFBookmarkResolutionPerformRelativeResolutionFirstMask CF_ENUM_AVAILABLE(10_8, 6_0) = ( 1UL << 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. kCFURLBookmarkResolutionAllowingPromisedItem API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = ( 1UL << 12 ), // If kCFURLBookmarkResolutionAllowingPromisedItem is set, resolving a bookmark may return promise item URL if the target has been evicted to the cloud (instead of downloading the evicted document during bookmark resolution). Clients must use NSPromisedItems and NSFileCoordinator API to access promised item URLs. kCFURLBookmarkResolutionAllowingPromisedItem is ignored when resolving security-scoped bookmarks. kCFBookmarkResolutionQuarantineMountedNetworkVolumesMask API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)) = ( 1UL << 13 ), // quarantine any network volume mounted during resolution }; @@ -747,26 +722,25 @@ typedef CF_ENUM(CFIndex, CFURLBookmarkMatchResult) { /* The relativeToURL and matchingPropertyKeys parameters are not used and are ignored */ CF_EXPORT -CFURLBookmarkMatchResult _CFURLBookmarkDataCompare(CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys) API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +CFURLBookmarkMatchResult _CFURLBookmarkDataCompare(CFDataRef bookmark1Ref, CFDataRef bookmark2Ref, CFURLRef relativeToURL, CFArrayRef* matchingPropertyKeys) CF_AVAILABLE(10_7, NA); CF_EXPORT -OSStatus _CFURLBookmarkDataToAliasHandle(CFDataRef bookmarkRef, void* aliasHandleP) API_AVAILABLE(macos(10.7)) API_UNAVAILABLE(ios, watchos, tvos); +OSStatus _CFURLBookmarkDataToAliasHandle(CFDataRef bookmarkRef, void* aliasHandleP) CF_AVAILABLE(10_7, NA); CF_EXPORT -CFURLRef _CFURLCreateByResolvingAliasFile(CFAllocatorRef allocator, CFURLRef url, CFURLBookmarkResolutionOptions options, CFArrayRef propertiesToInclude, CFErrorRef *error ) API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); +CFURLRef _CFURLCreateByResolvingAliasFile(CFAllocatorRef allocator, CFURLRef url, CFURLBookmarkResolutionOptions options, CFArrayRef propertiesToInclude, CFErrorRef *error ) CF_AVAILABLE(10_10, 8_0); /* The following are properties that can be asked of bookmark data objects in addition to the resource properties from CFURL itself. */ -extern const CFStringRef kCFURLBookmarkOriginalPathKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef kCFURLBookmarkOriginalRelativePathKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef kCFURLBookmarkOriginalRelativePathComponentsArrayKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef kCFURLBookmarkOriginalVolumeNameKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef kCFURLBookmarkOriginalVolumeCreationDateKey API_AVAILABLE(macos(10.7), ios(5.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef kCFURLBookmarkFileProviderStringKey API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0)); -extern const CFStringRef _kCFURLBookmarkURLStringKey API_AVAILABLE(macosx(10.13), ios(11.0), watchos(4.0), tvos(11.0)); +extern const CFStringRef kCFURLBookmarkOriginalPathKey CF_AVAILABLE(10_7, 5_0); +extern const CFStringRef kCFURLBookmarkOriginalRelativePathKey CF_AVAILABLE(10_7, 5_0); +extern const CFStringRef kCFURLBookmarkOriginalRelativePathComponentsArrayKey CF_AVAILABLE(10_7, 5_0); +extern const CFStringRef kCFURLBookmarkOriginalVolumeNameKey CF_AVAILABLE(10_7, 5_0); +extern const CFStringRef kCFURLBookmarkOriginalVolumeCreationDateKey CF_AVAILABLE(10_7, 5_0); +extern const CFStringRef kCFURLBookmarkFileProviderStringKey CF_AVAILABLE(10_10, 8_0); #endif CF_EXTERN_C_END diff --git a/Foundation.xcodeproj/project.pbxproj b/Foundation.xcodeproj/project.pbxproj index 2705a69be8..8a006af53a 100644 --- a/Foundation.xcodeproj/project.pbxproj +++ b/Foundation.xcodeproj/project.pbxproj @@ -302,12 +302,6 @@ 5BF7AEBF1BCD51F9008F214A /* NSURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4A1BCC5DCB00ED97BB /* NSURL.swift */; }; 5BF7AEC01BCD51F9008F214A /* NSUUID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4B1BCC5DCB00ED97BB /* NSUUID.swift */; }; 5BF7AEC11BCD51F9008F214A /* NSValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F4C1BCC5DCB00ED97BB /* NSValue.swift */; }; - 5BF9B7F31FABBDB900EE1A7C /* CFPropertyList_Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 5BF9B7F11FABBDB000EE1A7C /* CFPropertyList_Private.h */; }; - 5BF9B7FE1FABD5DA00EE1A7C /* CFBundle_DebugStrings.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F51FABD5D400EE1A7C /* CFBundle_DebugStrings.c */; }; - 5BF9B7FF1FABD5DA00EE1A7C /* CFBundle_Executable.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F81FABD5D500EE1A7C /* CFBundle_Executable.c */; }; - 5BF9B8001FABD5DA00EE1A7C /* CFBundle_Main.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F41FABD5D300EE1A7C /* CFBundle_Main.c */; }; - 5BF9B8011FABD5DA00EE1A7C /* CFBundle_ResourceFork.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F61FABD5D400EE1A7C /* CFBundle_ResourceFork.c */; }; - 5BF9B8021FABD5DA00EE1A7C /* CFBundle_Tables.c in Sources */ = {isa = PBXBuildFile; fileRef = 5BF9B7F71FABD5D400EE1A7C /* CFBundle_Tables.c */; }; 5FE52C951D147D1C00F7D270 /* TestNSTextCheckingResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5FE52C941D147D1C00F7D270 /* TestNSTextCheckingResult.swift */; }; 61E0117D1C1B5590000037DD /* RunLoop.swift in Sources */ = {isa = PBXBuildFile; fileRef = EADE0B761BD15DFF00C49C64 /* RunLoop.swift */; }; 61E0117E1C1B55B9000037DD /* Timer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BDC3F481BCC5DCB00ED97BB /* Timer.swift */; }; @@ -767,12 +761,6 @@ 5BECBA391D1CAE9A00B39B1F /* NSMeasurement.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NSMeasurement.swift; sourceTree = ""; }; 5BECBA3B1D1CAF8800B39B1F /* Unit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unit.swift; sourceTree = ""; }; 5BF7AEC21BCD568D008F214A /* ForSwiftFoundationOnly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ForSwiftFoundationOnly.h; sourceTree = ""; }; - 5BF9B7F11FABBDB000EE1A7C /* CFPropertyList_Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFPropertyList_Private.h; sourceTree = ""; }; - 5BF9B7F41FABD5D300EE1A7C /* CFBundle_Main.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_Main.c; sourceTree = ""; }; - 5BF9B7F51FABD5D400EE1A7C /* CFBundle_DebugStrings.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_DebugStrings.c; sourceTree = ""; }; - 5BF9B7F61FABD5D400EE1A7C /* CFBundle_ResourceFork.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_ResourceFork.c; sourceTree = ""; }; - 5BF9B7F71FABD5D400EE1A7C /* CFBundle_Tables.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_Tables.c; sourceTree = ""; }; - 5BF9B7F81FABD5D500EE1A7C /* CFBundle_Executable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = CFBundle_Executable.c; sourceTree = ""; }; 5E5835F31C20C9B500C81317 /* TestThread.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestThread.swift; sourceTree = ""; }; 5EB6A15C1C188FC40037DCB8 /* TestJSONSerialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestJSONSerialization.swift; sourceTree = ""; }; 5EF673AB1C28B527006212A3 /* TestNotificationQueue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNotificationQueue.swift; sourceTree = ""; }; @@ -1253,11 +1241,6 @@ 5B5D89481BBDA9EE00234F36 /* CFPlugIn.c */, 5B5D89451BBDA9EE00234F36 /* CFPlugIn.h */, 5B5D89461BBDA9EE00234F36 /* CFPlugInCOM.h */, - 5BF9B7F51FABD5D400EE1A7C /* CFBundle_DebugStrings.c */, - 5BF9B7F81FABD5D500EE1A7C /* CFBundle_Executable.c */, - 5BF9B7F41FABD5D300EE1A7C /* CFBundle_Main.c */, - 5BF9B7F61FABD5D400EE1A7C /* CFBundle_ResourceFork.c */, - 5BF9B7F71FABD5D400EE1A7C /* CFBundle_Tables.c */, ); name = PlugIn; path = CoreFoundation/PlugIn.subproj; @@ -1270,7 +1253,6 @@ 5B5D898F1BBDBFB100234F36 /* CFOldStylePList.c */, 5B5D88FB1BBC9B9500234F36 /* CFPropertyList.c */, 5B5D88FA1BBC9B9500234F36 /* CFPropertyList.h */, - 5BF9B7F11FABBDB000EE1A7C /* CFPropertyList_Private.h */, 5B5D89961BBDBFDA00234F36 /* CFXMLInputStream.c */, 5B5D89951BBDBFDA00234F36 /* CFXMLInputStream.h */, 5B5D899A1BBDBFEA00234F36 /* CFXMLNode.c */, @@ -1937,7 +1919,6 @@ 5B7C8AF91BEA81AC00C5B690 /* CFStringEncodingDatabase.h in Headers */, EA66F6361BEED03E00136161 /* TargetConditionals.h in Headers */, 5B7C8B001BEA82ED00C5B690 /* CFRuntime.h in Headers */, - 5BF9B7F31FABBDB900EE1A7C /* CFPropertyList_Private.h in Headers */, 5B7C8ABE1BEA807A00C5B690 /* CFByteOrder.h in Headers */, 5B7C8AF71BEA81AC00C5B690 /* CFStringEncodingConverterExt.h in Headers */, 5B7C8AE31BEA81AC00C5B690 /* CFLogUtilities.h in Headers */, @@ -2311,7 +2292,6 @@ 5B7C8A871BEA7FDB00C5B690 /* CFLocale.c in Sources */, 5BDF62901C1A550800A89075 /* CFRegularExpression.c in Sources */, 5B7C8AB71BEA801700C5B690 /* CFUnicodePrecomposition.c in Sources */, - 5BF9B7FE1FABD5DA00EE1A7C /* CFBundle_DebugStrings.c in Sources */, 5B7C8A721BEA7FCE00C5B690 /* CFBase.c in Sources */, 5B7C8A951BEA7FEC00C5B690 /* CFXMLTree.c in Sources */, 5B7C8AB81BEA802100C5B690 /* CFURLComponents_URIParser.c in Sources */, @@ -2319,7 +2299,6 @@ 5B7C8A791BEA7FCE00C5B690 /* CFUUID.c in Sources */, 5B7C8A7F1BEA7FCE00C5B690 /* CFData.c in Sources */, 5B7C8A9C1BEA7FF900C5B690 /* CFBundle.c in Sources */, - 5BF9B8001FABD5DA00EE1A7C /* CFBundle_Main.c in Sources */, 5B7C8AB51BEA801700C5B690 /* CFUniChar.c in Sources */, 61E011811C1B5998000037DD /* CFMessagePort.c in Sources */, 5B7C8AB61BEA801700C5B690 /* CFUnicodeDecomposition.c in Sources */, @@ -2334,7 +2313,6 @@ 5B7C8A7D1BEA7FCE00C5B690 /* CFBinaryHeap.c in Sources */, 5B7C8A7E1BEA7FCE00C5B690 /* CFBitVector.c in Sources */, 559451EC1F706BFA002807FB /* CFXMLPreferencesDomain.c in Sources */, - 5BF9B8011FABD5DA00EE1A7C /* CFBundle_ResourceFork.c in Sources */, 5B7C8A8F1BEA7FEC00C5B690 /* CFBinaryPList.c in Sources */, 5B7C8A911BEA7FEC00C5B690 /* CFPropertyList.c in Sources */, 5B7C8AB41BEA801700C5B690 /* CFStringEncodingDatabase.c in Sources */, @@ -2366,7 +2344,6 @@ 5B7C8AAB1BEA800D00C5B690 /* CFCharacterSet.c in Sources */, 5B7C8A7A1BEA7FCE00C5B690 /* CFArray.c in Sources */, 5B7C8ABA1BEA802100C5B690 /* CFURL.c in Sources */, - 5BF9B7FF1FABD5DA00EE1A7C /* CFBundle_Executable.c in Sources */, 5B7C8A731BEA7FCE00C5B690 /* CFFileUtilities.c in Sources */, 5B7C8A971BEA7FF900C5B690 /* CFBundle_Grok.c in Sources */, 5B7C8ABB1BEA802100C5B690 /* CFURLAccess.c in Sources */, @@ -2377,7 +2354,6 @@ 5B7C8A7B1BEA7FCE00C5B690 /* CFBag.c in Sources */, 5B7C8AA21BEA800400C5B690 /* CFPreferences.c in Sources */, 5B7C8A811BEA7FCE00C5B690 /* CFSet.c in Sources */, - 5BF9B8021FABD5DA00EE1A7C /* CFBundle_Tables.c in Sources */, 5B7C8A8A1BEA7FDB00C5B690 /* CFLocaleKeys.c in Sources */, 5B7C8A9B1BEA7FF900C5B690 /* CFBundle_Strings.c in Sources */, 5B2B59841C24D01100271109 /* CFConcreteStreams.c in Sources */, @@ -2563,7 +2539,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; @@ -2612,7 +2588,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.12; + MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; @@ -2686,6 +2662,7 @@ PRODUCT_BUNDLE_IDENTIFIER = org.swift.Foundation; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_INDEX_STORE_ENABLE = NO; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -2759,6 +2736,7 @@ PRODUCT_BUNDLE_IDENTIFIER = org.swift.Foundation; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; + SWIFT_INDEX_STORE_ENABLE = NO; SWIFT_INSTALL_OBJC_HEADER = NO; SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; SWIFT_VERSION = 4.0; diff --git a/Foundation/NSLog.swift b/Foundation/NSLog.swift index afa50a4ae8..1ba978dfff 100644 --- a/Foundation/NSLog.swift +++ b/Foundation/NSLog.swift @@ -9,6 +9,17 @@ import CoreFoundation +#if os(OSX) || os(iOS) +internal let kCFLogLevelEmergency = CFLogLevel.emergency +internal let kCFLogLevelAlert = CFLogLevel.alert +internal let kCFLogLevelCritical = CFLogLevel.critical +internal let kCFLogLevelError = CFLogLevel.error +internal let kCFLogLevelWarning = CFLogLevel.warning +internal let kCFLogLevelNotice = CFLogLevel.notice +internal let kCFLogLevelInfo = CFLogLevel.info +internal let kCFLogLevelDebug = CFLogLevel.debug +#endif + /* Output from NSLogv is serialized, in that only one thread in a process can be doing * the writing/logging described above at a time. All attempts at writing/logging a * message complete before the next thread can begin its attempts. The format specification @@ -18,7 +29,11 @@ import CoreFoundation public func NSLogv(_ format: String, _ args: CVaListPointer) { let message = NSString(format: format, arguments: args) - CFLog1(CFLogLevel(kCFLogLevelWarning), message._cfObject) +#if os(OSX) || os(iOS) + CFLog1(kCFLogLevelWarning, message._cfObject) +#else + CFLog1(Int32(kCFLogLevelWarning), message._cfObject) +#endif } public func NSLog(_ format: String, _ args: CVarArg...) { diff --git a/Foundation/PropertyListSerialization.swift b/Foundation/PropertyListSerialization.swift index 02e898d060..6eda2752c4 100644 --- a/Foundation/PropertyListSerialization.swift +++ b/Foundation/PropertyListSerialization.swift @@ -58,8 +58,7 @@ open class PropertyListSerialization : NSObject { #endif let options = CFOptionFlags(opt) let plistObj = _SwiftValue.store(plist) - let d = CFPropertyListCreateData(kCFAllocatorSystemDefault, plistObj, fmt, options, outErr) - return d?.takeRetainedValue() + return CFPropertyListCreateData(kCFAllocatorSystemDefault, plistObj, fmt, options, outErr) } if let res = result { return res._swiftObject diff --git a/Foundation/Stream.swift b/Foundation/Stream.swift index f43d625a4f..410be23867 100644 --- a/Foundation/Stream.swift +++ b/Foundation/Stream.swift @@ -157,7 +157,7 @@ open class InputStream: Stream { } open override var streamError: Error? { - return CFReadStreamCopyError(_stream) + return _CFReadStreamCopyError(_stream) } } @@ -221,7 +221,7 @@ open class OutputStream : Stream { } open override var streamError: Error? { - return CFWriteStreamCopyError(_stream) + return _CFWriteStreamCopyError(_stream) } } diff --git a/build.py b/build.py index dd0ee8cb69..fd66fee63d 100755 --- a/build.py +++ b/build.py @@ -223,7 +223,6 @@ 'CoreFoundation/String.subproj/CFRunArray.h', 'CoreFoundation/Locale.subproj/CFDateFormatter_Private.h', 'CoreFoundation/Locale.subproj/CFLocale_Private.h', - 'CoreFoundation/Parsing.subproj/CFPropertyList_Private.h', ], project = [ ]) @@ -277,10 +276,6 @@ 'CoreFoundation/PlugIn.subproj/CFBundle_Locale.c', 'CoreFoundation/PlugIn.subproj/CFBundle_Resources.c', 'CoreFoundation/PlugIn.subproj/CFBundle_Strings.c', - 'CoreFoundation/PlugIn.subproj/CFBundle_Main.c', - 'CoreFoundation/PlugIn.subproj/CFBundle_ResourceFork.c', - 'CoreFoundation/PlugIn.subproj/CFBundle_Executable.c', - 'CoreFoundation/PlugIn.subproj/CFBundle_DebugStrings.c', 'CoreFoundation/PlugIn.subproj/CFPlugIn.c', 'CoreFoundation/PlugIn.subproj/CFPlugIn_Factory.c', 'CoreFoundation/PlugIn.subproj/CFPlugIn_Instance.c',