2 * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
26 Copyright (c) 1998-2003, Apple, Inc. All rights reserved.
30 NOT TO BE USED OUTSIDE CF!
34 #error The header file CFInternal.h is for the exclusive use of CoreFoundation. No other project should include it.
37 #if !defined(__COREFOUNDATION_CFINTERNAL__)
38 #define __COREFOUNDATION_CFINTERNAL__ 1
40 #include <CoreFoundation/CFBase.h>
41 #include <CoreFoundation/CFURL.h>
42 #include <CoreFoundation/CFString.h>
43 #include <CoreFoundation/CFDate.h>
44 #include <CoreFoundation/CFArray.h>
45 #include "ForFoundationOnly.h"
46 #include "CFRuntime.h"
48 #include <mach/thread_switch.h>
50 #if defined(__MACH__) || defined(__LINUX__) || defined(__FREEBSD__)
56 #if !defined(__MACH__)
57 #define __private_extern__
60 CF_EXPORT
char **_CFArgv(void);
61 CF_EXPORT
int _CFArgc(void);
63 CF_EXPORT
const char *_CFProcessName(void);
64 CF_EXPORT CFStringRef
_CFProcessNameString(void);
66 CF_EXPORT Boolean
_CFIsCFM(void);
68 CF_EXPORT Boolean
_CFGetCurrentDirectory(char *path
, int maxlen
);
70 CF_EXPORT CFStringRef
_CFGetUserName(void);
71 CF_EXPORT CFStringRef
_CFStringCreateHostName(void);
73 CF_EXPORT
void __CFSetNastyFile(CFTypeRef cf
);
75 CF_EXPORT
void _CFMachPortInstallNotifyPort(CFRunLoopRef rl
, CFStringRef mode
);
79 #define HALT asm __volatile__("trap")
80 #elif defined(__i386__)
81 #define HALT asm __volatile__("int3")
85 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \
88 CFLog(prio, CFSTR(desc), a1, a2, a3, a4, a5); \
93 #define __CFAssert(cond, prio, desc, a1, a2, a3, a4, a5) \
97 #define CFAssert(condition, priority, description) \
98 __CFAssert((condition), (priority), description, 0, 0, 0, 0, 0)
99 #define CFAssert1(condition, priority, description, a1) \
100 __CFAssert((condition), (priority), description, (a1), 0, 0, 0, 0)
101 #define CFAssert2(condition, priority, description, a1, a2) \
102 __CFAssert((condition), (priority), description, (a1), (a2), 0, 0, 0)
103 #define CFAssert3(condition, priority, description, a1, a2, a3) \
104 __CFAssert((condition), (priority), description, (a1), (a2), (a3), 0, 0)
105 #define CFAssert4(condition, priority, description, a1, a2, a3, a4) \
106 __CFAssert((condition), (priority), description, (a1), (a2), (a3), (a4), 0)
108 #define __kCFLogAssertion 15
111 extern void __CFGenericValidateType_(CFTypeRef cf
, CFTypeID type
, const char *func
);
112 #define __CFGenericValidateType(cf, type) __CFGenericValidateType_(cf, type, __PRETTY_FUNCTION__)
114 #define __CFGenericValidateType(cf, type)
118 /* Bit manipulation macros */
119 /* Bits are numbered from 31 on left to 0 on right */
120 /* 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. */
121 #define __CFBitfieldMask(N1, N2) ((((UInt32)~0UL) << (31UL - (N1) + (N2))) >> (31UL - N1))
122 #define __CFBitfieldGetValue(V, N1, N2) (((V) & __CFBitfieldMask(N1, N2)) >> (N2))
123 #define __CFBitfieldSetValue(V, N1, N2, X) ((V) = ((V) & ~__CFBitfieldMask(N1, N2)) | (((X) << (N2)) & __CFBitfieldMask(N1, N2)))
124 #define __CFBitfieldMaxValue(N1, N2) __CFBitfieldGetValue(0xFFFFFFFFUL, (N1), (N2))
126 #define __CFBitIsSet(V, N) (((V) & (1UL << (N))) != 0)
127 #define __CFBitSet(V, N) ((V) |= (1UL << (N)))
128 #define __CFBitClear(V, N) ((V) &= ~(1UL << (N)))
130 typedef struct ___CFThreadSpecificData
{
135 // If you add things to this struct, add cleanup to __CFFinalizeThreadData()
136 } __CFThreadSpecificData
;
138 extern __CFThreadSpecificData
*__CFGetThreadSpecificData(void);
140 #if defined(__MACH__) || defined(__LINUX__) || defined(__FREEBSD__)
141 extern pthread_key_t __CFTSDKey
;
143 #if defined(__WIN32__)
144 extern DWORD __CFTSDKey
;
147 //extern void *pthread_getspecific(pthread_key_t key);
149 CF_INLINE __CFThreadSpecificData
*__CFGetThreadSpecificData_inline(void) {
150 #if defined(__MACH__) || defined(__LINUX__) || defined(__FREEBSD__)
151 __CFThreadSpecificData
*data
= pthread_getspecific(__CFTSDKey
);
152 return data
? data
: __CFGetThreadSpecificData();
153 #elif defined(__WIN32__)
154 __CFThreadSpecificData
*data
= TlsGetValue(__CFTSDKey
);
155 return data
? data
: __CFGetThreadSpecificData();
159 CF_EXPORT
void CFLog(int p
, CFStringRef str
, ...);
161 #define __kCFAllocatorTypeID_CONST 2
163 CF_INLINE CFAllocatorRef
__CFGetDefaultAllocator(void) {
164 CFAllocatorRef allocator
= __CFGetThreadSpecificData_inline()->_allocator
;
165 if (NULL
== allocator
) {
166 allocator
= kCFAllocatorSystemDefault
;
171 extern CFTypeID
__CFGenericTypeID(const void *cf
);
173 // This should only be used in CF types, not toll-free bridged objects!
174 // It should not be used with CFAllocator arguments!
175 // Use CFGetAllocator() in the general case, and this inline function in a few limited (but often called) situations.
176 CF_INLINE CFAllocatorRef
__CFGetAllocator(CFTypeRef cf
) { // !!! Use with CF types only, and NOT WITH CFAllocator!
177 CFAssert1(__kCFAllocatorTypeID_CONST
!= __CFGenericTypeID(cf
), __kCFLogAssertion
, "__CFGetAllocator(): CFAllocator argument", cf
);
178 if (__CFBitfieldGetValue(((const CFRuntimeBase
*)cf
)->_info
, 7, 7)) {
179 return kCFAllocatorSystemDefault
;
181 return *(CFAllocatorRef
*)((char *)cf
- sizeof(CFAllocatorRef
));
184 // Don't define a __CFGetCurrentRunLoop(), because even internal clients should go through the real one
187 #if !defined(LLONG_MAX)
188 #if defined(_I64_MAX)
189 #define LLONG_MAX _I64_MAX
191 #warning Arbitrarily defining LLONG_MAX
192 #define LLONG_MAX (int64_t)9223372036854775807
194 #endif /* !defined(LLONG_MAX) */
196 #if !defined(LLONG_MIN)
197 #if defined(_I64_MIN)
198 #define LLONG_MIN _I64_MIN
200 #warning Arbitrarily defining LLONG_MIN
201 #define LLONG_MIN (-LLONG_MAX - (int64_t)1)
203 #endif /* !defined(LLONG_MIN) */
205 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
206 #define __CFMin(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
207 #define __CFMax(A,B) ({__typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
209 #define __CFMin(A,B) ((A) < (B) ? (A) : (B))
210 #define __CFMax(A,B) ((A) > (B) ? (A) : (B))
211 #endif /* __GNUC__ */
213 /* Secret CFAllocator hint bits */
214 #define __kCFAllocatorTempMemory 0x2
215 #define __kCFAllocatorNoPointers 0x10
216 #define __kCFAllocatorDoNotRecordEvent 0x100
218 CF_EXPORT CFAllocatorRef
_CFTemporaryMemoryAllocator(void);
220 extern SInt64
__CFTimeIntervalToTSR(CFTimeInterval ti
);
221 extern CFTimeInterval
__CFTSRToTimeInterval(SInt64 tsr
);
222 extern SInt64
__CFAbsoluteTimeToTSR(CFAbsoluteTime at
);
223 extern CFAbsoluteTime
__CFTSRToAbsoluteTime(SInt64 tsr
);
225 extern CFStringRef
__CFCopyFormattingDescription(CFTypeRef cf
, CFDictionaryRef formatOptions
);
227 /* result is long long or int, depending on doLonglong
229 extern Boolean
__CFStringScanInteger(CFStringInlineBuffer
*buf
, CFDictionaryRef locale
, SInt32
*indexPtr
, Boolean doLonglong
, void *result
);
230 extern Boolean
__CFStringScanDouble(CFStringInlineBuffer
*buf
, CFDictionaryRef locale
, SInt32
*indexPtr
, double *resultPtr
);
231 extern Boolean
__CFStringScanHex(CFStringInlineBuffer
*buf
, SInt32
*indexPtr
, unsigned *result
);
234 #define CONST_STRING_DECL(S, V) const CFStringRef S = __builtin___CFStringMakeConstantString(V);
237 #if defined(__MACH__)
238 #define __kCFCharacterSetDir "/System/Library/CoreServices"
239 #elif defined(__LINUX__) || defined(__FREEBSD__)
240 #define __kCFCharacterSetDir "/usr/local/share/CoreFoundation"
241 #elif defined(__WIN32__)
242 #define __kCFCharacterSetDir "\\Windows\\CoreFoundation"
246 /* Buffer size for file pathname */
247 #if defined(__WIN32__)
248 #define CFMaxPathSize ((CFIndex)262)
249 #define CFMaxPathLength ((CFIndex)260)
251 #define CFMaxPathSize ((CFIndex)1026)
252 #define CFMaxPathLength ((CFIndex)1024)
255 #if defined(__MACH__)
256 extern bool __CFOASafe
;
257 extern void __CFSetLastAllocationEventName(void *ptr
, const char *classname
);
260 #define __CFSetLastAllocationEventName(a, b)
264 CF_EXPORT CFStringRef
_CFCreateLimitedUniqueString(void);
266 extern CFStringRef
__CFCopyEthernetAddrString(void);
268 /* Comparators are passed the address of the values; this is somewhat different than CFComparatorFunction is used in public API usually. */
269 CF_EXPORT CFIndex
CFBSearch(const void *element
, CFIndex elementSize
, const void *list
, CFIndex count
, CFComparatorFunction comparator
, void *context
);
271 CF_EXPORT CFHashCode
CFHashBytes(UInt8
*bytes
, CFIndex length
);
273 CF_EXPORT CFStringEncoding
CFStringFileSystemEncoding(void);
275 CF_EXPORT 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
);
277 extern const void *__CFTypeCollectionRetain(CFAllocatorRef allocator
, const void *ptr
);
278 extern void __CFTypeCollectionRelease(CFAllocatorRef allocator
, const void *ptr
);
280 typedef uint32_t CFSpinLock_t
;
282 #if defined(__MACH__)
285 extern int __is_threaded
;
286 extern void _spin_lock(CFSpinLock_t
*lockp
);
287 extern void _spin_unlock(CFSpinLock_t
*lockp
);
288 // It would be better to use _pthread_is_threaded() instead of
289 // __is_threaded, but the latter is SO much faster it's hard to
290 // resist, and CF _is_ an internal project that can rev if needed.
292 CF_INLINE
void __CFSpinLock(CFSpinLock_t
*lockp
) {
293 if (__is_threaded
) _spin_lock(lockp
);
296 CF_INLINE
void __CFSpinUnlock(CFSpinLock_t
*lockp
) {
297 if (__is_threaded
) _spin_unlock(lockp
);
302 #warning CF spin locks not defined for this platform -- CF is not thread-safe
303 #define __CFSpinLock(A) do {} while (0)
304 #define __CFSpinUnlock(A) do {} while (0)
308 #if defined(__svr4__) || defined(__hpux__)
310 #elif defined(__WIN32__)
311 #elif defined(__MACH__) || defined(__LINUX__) || defined(__FREEBSD__)
312 #include <sys/errno.h>
315 #define thread_errno() errno
316 #define thread_set_errno(V) do {errno = (V);} while (0)
318 extern void *__CFStartSimpleThread(void *func
, void *arg
);
320 /* ==================== Simple file access ==================== */
321 /* For dealing with abstract types. MF:!!! These ought to be somewhere else and public. */
323 CF_EXPORT CFStringRef
_CFCopyExtensionForAbstractType(CFStringRef abstractType
);
325 /* ==================== Simple file access ==================== */
326 /* These functions all act on a c-strings which must be in the file system encoding. */
328 CF_EXPORT Boolean
_CFCreateDirectory(const char *path
);
329 CF_EXPORT Boolean
_CFRemoveDirectory(const char *path
);
330 CF_EXPORT Boolean
_CFDeleteFile(const char *path
);
332 CF_EXPORT Boolean
_CFReadBytesFromFile(CFAllocatorRef alloc
, CFURLRef url
, void **bytes
, CFIndex
*length
, CFIndex maxLength
);
333 /* resulting bytes are allocated from alloc which MUST be non-NULL. */
334 /* maxLength of zero means the whole file. Otherwise it sets a limit on the number of bytes read. */
336 CF_EXPORT Boolean
_CFWriteBytesToFile(CFURLRef url
, const void *bytes
, CFIndex length
);
337 #if defined(__MACH__)
338 CF_EXPORT Boolean
_CFWriteBytesToFileWithAtomicity(CFURLRef url
, const void *bytes
, unsigned int length
, SInt32 mode
, Boolean atomic
);
341 CF_EXPORT CFMutableArrayRef
_CFContentsOfDirectory(CFAllocatorRef alloc
, char *dirPath
, void *dirSpec
, CFURLRef dirURL
, CFStringRef matchingAbstractType
);
342 /* On Mac OS 8/9, one of dirSpec, dirPath and dirURL must be non-NULL */
343 /* On all other platforms, one of path and dirURL must be non-NULL */
344 /* If both are present, they are assumed to be in-synch; that is, they both refer to the same directory. */
345 /* alloc may be NULL */
346 /* return value is CFArray of CFURLs */
348 CF_EXPORT SInt32
_CFGetFileProperties(CFAllocatorRef alloc
, CFURLRef pathURL
, Boolean
*exists
, SInt32
*posixMode
, SInt64
*size
, CFDateRef
*modTime
, SInt32
*ownerID
, CFArrayRef
*dirContents
);
349 /* alloc may be NULL */
350 /* 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. */
353 /* ==================== Simple path manipulation ==================== */
354 /* These functions all act on a UniChar buffers. */
356 CF_EXPORT Boolean
_CFIsAbsolutePath(UniChar
*unichars
, CFIndex length
);
357 CF_EXPORT Boolean
_CFStripTrailingPathSlashes(UniChar
*unichars
, CFIndex
*length
);
358 CF_EXPORT Boolean
_CFAppendPathComponent(UniChar
*unichars
, CFIndex
*length
, CFIndex maxLength
, UniChar
*component
, CFIndex componentLength
);
359 CF_EXPORT Boolean
_CFAppendPathExtension(UniChar
*unichars
, CFIndex
*length
, CFIndex maxLength
, UniChar
*extension
, CFIndex extensionLength
);
360 CF_EXPORT Boolean
_CFTransmutePathSlashes(UniChar
*unichars
, CFIndex
*length
, UniChar replSlash
);
361 CF_EXPORT CFIndex
_CFStartOfLastPathComponent(UniChar
*unichars
, CFIndex length
);
362 CF_EXPORT CFIndex
_CFLengthAfterDeletingLastPathComponent(UniChar
*unichars
, CFIndex length
);
363 CF_EXPORT CFIndex
_CFStartOfPathExtension(UniChar
*unichars
, CFIndex length
);
364 CF_EXPORT CFIndex
_CFLengthAfterDeletingPathExtension(UniChar
*unichars
, CFIndex length
);
366 #if !defined(__MACH__)
368 #define CF_IS_OBJC(typeID, obj) (false)
370 #define CF_OBJC_FUNCDISPATCH0(typeID, rettype, obj, sel)
371 #define CF_OBJC_FUNCDISPATCH1(typeID, rettype, obj, sel, a1)
372 #define CF_OBJC_FUNCDISPATCH2(typeID, rettype, obj, sel, a1, a2)
373 #define CF_OBJC_FUNCDISPATCH3(typeID, rettype, obj, sel, a1, a2, a3)
374 #define CF_OBJC_FUNCDISPATCH4(typeID, rettype, obj, sel, a1, a2, a3, a4)
378 #if defined(__LINUX__) || defined(__FREEBSD__) || defined(__WIN32__)
379 #define __CFISAForTypeID(x) (NULL)
382 #if defined(__MACH__)
384 struct objc_class
{ // nasty, nasty
390 #define __CFMaxRuntimeTypes 256
392 extern struct objc_class
*__CFRuntimeObjCClassTable
[];
393 CF_INLINE
void *__CFISAForTypeID(CFTypeID typeID
) {
394 return (void *)(__CFRuntimeObjCClassTable
[typeID
]);
399 extern SEL (*__CFGetObjCSelector
)(const char *);
400 extern void * (*__CFSendObjCMsg
)(const void *, SEL
, ...);
402 // Although it might seem to make better performance to check for NULL
403 // first, doing the other check first is better.
404 CF_INLINE
int CF_IS_OBJC(CFTypeID typeID
, const void *obj
) {
405 return (((CFRuntimeBase
*)obj
)->_isa
!= __CFISAForTypeID(typeID
) && ((CFRuntimeBase
*)obj
)->_isa
> (void *)0xFFF);
408 #define CF_OBJC_FUNCDISPATCH0(typeID, rettype, obj, sel) \
409 if (CF_IS_OBJC(typeID, obj)) \
410 {rettype (*func)(const void *, SEL) = (void *)__CFSendObjCMsg; \
411 static SEL s = NULL; if (!s) s = __CFGetObjCSelector(sel); \
412 return func((const void *)obj, s);}
413 #define CF_OBJC_FUNCDISPATCH1(typeID, rettype, obj, sel, a1) \
414 if (CF_IS_OBJC(typeID, obj)) \
415 {rettype (*func)(const void *, SEL, ...) = (void *)__CFSendObjCMsg; \
416 static SEL s = NULL; if (!s) s = __CFGetObjCSelector(sel); \
417 return func((const void *)obj, s, (a1));}
418 #define CF_OBJC_FUNCDISPATCH2(typeID, rettype, obj, sel, a1, a2) \
419 if (CF_IS_OBJC(typeID, obj)) \
420 {rettype (*func)(const void *, SEL, ...) = (void *)__CFSendObjCMsg; \
421 static SEL s = NULL; if (!s) s = __CFGetObjCSelector(sel); \
422 return func((const void *)obj, s, (a1), (a2));}
423 #define CF_OBJC_FUNCDISPATCH3(typeID, rettype, obj, sel, a1, a2, a3) \
424 if (CF_IS_OBJC(typeID, obj)) \
425 {rettype (*func)(const void *, SEL, ...) = (void *)__CFSendObjCMsg; \
426 static SEL s = NULL; if (!s) s = __CFGetObjCSelector(sel); \
427 return func((const void *)obj, s, (a1), (a2), (a3));}
428 #define CF_OBJC_FUNCDISPATCH4(typeID, rettype, obj, sel, a1, a2, a3, a4) \
429 if (CF_IS_OBJC(typeID, obj)) \
430 {rettype (*func)(const void *, SEL, ...) = (void *)__CFSendObjCMsg; \
431 static SEL s = NULL; if (!s) s = __CFGetObjCSelector(sel); \
432 return func((const void *)obj, s, (a1), (a2), (a3), (a4));}
436 /* See comments in CFBase.c
438 #if defined(__ppc__) && defined(__MACH__)
439 extern void __CF_FAULT_CALLBACK(void **ptr
);
440 extern void *__CF_INVOKE_CALLBACK(void *, ...);
442 #define FAULT_CALLBACK(V) __CF_FAULT_CALLBACK(V)
443 #define INVOKE_CALLBACK1(P, A) __CF_INVOKE_CALLBACK(P, A)
444 #define INVOKE_CALLBACK2(P, A, B) __CF_INVOKE_CALLBACK(P, A, B)
445 #define INVOKE_CALLBACK3(P, A, B, C) __CF_INVOKE_CALLBACK(P, A, B, C)
446 #define INVOKE_CALLBACK4(P, A, B, C, D) __CF_INVOKE_CALLBACK(P, A, B, C, D)
447 #define INVOKE_CALLBACK5(P, A, B, C, D, E) __CF_INVOKE_CALLBACK(P, A, B, C, D, E)
449 #define FAULT_CALLBACK(V)
450 #define INVOKE_CALLBACK1(P, A) (P)(A)
451 #define INVOKE_CALLBACK2(P, A, B) (P)(A, B)
452 #define INVOKE_CALLBACK3(P, A, B, C) (P)(A, B, C)
453 #define INVOKE_CALLBACK4(P, A, B, C, D) (P)(A, B, C, D)
454 #define INVOKE_CALLBACK5(P, A, B, C, D, E) (P)(A, B, C, D, E)
458 __private_extern__ CFArrayRef
_CFBundleCopyUserLanguages(Boolean useBackstops
);
460 #endif /* ! __COREFOUNDATION_CFINTERNAL__ */