]> git.saurik.com Git - apple/cf.git/blob - CFInternal.h
CF-635.15.tar.gz
[apple/cf.git] / CFInternal.h
1 /*
2 * Copyright (c) 2011 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 /* CFInternal.h
25 Copyright (c) 1998-2011, Apple Inc. All rights reserved.
26 */
27
28 /*
29 NOT TO BE USED OUTSIDE CF!
30 */
31
32 #if !CF_BUILDING_CF
33 #error The header file CFInternal.h is for the exclusive use of CoreFoundation. No other project should include it.
34 #endif
35
36 #if !defined(__COREFOUNDATION_CFINTERNAL__)
37 #define __COREFOUNDATION_CFINTERNAL__ 1
38
39 #define __CF_COMPILE_YEAR__ (__DATE__[7] * 1000 + __DATE__[8] * 100 + __DATE__[9] * 10 + __DATE__[10] - 53328)
40 #define __CF_COMPILE_MONTH__ ((__DATE__[1] + __DATE__[2] == 207) ? 1 : \
41 (__DATE__[1] + __DATE__[2] == 199) ? 2 : \
42 (__DATE__[1] + __DATE__[2] == 211) ? 3 : \
43 (__DATE__[1] + __DATE__[2] == 226) ? 4 : \
44 (__DATE__[1] + __DATE__[2] == 218) ? 5 : \
45 (__DATE__[1] + __DATE__[2] == 227) ? 6 : \
46 (__DATE__[1] + __DATE__[2] == 225) ? 7 : \
47 (__DATE__[1] + __DATE__[2] == 220) ? 8 : \
48 (__DATE__[1] + __DATE__[2] == 213) ? 9 : \
49 (__DATE__[1] + __DATE__[2] == 215) ? 10 : \
50 (__DATE__[1] + __DATE__[2] == 229) ? 11 : \
51 (__DATE__[1] + __DATE__[2] == 200) ? 12 : 0)
52 #define __CF_COMPILE_DAY__ (__DATE__[4] * 10 + __DATE__[5] - (__DATE__[4] == ' ' ? 368 : 528))
53 #define __CF_COMPILE_DATE__ (__CF_COMPILE_YEAR__ * 10000 + __CF_COMPILE_MONTH__ * 100 + __CF_COMPILE_DAY__)
54
55 #define __CF_COMPILE_HOUR__ (__TIME__[0] * 10 + __TIME__[1] - 528)
56 #define __CF_COMPILE_MINUTE__ (__TIME__[3] * 10 + __TIME__[4] - 528)
57 #define __CF_COMPILE_SECOND__ (__TIME__[6] * 10 + __TIME__[7] - 528)
58 #define __CF_COMPILE_TIME__ (__CF_COMPILE_HOUR__ * 10000 + __CF_COMPILE_MINUTE__ * 100 + __CF_COMPILE_SECOND__)
59
60 #define __CF_COMPILE_SECOND_OF_DAY__ (__CF_COMPILE_HOUR__ * 3600 + __CF_COMPILE_MINUTE__ * 60 + __CF_COMPILE_SECOND__)
61
62 // __CF_COMPILE_DAY_OF_EPOCH__ works within Gregorian years 2001 - 2099; the epoch is of course CF's epoch
63 #define __CF_COMPILE_DAY_OF_EPOCH__ ((__CF_COMPILE_YEAR__ - 2001) * 365 + (__CF_COMPILE_YEAR__ - 2001) / 4 \
64 + ((__DATE__[1] + __DATE__[2] == 207) ? 0 : \
65 (__DATE__[1] + __DATE__[2] == 199) ? 31 : \
66 (__DATE__[1] + __DATE__[2] == 211) ? 59 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
67 (__DATE__[1] + __DATE__[2] == 226) ? 90 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
68 (__DATE__[1] + __DATE__[2] == 218) ? 120 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
69 (__DATE__[1] + __DATE__[2] == 227) ? 151 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
70 (__DATE__[1] + __DATE__[2] == 225) ? 181 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
71 (__DATE__[1] + __DATE__[2] == 220) ? 212 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
72 (__DATE__[1] + __DATE__[2] == 213) ? 243 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
73 (__DATE__[1] + __DATE__[2] == 215) ? 273 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
74 (__DATE__[1] + __DATE__[2] == 229) ? 304 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
75 (__DATE__[1] + __DATE__[2] == 200) ? 334 + (__CF_COMPILE_YEAR__ % 4 == 0) : \
76 365 + (__CF_COMPILE_YEAR__ % 4 == 0)) \
77 + __CF_COMPILE_DAY__)
78
79
80 CF_EXTERN_C_BEGIN
81
82 #include <CoreFoundation/CFBase.h>
83 #include <CoreFoundation/CFURL.h>
84 #include <CoreFoundation/CFString.h>
85 #include <CoreFoundation/CFDate.h>
86 #include <CoreFoundation/CFArray.h>
87 #include <CoreFoundation/CFLogUtilities.h>
88 #include <CoreFoundation/CFRuntime.h>
89 #include <limits.h>
90 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
91 #include <xlocale.h>
92 #include <unistd.h>
93 #endif
94 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
95 #include <sys/time.h>
96 #include <pthread.h>
97 #include <signal.h>
98 #endif
99 #if DEPLOYMENT_TARGET_WINDOWS
100 #include <pthread.h>
101 #endif
102
103
104 #if defined(__BIG_ENDIAN__)
105 #define __CF_BIG_ENDIAN__ 1
106 #define __CF_LITTLE_ENDIAN__ 0
107 #endif
108
109 #if defined(__LITTLE_ENDIAN__)
110 #define __CF_LITTLE_ENDIAN__ 1
111 #define __CF_BIG_ENDIAN__ 0
112 #endif
113
114
115 #include <CoreFoundation/ForFoundationOnly.h>
116
117 CF_EXPORT const char *_CFProcessName(void);
118 CF_EXPORT CFStringRef _CFProcessNameString(void);
119
120 CF_EXPORT Boolean _CFGetCurrentDirectory(char *path, int maxlen);
121
122 CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void);
123
124 CF_EXPORT CFStringRef _CFStringCreateHostName(void);
125
126 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
127 #include <CoreFoundation/CFRunLoop.h>
128 CF_EXPORT void _CFMachPortInstallNotifyPort(CFRunLoopRef rl, CFStringRef mode);
129 #endif
130
131 __private_extern__ CFIndex __CFActiveProcessorCount();
132
133 #if defined(__ppc__)
134 #define HALT do {asm __volatile__("trap"); kill(getpid(), 9); } while (0)
135 #elif defined(__i386__) || defined(__x86_64__)
136 #if defined(__GNUC__)
137 #define HALT do {asm __volatile__("int3"); kill(getpid(), 9); } while (0)
138 #elif defined(_MSC_VER)
139 #define HALT do { DebugBreak(); abort(); } while (0)
140 #else
141 #error Compiler not supported
142 #endif
143 #endif
144 #if defined(__arm__)
145 #define HALT do {asm __volatile__("bkpt 0xCF"); kill(getpid(), 9); } while (0)
146 #endif
147
148 #if defined(DEBUG)
149 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \
150 do { \
151 if (!(cond)) { \
152 CFLog(prio, CFSTR(desc), a1, a2, a3, a4, a5); \
153 /* HALT; */ \
154 } \
155 } while (0)
156 #else
157 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \
158 do {} while (0)
159 #endif
160
161 #define CFAssert(condition, priority, description) \
162 __CFAssert((condition), (priority), description, 0, 0, 0, 0, 0)
163 #define CFAssert1(condition, priority, description, a1) \
164 __CFAssert((condition), (priority), description, (a1), 0, 0, 0, 0)
165 #define CFAssert2(condition, priority, description, a1, a2) \
166 __CFAssert((condition), (priority), description, (a1), (a2), 0, 0, 0)
167 #define CFAssert3(condition, priority, description, a1, a2, a3) \
168 __CFAssert((condition), (priority), description, (a1), (a2), (a3), 0, 0)
169 #define CFAssert4(condition, priority, description, a1, a2, a3, a4) \
170 __CFAssert((condition), (priority), description, (a1), (a2), (a3), (a4), 0)
171
172 #define __kCFLogAssertion 3
173
174 // This CF-only log function uses no CF functionality, so it may be called anywhere within CF - including thread teardown or prior to full CF setup
175 __private_extern__ void _CFLogSimple(int32_t lev, char *format, ...);
176
177 #if defined(DEBUG)
178 extern void __CFGenericValidateType_(CFTypeRef cf, CFTypeID type, const char *func);
179 #define __CFGenericValidateType(cf, type) __CFGenericValidateType_(cf, type, __PRETTY_FUNCTION__)
180 #else
181 #define __CFGenericValidateType(cf, type) ((void)0)
182 #endif
183
184 #define CF_INFO_BITS (!!(__CF_BIG_ENDIAN__) * 3)
185 #define CF_RC_BITS (!!(__CF_LITTLE_ENDIAN__) * 3)
186
187 /* Bit manipulation macros */
188 /* Bits are numbered from 31 on left to 0 on right */
189 /* 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. */
190 /* In the following, N1 and N2 specify an inclusive range N2..N1 with N1 >= N2 */
191 #define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1))
192 #define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2))
193 #define __CFBitfieldSetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfieldMask(N1, N2)) | (((X) << (N2)) & __CFBitfieldMask(N1, N2)))
194 #define __CFBitfieldMaxValue(N1, N2) __CFBitfieldGetValue(0xFFFFFFFFUL, (N1), (N2))
195
196 #define __CFBitIsSet(V, N) (((V) & (1UL << (N))) != 0)
197 #define __CFBitSet(V, N) ((V) |= (1UL << (N)))
198 #define __CFBitClear(V, N) ((V) &= ~(1UL << (N)))
199
200 // Foundation uses 20-40
201 // Foundation knows about the value of __CFTSDKeyAutoreleaseData1
202 enum {
203 __CFTSDKeyAllocator = 1,
204 __CFTSDKeyIsInCFLog = 2,
205 __CFTSDKeyIsInNSCache = 3,
206 __CFTSDKeyIsInGCDMainQ = 4,
207 __CFTSDKeyICUConverter = 7,
208 __CFTSDKeyCollatorLocale = 8,
209 __CFTSDKeyCollatorUCollator = 9,
210 __CFTSDKeyRunLoop = 10,
211 __CFTSDKeyRunLoopCntr = 11,
212 // autorelease pool stuff must be higher than run loop constants
213 __CFTSDKeyAutoreleaseData2 = 61,
214 __CFTSDKeyAutoreleaseData1 = 62,
215 __CFTSDKeyExceptionData = 63,
216 };
217
218 #define __kCFAllocatorTypeID_CONST 2
219
220 CF_INLINE CFAllocatorRef __CFGetDefaultAllocator(void) {
221 CFAllocatorRef allocator = (CFAllocatorRef)_CFGetTSD(__CFTSDKeyAllocator);
222 if (NULL == allocator) {
223 allocator = kCFAllocatorSystemDefault;
224 }
225 return allocator;
226 }
227
228
229 #if !defined(LLONG_MAX)
230 #if defined(_I64_MAX)
231 #define LLONG_MAX _I64_MAX
232 #else
233 #warning Arbitrarily defining LLONG_MAX
234 #define LLONG_MAX (int64_t)9223372036854775807
235 #endif
236 #endif /* !defined(LLONG_MAX) */
237
238 #if !defined(LLONG_MIN)
239 #if defined(_I64_MIN)
240 #define LLONG_MIN _I64_MIN
241 #else
242 #warning Arbitrarily defining LLONG_MIN
243 #define LLONG_MIN (-LLONG_MAX - (int64_t)1)
244 #endif
245 #endif /* !defined(LLONG_MIN) */
246
247 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
248 #define __CFMin(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
249 #define __CFMax(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
250 #else /* __GNUC__ */
251 #define __CFMin(A,B) ((A) < (B) ? (A) : (B))
252 #define __CFMax(A,B) ((A) > (B) ? (A) : (B))
253 #endif /* __GNUC__ */
254
255 /* Secret CFAllocator hint bits */
256 #define __kCFAllocatorTempMemory 0x2
257 #define __kCFAllocatorNoPointers 0x10
258 #define __kCFAllocatorDoNotRecordEvent 0x100
259 #define __kCFAllocatorGCScannedMemory 0x200 /* GC: memory should be scanned. */
260 #define __kCFAllocatorGCObjectMemory 0x400 /* GC: memory needs to be finalized. */
261
262 CF_INLINE auto_memory_type_t CF_GET_GC_MEMORY_TYPE(CFOptionFlags flags) {
263 auto_memory_type_t type = (flags & __kCFAllocatorGCScannedMemory ? 0 : AUTO_UNSCANNED) | (flags & __kCFAllocatorGCObjectMemory ? AUTO_OBJECT : 0);
264 return type;
265 }
266
267 CF_INLINE void __CFAssignWithWriteBarrier(void **location, void *value) {
268 if (kCFUseCollectableAllocator) {
269 objc_assign_strongCast((id)value, (id *)location);
270 } else {
271 *location = value;
272 }
273 }
274
275 // Zero-retain count CFAllocator functions, i.e. memory that will be collected, no dealloc necessary
276 CF_EXPORT void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint);
277 CF_EXPORT void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint);
278 CF_EXPORT void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr);
279
280 CF_EXPORT CFAllocatorRef _CFTemporaryMemoryAllocator(void);
281
282 extern SInt64 __CFTimeIntervalToTSR(CFTimeInterval ti);
283 extern CFTimeInterval __CFTSRToTimeInterval(SInt64 tsr);
284
285 extern CFStringRef __CFCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions);
286
287
288 /* result is long long or int, depending on doLonglong
289 */
290 extern Boolean __CFStringScanInteger(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, Boolean doLonglong, void *result);
291 extern Boolean __CFStringScanDouble(CFStringInlineBuffer *buf, CFTypeRef locale, SInt32 *indexPtr, double *resultPtr);
292 extern Boolean __CFStringScanHex(CFStringInlineBuffer *buf, SInt32 *indexPtr, unsigned *result);
293
294 extern const char *__CFgetenv(const char *n);
295
296 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
297 #define STACK_BUFFER_DECL(T, N, C) T N[C]
298 #elif DEPLOYMENT_TARGET_WINDOWS
299 #define STACK_BUFFER_DECL(T, N, C) T *N = (T *)_alloca((C) * sizeof(T))
300 #else
301 #error Unknown or unspecified DEPLOYMENT_TARGET
302 #endif
303
304
305 CF_EXPORT void * __CFConstantStringClassReferencePtr;
306
307 #ifdef __CONSTANT_CFSTRINGS__
308
309 #define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
310 #define PE_CONST_STRING_DECL(S, V) __private_extern__ const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
311
312 #else
313
314 struct CF_CONST_STRING {
315 CFRuntimeBase _base;
316 uint8_t *_ptr;
317 uint32_t _length;
318 };
319
320 CF_EXPORT int __CFConstantStringClassReference[];
321
322 /* 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 */
323
324 #if __CF_BIG_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
325 #define CONST_STRING_DECL(S, V) \
326 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
327 const CFStringRef S = (CFStringRef) & __ ## S ## __;
328 #define PE_CONST_STRING_DECL(S, V) \
329 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
330 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
331 #elif __CF_LITTLE_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
332 #define CONST_STRING_DECL(S, V) \
333 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)V, sizeof(V) - 1}; \
334 const CFStringRef S = (CFStringRef) & __ ## S ## __;
335 #define PE_CONST_STRING_DECL(S, V) \
336 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)V, sizeof(V) - 1}; \
337 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
338 #elif DEPLOYMENT_TARGET_WINDOWS
339 #define CONST_STRING_DECL(S, V) \
340 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
341 const CFStringRef S = (CFStringRef) & __ ## S ## __;
342 #define PE_CONST_STRING_DECL(S, V) \
343 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
344 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
345 #endif // __BIG_ENDIAN__
346 #endif // __CONSTANT_CFSTRINGS__
347
348
349 /* Buffer size for file pathname */
350 #if DEPLOYMENT_TARGET_WINDOWS
351 #define CFMaxPathSize ((CFIndex)262)
352 #define CFMaxPathLength ((CFIndex)260)
353 #else
354 #define CFMaxPathSize ((CFIndex)1026)
355 #define CFMaxPathLength ((CFIndex)1024)
356 #endif
357
358 CF_EXPORT bool __CFOASafe;
359 CF_EXPORT void __CFSetLastAllocationEventName(void *ptr, const char *classname);
360
361
362
363 /* Comparators are passed the address of the values; this is somewhat different than CFComparatorFunction is used in public API usually. */
364 CF_EXPORT CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context);
365
366 CF_EXPORT CFHashCode CFHashBytes(UInt8 *bytes, CFIndex length);
367
368 CF_EXPORT CFStringEncoding CFStringFileSystemEncoding(void);
369
370 __private_extern__ CFStringRef __CFStringCreateImmutableFunnel3(CFAllocatorRef alloc, const void *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean possiblyExternalFormat, Boolean tryToReduceUnicode, Boolean hasLengthByte, Boolean hasNullByte, Boolean noCopy, CFAllocatorRef contentsDeallocator, UInt32 converterFlags);
371
372 extern const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr);
373 extern const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr);
374 extern void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr);
375
376 extern CFTypeRef CFMakeUncollectable(CFTypeRef cf);
377
378 __private_extern__ void _CFRaiseMemoryException(CFStringRef reason);
379
380 __private_extern__ Boolean __CFProphylacticAutofsAccess;
381
382
383 #if DEPLOYMENT_TARGET_MACOSX
384
385 typedef OSSpinLock CFSpinLock_t;
386
387 #define CFSpinLockInit OS_SPINLOCK_INIT
388 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
389
390 #define __CFSpinLock(LP) ({ \
391 OSSpinLock *__lockp__ = (LP); \
392 OSSpinLock __lockv__ = *__lockp__; \
393 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
394 CFLog(3, CFSTR("In '%s', file %s, line %d, during lock, spin lock %p has value 0x%x, which is neither locked nor unlocked. The memory has been smashed."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \
395 /* HALT; */ \
396 } \
397 OSSpinLockLock(__lockp__); })
398
399 #define __CFSpinUnlock(LP) ({ \
400 OSSpinLock *__lockp__ = (LP); \
401 OSSpinLock __lockv__ = *__lockp__; \
402 if (~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
403 CFLog(3, CFSTR("In '%s', file %s, line %d, during unlock, spin lock %p has value 0x%x, which is not locked. The memory has been smashed or the lock is being unlocked when not locked."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \
404 /* HALT; */ \
405 } \
406 OSSpinLockUnlock(__lockp__); })
407
408 #define __CFSpinLockTry(LP) ({ \
409 OSSpinLock *__lockp__ = (LP); \
410 OSSpinLock __lockv__ = *__lockp__; \
411 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
412 CFLog(3, CFSTR("In '%s', file %s, line %d, during lock, spin lock %p has value 0x%x, which is neither locked nor unlocked. The memory has been smashed."), __PRETTY_FUNCTION__, __FILE__, __LINE__, __lockp__, __lockv__); \
413 /* HALT; */ \
414 } \
415 OSSpinLockTry(__lockp__); })
416
417 #elif DEPLOYMENT_TARGET_EMBEDDED
418
419 typedef OSSpinLock CFSpinLock_t;
420
421 #define CFSpinLockInit OS_SPINLOCK_INIT
422 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
423
424 #define __CFSpinLock(LP) ({ \
425 OSSpinLock *__lockp__ = (LP); \
426 OSSpinLockLock(__lockp__); })
427
428 #define __CFSpinUnlock(LP) ({ \
429 OSSpinLock *__lockp__ = (LP); \
430 OSSpinLockUnlock(__lockp__); })
431
432 #define __CFSpinLockTry(LP) ({ \
433 OSSpinLock *__lockp__ = (LP); \
434 OSSpinLockTry(__lockp__); })
435
436 #elif DEPLOYMENT_TARGET_WINDOWS
437
438 typedef int32_t CFSpinLock_t;
439 #define CFSpinLockInit 0
440 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
441
442 CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) {
443 while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
444 Sleep(0);
445 }
446 }
447
448 CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) {
449 MemoryBarrier();
450 *lock = 0;
451 }
452
453 CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
454 return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
455 }
456
457 #elif DEPLOYMENT_TARGET_LINUX
458
459 typedef int32_t CFSpinLock_t;
460 #define CFSpinLockInit 0
461 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
462
463 CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) {
464 while (__sync_val_compare_and_swap(lock, ~0, 0) != 0) {
465 sleep(0);
466 }
467 }
468
469 CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) {
470 __sync_synchronize();
471 *lock = 0;
472 }
473
474 CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
475 return (__sync_val_compare_and_swap(lock, ~0, 0) == 0);
476 }
477
478 #else
479
480 #warning CF spin locks not defined for this platform -- CF is not thread-safe
481 #define __CFSpinLock(A) do {} while (0)
482 #define __CFSpinUnlock(A) do {} while (0)
483
484 #endif
485
486
487 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
488 extern uint8_t __CF120293;
489 extern uint8_t __CF120290;
490 extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void);
491 #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)
492 #define CHECK_FOR_FORK_RET(...) do { CHECK_FOR_FORK(); if (__CF120293) return __VA_ARGS__; } while (0)
493 #define HAS_FORKED() (__CF120293)
494 #endif
495
496 #if !defined(CHECK_FOR_FORK)
497 #define CHECK_FOR_FORK() do { } while (0)
498 #endif
499
500 #if !defined(CHECK_FOR_FORK_RET)
501 #define CHECK_FOR_FORK_RET(...) do { } while (0)
502 #endif
503
504 #if !defined(HAS_FORKED)
505 #define HAS_FORKED() 0
506 #endif
507
508 #if DEPLOYMENT_TARGET_WINDOWS
509 #include <errno.h>
510 #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
511 #include <sys/errno.h>
512 #endif
513
514 #define thread_errno() errno
515 #define thread_set_errno(V) do {errno = (V);} while (0)
516
517 extern void *__CFStartSimpleThread(void *func, void *arg);
518
519 /* ==================== Simple file access ==================== */
520 /* For dealing with abstract types. MF:!!! These ought to be somewhere else and public. */
521
522 CF_EXPORT CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType);
523
524 /* ==================== Simple file access ==================== */
525 /* These functions all act on a c-strings which must be in the file system encoding. */
526
527 CF_EXPORT Boolean _CFCreateDirectory(const char *path);
528 #if DEPLOYMENT_TARGET_WINDOWS
529 CF_EXPORT Boolean _CFCreateDirectoryWide(const wchar_t *path);
530 #endif
531 CF_EXPORT Boolean _CFRemoveDirectory(const char *path);
532 CF_EXPORT Boolean _CFDeleteFile(const char *path);
533
534 CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength);
535 /* resulting bytes are allocated from alloc which MUST be non-NULL. */
536 /* maxLength of zero means the whole file. Otherwise it sets a limit on the number of bytes read. */
537
538 CF_EXPORT Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length);
539 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
540 CF_EXPORT Boolean _CFWriteBytesToFileWithAtomicity(CFURLRef url, const void *bytes, unsigned int length, SInt32 mode, Boolean atomic);
541 #endif
542
543 CF_EXPORT CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType);
544 /* On Mac OS 8/9, one of dirSpec, dirPath and dirURL must be non-NULL */
545 /* On all other platforms, one of path and dirURL must be non-NULL */
546 /* If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */
547 /* alloc may be NULL */
548 /* return value is CFArray of CFURLs */
549
550 CF_EXPORT SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
551 /* alloc may be NULL */
552 /* 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. */
553
554 CF_EXPORT SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
555 /* alloc may be NULL */
556 /* 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. */
557
558
559 /* ==================== Simple path manipulation ==================== */
560 /* These functions all act on a UniChar buffers. */
561
562 CF_EXPORT Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length);
563 CF_EXPORT Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length);
564 __private_extern__ Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex *length, CFIndex maxLength);
565 CF_EXPORT Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength);
566 CF_EXPORT Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength);
567 CF_EXPORT Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash);
568 CF_EXPORT CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length);
569 CF_EXPORT CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length);
570 CF_EXPORT CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length);
571 CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length);
572
573 #define __CFMaxRuntimeTypes 65535
574
575 // Tagged pointer support
576 // Low-bit set means tagged object, next 3 bits (currently)
577 // define the tagged object class, next 4 bits are for type
578 // information for the specific tagged object class. Thus,
579 // the low byte is for type info, and the rest of a pointer
580 // (32 or 64-bit) is for payload, whatever the tagged class.
581 //
582 // Note that the specific integers used to identify the
583 // specific tagged classes can and will change from release
584 // to release (that's why this stuff is in CF*Internal*.h),
585 // as can the definition of type info vs payload above.
586 //
587 #if defined(__x86_64__)
588 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
589 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
590 #else
591 #define CF_IS_TAGGED_OBJ(PTR) 0
592 #define CF_TAGGED_OBJ_TYPE(PTR) 0
593 #endif
594
595 enum {
596 kCFTaggedObjectID_Invalid = 0,
597 kCFTaggedObjectID_Undefined0 = (0 << 1) + 1,
598 kCFTaggedObjectID_Integer = (1 << 1) + 1,
599 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
600 kCFTaggedObjectID_Undefined3 = (3 << 1) + 1,
601 kCFTaggedObjectID_Undefined4 = (4 << 1) + 1,
602 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
603 kCFTaggedObjectID_Date = (6 << 1) + 1,
604 kCFTaggedObjectID_DateTS = (7 << 1) + 1,
605 };
606
607
608 #define __CFRuntimeClassTableSize 1024
609
610 extern uintptr_t __CFRuntimeObjCClassTable[];
611 CF_INLINE uintptr_t __CFISAForTypeID(CFTypeID typeID) {
612 return (typeID < __CFRuntimeClassTableSize) ? __CFRuntimeObjCClassTable[typeID] : 0;
613 }
614
615 CF_INLINE Boolean CF_IS_OBJC(CFTypeID typeID, const void *obj) {
616 if (CF_IS_TAGGED_OBJ(obj)) return true;
617 uintptr_t cfisa = ((CFRuntimeBase *)obj)->_cfisa;
618 if (cfisa == 0) return false;
619 #if 0
620 // Temporarily disabled
621 #if __LP64__
622 if (cfisa < 0x10000000UL) {
623 CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
624 return false;
625 }
626 #else
627 if (cfisa < 0x1000UL) {
628 CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
629 return false;
630 }
631 #endif
632 #endif
633 if (cfisa == (uintptr_t)__CFConstantStringClassReferencePtr) return false;
634 uintptr_t type_isa = (uintptr_t)(typeID < __CFRuntimeClassTableSize ? __CFRuntimeObjCClassTable[typeID] : 0);
635 if (cfisa == type_isa) return false;
636 return true;
637 }
638
639 #define STUB_CF_OBJC 1
640
641 #if STUB_CF_OBJC
642
643 #define CF_IS_OBJC(typeID, obj) (false)
644
645 #define CF_OBJC_VOIDCALL0(obj, sel) do { } while (0)
646 #define CF_OBJC_VOIDCALL1(obj, sel, a1) do { } while (0)
647 #define CF_OBJC_VOIDCALL2(obj, sel, a1, a2) do { } while (0)
648
649 #define CF_OBJC_CALL0(rettype, retvar, obj, sel) do { } while (0)
650 #define CF_OBJC_CALL1(rettype, retvar, obj, sel, a1) do { } while (0)
651 #define CF_OBJC_CALL2(rettype, retvar, obj, sel, a1, a2) do { } while (0)
652
653 #define CF_OBJC_FUNCDISPATCH0(typeID, rettype, obj, sel) do { } while (0)
654 #define CF_OBJC_FUNCDISPATCH1(typeID, rettype, obj, sel, a1) do { } while (0)
655 #define CF_OBJC_FUNCDISPATCH2(typeID, rettype, obj, sel, a1, a2) do { } while (0)
656 #define CF_OBJC_FUNCDISPATCH3(typeID, rettype, obj, sel, a1, a2, a3) do { } while (0)
657 #define CF_OBJC_FUNCDISPATCH4(typeID, rettype, obj, sel, a1, a2, a3, a4) do { } while (0)
658 #define CF_OBJC_FUNCDISPATCH5(typeID, rettype, obj, sel, a1, a2, a3, a4, a5) do { } while (0)
659
660 #endif // STUB_CF_OBJC
661
662
663 /* See comments in CFBase.c
664 */
665 #if SUPPORT_CFM
666 extern void __CF_FAULT_CALLBACK(void **ptr);
667 extern void *__CF_INVOKE_CALLBACK(void *, ...);
668 #define FAULT_CALLBACK(V) __CF_FAULT_CALLBACK(V)
669 #define INVOKE_CALLBACK1(P, A) (__CF_INVOKE_CALLBACK(P, A))
670 #define INVOKE_CALLBACK2(P, A, B) (__CF_INVOKE_CALLBACK(P, A, B))
671 #define INVOKE_CALLBACK3(P, A, B, C) (__CF_INVOKE_CALLBACK(P, A, B, C))
672 #define INVOKE_CALLBACK4(P, A, B, C, D) (__CF_INVOKE_CALLBACK(P, A, B, C, D))
673 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (__CF_INVOKE_CALLBACK(P, A, B, C, D, E))
674 #define UNFAULT_CALLBACK(V) do { V = (void *)((uintptr_t)V & ~0x3); } while (0)
675 #else
676 #define FAULT_CALLBACK(V)
677 #define INVOKE_CALLBACK1(P, A) (P)(A)
678 #define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
679 #define INVOKE_CALLBACK3(P, A, B, C) (P)(A, B, C)
680 #define INVOKE_CALLBACK4(P, A, B, C, D) (P)(A, B, C, D)
681 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (P)(A, B, C, D, E)
682 #define UNFAULT_CALLBACK(V) do { } while (0)
683 #endif
684
685 /* For the support of functionality which needs CarbonCore or other frameworks */
686 // These macros define an upcall or weak "symbol-lookup" wrapper function.
687 // The parameters are:
688 // R : the return type of the function
689 // N : the name of the function (in the other library)
690 // P : the parenthesized parameter list of the function
691 // A : the parenthesized actual argument list to be passed
692 // FAILACTION: (only for the _FAIL macros) additional code to be
693 // run when the function cannot be found.
694 // opt: a fifth optional argument can be passed in which is the
695 // return value of the wrapper when the function cannot be
696 // found; should be of type R, & can be a function call
697 // The name of the resulting wrapper function is:
698 // __CFCarbonCore_N (where N is the second parameter)
699 // __CFNetwork_N (where N is the second parameter)
700 //
701 // Example:
702 // DEFINE_WEAK_CARBONCORE_FUNC(void, DisposeHandle, (Handle h), (h))
703 //
704
705 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
706
707 extern void *__CFLookupCFNetworkFunction(const char *name);
708
709 #define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...) \
710 typedef R (*dyfuncptr)P; \
711 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \
712 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \
713 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \
714 if (dyfunc) { return dyfunc A ; } \
715 return __VA_ARGS__ ; \
716 }
717
718 #define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, FAILACTION, ...) \
719 static R __CFNetwork_ ## N P { \
720 typedef R (*dyfuncptr)P; \
721 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \
722 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \
723 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \
724 if (dyfunc) { return dyfunc A ; } \
725 FAILACTION ; \
726 return __VA_ARGS__ ; \
727 }
728
729 #else
730
731 #define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...)
732 #define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, ...)
733
734 #endif
735
736
737 #if !defined(DEFINE_WEAK_CARBONCORE_FUNC)
738 #define DEFINE_WEAK_CARBONCORE_FUNC(R, N, P, A, ...)
739 #endif
740 #if !defined(DEFINE_WEAK_CORESERVICESINTERNAL_FUNC)
741 #define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...)
742 #endif
743
744 __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale);
745
746
747 __private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops);
748
749
750 // This should only be used in CF types, not toll-free bridged objects!
751 // It should not be used with CFAllocator arguments!
752 // Use CFGetAllocator() in the general case, and this inline function in a few limited (but often called) situations.
753 CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) { // !!! Use with CF types only, and NOT WITH CFAllocator!
754 if (CF_IS_TAGGED_OBJ(cf)) {
755 return kCFAllocatorSystemDefault;
756 }
757 if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7), 1)) {
758 return kCFAllocatorSystemDefault;
759 }
760 return *(CFAllocatorRef *)((char *)cf - sizeof(CFAllocatorRef));
761 }
762
763
764 #if DEPLOYMENT_TARGET_WINDOWS
765 __private_extern__ const wchar_t *_CFDLLPath(void);
766 __private_extern__ void __CFStringCleanup(void);
767 __private_extern__ void __CFSocketCleanup(void);
768 __private_extern__ void __CFUniCharCleanup(void);
769 __private_extern__ void __CFStreamCleanup(void);
770 #endif
771
772 /* !!! Avoid #importing objc.h; e.g. converting this to a .m file */
773 struct __objcFastEnumerationStateEquivalent {
774 unsigned long state;
775 unsigned long *itemsPtr;
776 unsigned long *mutationsPtr;
777 unsigned long extra[5];
778 };
779
780 CF_EXTERN_C_END
781
782 #endif /* ! __COREFOUNDATION_CFINTERNAL__ */
783