]> git.saurik.com Git - apple/cf.git/blob - CFInternal.h
c573ea810ad59d7864b828f5650c809aa003729f
[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 CFTypeRef _CFTryRetain(CFTypeRef cf);
306 CF_EXPORT Boolean _CFIsDeallocating(CFTypeRef cf);
307
308
309 CF_EXPORT void * __CFConstantStringClassReferencePtr;
310
311 #ifdef __CONSTANT_CFSTRINGS__
312
313 #define CONST_STRING_DECL(S, V) const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
314 #define PE_CONST_STRING_DECL(S, V) __private_extern__ const CFStringRef S = (const CFStringRef)__builtin___CFStringMakeConstantString(V);
315
316 #else
317
318 struct CF_CONST_STRING {
319 CFRuntimeBase _base;
320 uint8_t *_ptr;
321 uint32_t _length;
322 };
323
324 CF_EXPORT int __CFConstantStringClassReference[];
325
326 /* 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 */
327
328 #if __CF_BIG_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
329 #define CONST_STRING_DECL(S, V) \
330 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
331 const CFStringRef S = (CFStringRef) & __ ## S ## __;
332 #define PE_CONST_STRING_DECL(S, V) \
333 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0x00, 0x00, 0x07, 0xc8}}, (uint8_t *)V, sizeof(V) - 1}; \
334 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
335 #elif __CF_LITTLE_ENDIAN__ && (DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX)
336 #define CONST_STRING_DECL(S, V) \
337 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)V, sizeof(V) - 1}; \
338 const CFStringRef S = (CFStringRef) & __ ## S ## __;
339 #define PE_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 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
342 #elif DEPLOYMENT_TARGET_WINDOWS
343 #define CONST_STRING_DECL(S, V) \
344 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
345 const CFStringRef S = (CFStringRef) & __ ## S ## __;
346 #define PE_CONST_STRING_DECL(S, V) \
347 static struct CF_CONST_STRING __ ## S ## __ = {{(uintptr_t)&__CFConstantStringClassReference, {0xc8, 0x07, 0x00, 0x00}}, (uint8_t *)(V), sizeof(V) - 1}; \
348 __private_extern__ const CFStringRef S = (CFStringRef) & __ ## S ## __;
349 #endif // __BIG_ENDIAN__
350 #endif // __CONSTANT_CFSTRINGS__
351
352
353 /* Buffer size for file pathname */
354 #if DEPLOYMENT_TARGET_WINDOWS
355 #define CFMaxPathSize ((CFIndex)262)
356 #define CFMaxPathLength ((CFIndex)260)
357 #else
358 #define CFMaxPathSize ((CFIndex)1026)
359 #define CFMaxPathLength ((CFIndex)1024)
360 #endif
361
362 CF_EXPORT bool __CFOASafe;
363 CF_EXPORT void __CFSetLastAllocationEventName(void *ptr, const char *classname);
364
365
366
367 /* Comparators are passed the address of the values; this is somewhat different than CFComparatorFunction is used in public API usually. */
368 CF_EXPORT CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context);
369
370 CF_EXPORT CFHashCode CFHashBytes(UInt8 *bytes, CFIndex length);
371
372 CF_EXPORT CFStringEncoding CFStringFileSystemEncoding(void);
373
374 __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);
375
376 extern const void *__CFStringCollectionCopy(CFAllocatorRef allocator, const void *ptr);
377 extern const void *__CFTypeCollectionRetain(CFAllocatorRef allocator, const void *ptr);
378 extern void __CFTypeCollectionRelease(CFAllocatorRef allocator, const void *ptr);
379
380 extern CFTypeRef CFMakeUncollectable(CFTypeRef cf);
381
382 __private_extern__ void _CFRaiseMemoryException(CFStringRef reason);
383
384 __private_extern__ Boolean __CFProphylacticAutofsAccess;
385
386
387 #if DEPLOYMENT_TARGET_MACOSX
388
389 typedef OSSpinLock CFSpinLock_t;
390
391 #define CFSpinLockInit OS_SPINLOCK_INIT
392 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
393
394 #define __CFSpinLock(LP) ({ \
395 OSSpinLock *__lockp__ = (LP); \
396 OSSpinLock __lockv__ = *__lockp__; \
397 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
398 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__); \
399 /* HALT; */ \
400 } \
401 OSSpinLockLock(__lockp__); })
402
403 #define __CFSpinUnlock(LP) ({ \
404 OSSpinLock *__lockp__ = (LP); \
405 OSSpinLock __lockv__ = *__lockp__; \
406 if (~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
407 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__); \
408 /* HALT; */ \
409 } \
410 OSSpinLockUnlock(__lockp__); })
411
412 #define __CFSpinLockTry(LP) ({ \
413 OSSpinLock *__lockp__ = (LP); \
414 OSSpinLock __lockv__ = *__lockp__; \
415 if (0 != __lockv__ && ~0 != __lockv__ && (uintptr_t)__lockp__ != (uintptr_t)__lockv__) { \
416 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__); \
417 /* HALT; */ \
418 } \
419 OSSpinLockTry(__lockp__); })
420
421 #elif DEPLOYMENT_TARGET_EMBEDDED
422
423 typedef OSSpinLock CFSpinLock_t;
424
425 #define CFSpinLockInit OS_SPINLOCK_INIT
426 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
427
428 #define __CFSpinLock(LP) ({ \
429 OSSpinLock *__lockp__ = (LP); \
430 OSSpinLockLock(__lockp__); })
431
432 #define __CFSpinUnlock(LP) ({ \
433 OSSpinLock *__lockp__ = (LP); \
434 OSSpinLockUnlock(__lockp__); })
435
436 #define __CFSpinLockTry(LP) ({ \
437 OSSpinLock *__lockp__ = (LP); \
438 OSSpinLockTry(__lockp__); })
439
440 #elif DEPLOYMENT_TARGET_WINDOWS
441
442 typedef int32_t CFSpinLock_t;
443 #define CFSpinLockInit 0
444 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
445
446 CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) {
447 while (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) != 0) {
448 Sleep(0);
449 }
450 }
451
452 CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) {
453 MemoryBarrier();
454 *lock = 0;
455 }
456
457 CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
458 return (InterlockedCompareExchange((LONG volatile *)lock, ~0, 0) == 0);
459 }
460
461 #elif DEPLOYMENT_TARGET_LINUX
462
463 typedef int32_t CFSpinLock_t;
464 #define CFSpinLockInit 0
465 #define CF_SPINLOCK_INIT_FOR_STRUCTS(X) (X = CFSpinLockInit)
466
467 CF_INLINE void __CFSpinLock(volatile CFSpinLock_t *lock) {
468 while (__sync_val_compare_and_swap(lock, ~0, 0) != 0) {
469 sleep(0);
470 }
471 }
472
473 CF_INLINE void __CFSpinUnlock(volatile CFSpinLock_t *lock) {
474 __sync_synchronize();
475 *lock = 0;
476 }
477
478 CF_INLINE Boolean __CFSpinLockTry(volatile CFSpinLock_t *lock) {
479 return (__sync_val_compare_and_swap(lock, ~0, 0) == 0);
480 }
481
482 #else
483
484 #warning CF spin locks not defined for this platform -- CF is not thread-safe
485 #define __CFSpinLock(A) do {} while (0)
486 #define __CFSpinUnlock(A) do {} while (0)
487
488 #endif
489
490
491 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
492 extern uint8_t __CF120293;
493 extern uint8_t __CF120290;
494 extern void __THE_PROCESS_HAS_FORKED_AND_YOU_CANNOT_USE_THIS_COREFOUNDATION_FUNCTIONALITY___YOU_MUST_EXEC__(void);
495 #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)
496 #define CHECK_FOR_FORK_RET(...) do { CHECK_FOR_FORK(); if (__CF120293) return __VA_ARGS__; } while (0)
497 #define HAS_FORKED() (__CF120293)
498 #endif
499
500 #if !defined(CHECK_FOR_FORK)
501 #define CHECK_FOR_FORK() do { } while (0)
502 #endif
503
504 #if !defined(CHECK_FOR_FORK_RET)
505 #define CHECK_FOR_FORK_RET(...) do { } while (0)
506 #endif
507
508 #if !defined(HAS_FORKED)
509 #define HAS_FORKED() 0
510 #endif
511
512 #if DEPLOYMENT_TARGET_WINDOWS
513 #include <errno.h>
514 #elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_LINUX
515 #include <sys/errno.h>
516 #endif
517
518 #define thread_errno() errno
519 #define thread_set_errno(V) do {errno = (V);} while (0)
520
521 extern void *__CFStartSimpleThread(void *func, void *arg);
522
523 /* ==================== Simple file access ==================== */
524 /* For dealing with abstract types. MF:!!! These ought to be somewhere else and public. */
525
526 CF_EXPORT CFStringRef _CFCopyExtensionForAbstractType(CFStringRef abstractType);
527
528 /* ==================== Simple file access ==================== */
529 /* These functions all act on a c-strings which must be in the file system encoding. */
530
531 CF_EXPORT Boolean _CFCreateDirectory(const char *path);
532 #if DEPLOYMENT_TARGET_WINDOWS
533 CF_EXPORT Boolean _CFCreateDirectoryWide(const wchar_t *path);
534 #endif
535 CF_EXPORT Boolean _CFRemoveDirectory(const char *path);
536 CF_EXPORT Boolean _CFDeleteFile(const char *path);
537
538 CF_EXPORT Boolean _CFReadBytesFromFile(CFAllocatorRef alloc, CFURLRef url, void **bytes, CFIndex *length, CFIndex maxLength);
539 /* resulting bytes are allocated from alloc which MUST be non-NULL. */
540 /* maxLength of zero means the whole file. Otherwise it sets a limit on the number of bytes read. */
541
542 CF_EXPORT Boolean _CFWriteBytesToFile(CFURLRef url, const void *bytes, CFIndex length);
543 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
544 CF_EXPORT Boolean _CFWriteBytesToFileWithAtomicity(CFURLRef url, const void *bytes, unsigned int length, SInt32 mode, Boolean atomic);
545 #endif
546
547 CF_EXPORT CFMutableArrayRef _CFContentsOfDirectory(CFAllocatorRef alloc, char *dirPath, void *dirSpec, CFURLRef dirURL, CFStringRef matchingAbstractType);
548 /* On Mac OS 8/9, one of dirSpec, dirPath and dirURL must be non-NULL */
549 /* On all other platforms, one of path and dirURL must be non-NULL */
550 /* If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */
551 /* alloc may be NULL */
552 /* return value is CFArray of CFURLs */
553
554 CF_EXPORT SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, 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 CF_EXPORT SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, SInt64 *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents);
559 /* alloc may be NULL */
560 /* 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. */
561
562
563 /* ==================== Simple path manipulation ==================== */
564 /* These functions all act on a UniChar buffers. */
565
566 CF_EXPORT Boolean _CFIsAbsolutePath(UniChar *unichars, CFIndex length);
567 CF_EXPORT Boolean _CFStripTrailingPathSlashes(UniChar *unichars, CFIndex *length);
568 __private_extern__ Boolean _CFAppendTrailingPathSlash(UniChar *unichars, CFIndex *length, CFIndex maxLength);
569 CF_EXPORT Boolean _CFAppendPathComponent(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *component, CFIndex componentLength);
570 CF_EXPORT Boolean _CFAppendPathExtension(UniChar *unichars, CFIndex *length, CFIndex maxLength, UniChar *extension, CFIndex extensionLength);
571 CF_EXPORT Boolean _CFTransmutePathSlashes(UniChar *unichars, CFIndex *length, UniChar replSlash);
572 CF_EXPORT CFIndex _CFStartOfLastPathComponent(UniChar *unichars, CFIndex length);
573 CF_EXPORT CFIndex _CFLengthAfterDeletingLastPathComponent(UniChar *unichars, CFIndex length);
574 CF_EXPORT CFIndex _CFStartOfPathExtension(UniChar *unichars, CFIndex length);
575 CF_EXPORT CFIndex _CFLengthAfterDeletingPathExtension(UniChar *unichars, CFIndex length);
576
577 #define __CFMaxRuntimeTypes 65535
578
579 // Tagged pointer support
580 // Low-bit set means tagged object, next 3 bits (currently)
581 // define the tagged object class, next 4 bits are for type
582 // information for the specific tagged object class. Thus,
583 // the low byte is for type info, and the rest of a pointer
584 // (32 or 64-bit) is for payload, whatever the tagged class.
585 //
586 // Note that the specific integers used to identify the
587 // specific tagged classes can and will change from release
588 // to release (that's why this stuff is in CF*Internal*.h),
589 // as can the definition of type info vs payload above.
590 //
591 #if defined(__x86_64__)
592 #define CF_IS_TAGGED_OBJ(PTR) ((uintptr_t)(PTR) & 0x1)
593 #define CF_TAGGED_OBJ_TYPE(PTR) ((uintptr_t)(PTR) & 0xF)
594 #else
595 #define CF_IS_TAGGED_OBJ(PTR) 0
596 #define CF_TAGGED_OBJ_TYPE(PTR) 0
597 #endif
598
599 enum {
600 kCFTaggedObjectID_Invalid = 0,
601 kCFTaggedObjectID_Undefined0 = (0 << 1) + 1,
602 kCFTaggedObjectID_Integer = (1 << 1) + 1,
603 kCFTaggedObjectID_Undefined2 = (2 << 1) + 1,
604 kCFTaggedObjectID_Undefined3 = (3 << 1) + 1,
605 kCFTaggedObjectID_Undefined4 = (4 << 1) + 1,
606 kCFTaggedObjectID_ManagedObjectID = (5 << 1) + 1, // Core Data
607 kCFTaggedObjectID_Date = (6 << 1) + 1,
608 kCFTaggedObjectID_DateTS = (7 << 1) + 1,
609 };
610
611
612 #define __CFRuntimeClassTableSize 1024
613
614 extern uintptr_t __CFRuntimeObjCClassTable[];
615 CF_INLINE uintptr_t __CFISAForTypeID(CFTypeID typeID) {
616 return (typeID < __CFRuntimeClassTableSize) ? __CFRuntimeObjCClassTable[typeID] : 0;
617 }
618
619 CF_INLINE Boolean CF_IS_OBJC(CFTypeID typeID, const void *obj) {
620 if (CF_IS_TAGGED_OBJ(obj)) return true;
621 uintptr_t cfisa = ((CFRuntimeBase *)obj)->_cfisa;
622 if (cfisa == 0) return false;
623 #if 0
624 // Temporarily disabled
625 #if __LP64__
626 if (cfisa < 0x10000000UL) {
627 CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
628 return false;
629 }
630 #else
631 if (cfisa < 0x1000UL) {
632 CFLog(kCFLogLevelWarning, CFSTR("*** Warning: CF tested pointer %p for objectness and found its isa pointer to be bogus (%p)"), obj, cfisa);
633 return false;
634 }
635 #endif
636 #endif
637 if (cfisa == (uintptr_t)__CFConstantStringClassReferencePtr) return false;
638 uintptr_t type_isa = (uintptr_t)(typeID < __CFRuntimeClassTableSize ? __CFRuntimeObjCClassTable[typeID] : 0);
639 if (cfisa == type_isa) return false;
640 return true;
641 }
642
643 #define STUB_CF_OBJC 1
644
645 #if STUB_CF_OBJC
646
647 #define CF_IS_OBJC(typeID, obj) (false)
648
649 #define CF_OBJC_VOIDCALL0(obj, sel) do { } while (0)
650 #define CF_OBJC_VOIDCALL1(obj, sel, a1) do { } while (0)
651 #define CF_OBJC_VOIDCALL2(obj, sel, a1, a2) do { } while (0)
652
653 #define CF_OBJC_CALL0(rettype, retvar, obj, sel) do { } while (0)
654 #define CF_OBJC_CALL1(rettype, retvar, obj, sel, a1) do { } while (0)
655 #define CF_OBJC_CALL2(rettype, retvar, obj, sel, a1, a2) do { } while (0)
656
657 #define CF_OBJC_FUNCDISPATCH0(typeID, rettype, obj, sel) do { } while (0)
658 #define CF_OBJC_FUNCDISPATCH1(typeID, rettype, obj, sel, a1) do { } while (0)
659 #define CF_OBJC_FUNCDISPATCH2(typeID, rettype, obj, sel, a1, a2) do { } while (0)
660 #define CF_OBJC_FUNCDISPATCH3(typeID, rettype, obj, sel, a1, a2, a3) do { } while (0)
661 #define CF_OBJC_FUNCDISPATCH4(typeID, rettype, obj, sel, a1, a2, a3, a4) do { } while (0)
662 #define CF_OBJC_FUNCDISPATCH5(typeID, rettype, obj, sel, a1, a2, a3, a4, a5) do { } while (0)
663
664 #endif // STUB_CF_OBJC
665
666
667 /* See comments in CFBase.c
668 */
669 #if SUPPORT_CFM
670 extern void __CF_FAULT_CALLBACK(void **ptr);
671 extern void *__CF_INVOKE_CALLBACK(void *, ...);
672 #define FAULT_CALLBACK(V) __CF_FAULT_CALLBACK(V)
673 #define INVOKE_CALLBACK1(P, A) (__CF_INVOKE_CALLBACK(P, A))
674 #define INVOKE_CALLBACK2(P, A, B) (__CF_INVOKE_CALLBACK(P, A, B))
675 #define INVOKE_CALLBACK3(P, A, B, C) (__CF_INVOKE_CALLBACK(P, A, B, C))
676 #define INVOKE_CALLBACK4(P, A, B, C, D) (__CF_INVOKE_CALLBACK(P, A, B, C, D))
677 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (__CF_INVOKE_CALLBACK(P, A, B, C, D, E))
678 #define UNFAULT_CALLBACK(V) do { V = (void *)((uintptr_t)V & ~0x3); } while (0)
679 #else
680 #define FAULT_CALLBACK(V)
681 #define INVOKE_CALLBACK1(P, A) (P)(A)
682 #define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
683 #define INVOKE_CALLBACK3(P, A, B, C) (P)(A, B, C)
684 #define INVOKE_CALLBACK4(P, A, B, C, D) (P)(A, B, C, D)
685 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (P)(A, B, C, D, E)
686 #define UNFAULT_CALLBACK(V) do { } while (0)
687 #endif
688
689 /* For the support of functionality which needs CarbonCore or other frameworks */
690 // These macros define an upcall or weak "symbol-lookup" wrapper function.
691 // The parameters are:
692 // R : the return type of the function
693 // N : the name of the function (in the other library)
694 // P : the parenthesized parameter list of the function
695 // A : the parenthesized actual argument list to be passed
696 // FAILACTION: (only for the _FAIL macros) additional code to be
697 // run when the function cannot be found.
698 // opt: a fifth optional argument can be passed in which is the
699 // return value of the wrapper when the function cannot be
700 // found; should be of type R, & can be a function call
701 // The name of the resulting wrapper function is:
702 // __CFCarbonCore_N (where N is the second parameter)
703 // __CFNetwork_N (where N is the second parameter)
704 //
705 // Example:
706 // DEFINE_WEAK_CARBONCORE_FUNC(void, DisposeHandle, (Handle h), (h))
707 //
708
709 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
710
711 extern void *__CFLookupCFNetworkFunction(const char *name);
712
713 #define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...) \
714 typedef R (*dyfuncptr)P; \
715 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \
716 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \
717 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \
718 if (dyfunc) { return dyfunc A ; } \
719 return __VA_ARGS__ ; \
720 }
721
722 #define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, FAILACTION, ...) \
723 static R __CFNetwork_ ## N P { \
724 typedef R (*dyfuncptr)P; \
725 static dyfuncptr dyfunc = (dyfuncptr)(~(uintptr_t)0); \
726 if ((dyfuncptr)(~(uintptr_t)0) == dyfunc) { \
727 dyfunc = (dyfuncptr)__CFLookupCFNetworkFunction(#N); } \
728 if (dyfunc) { return dyfunc A ; } \
729 FAILACTION ; \
730 return __VA_ARGS__ ; \
731 }
732
733 #else
734
735 #define DEFINE_WEAK_CFNETWORK_FUNC(R, N, P, A, ...)
736 #define DEFINE_WEAK_CFNETWORK_FUNC_FAIL(R, N, P, A, ...)
737
738 #endif
739
740
741 #if !defined(DEFINE_WEAK_CARBONCORE_FUNC)
742 #define DEFINE_WEAK_CARBONCORE_FUNC(R, N, P, A, ...)
743 #endif
744 #if !defined(DEFINE_WEAK_CORESERVICESINTERNAL_FUNC)
745 #define DEFINE_WEAK_CORESERVICESINTERNAL_FUNC(R, N, P, A, ...)
746 #endif
747
748 __private_extern__ CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *str1, CFRange str1Range, CFStringInlineBuffer *str2, CFRange str2Range, CFOptionFlags options, const void *compareLocale);
749
750
751 __private_extern__ CFArrayRef _CFBundleCopyUserLanguages(Boolean useBackstops);
752
753
754 // This should only be used in CF types, not toll-free bridged objects!
755 // It should not be used with CFAllocator arguments!
756 // Use CFGetAllocator() in the general case, and this inline function in a few limited (but often called) situations.
757 CF_INLINE CFAllocatorRef __CFGetAllocator(CFTypeRef cf) { // !!! Use with CF types only, and NOT WITH CFAllocator!
758 if (CF_IS_TAGGED_OBJ(cf)) {
759 return kCFAllocatorSystemDefault;
760 }
761 if (__builtin_expect(__CFBitfieldGetValue(((const CFRuntimeBase *)cf)->_cfinfo[CF_INFO_BITS], 7, 7), 1)) {
762 return kCFAllocatorSystemDefault;
763 }
764 return *(CFAllocatorRef *)((char *)cf - sizeof(CFAllocatorRef));
765 }
766
767
768 #if DEPLOYMENT_TARGET_WINDOWS
769 __private_extern__ const wchar_t *_CFDLLPath(void);
770 __private_extern__ void __CFStringCleanup(void);
771 __private_extern__ void __CFSocketCleanup(void);
772 __private_extern__ void __CFUniCharCleanup(void);
773 __private_extern__ void __CFStreamCleanup(void);
774 #endif
775
776 /* !!! Avoid #importing objc.h; e.g. converting this to a .m file */
777 struct __objcFastEnumerationStateEquivalent {
778 unsigned long state;
779 unsigned long *itemsPtr;
780 unsigned long *mutationsPtr;
781 unsigned long extra[5];
782 };
783
784 CF_EXTERN_C_END
785
786 #endif /* ! __COREFOUNDATION_CFINTERNAL__ */
787