1/*
2 * Copyright (c) 2014 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/*	CFPriv.h
25	Copyright (c) 1998-2013, Apple Inc. All rights reserved.
26*/
27
28/*
29        APPLE SPI:  NOT TO BE USED OUTSIDE APPLE!
30*/
31
32#if !defined(__COREFOUNDATION_CFPRIV__)
33#define __COREFOUNDATION_CFPRIV__ 1
34
35#include <string.h>
36#include <CoreFoundation/CFBase.h>
37#include <CoreFoundation/CFArray.h>
38#include <CoreFoundation/CFString.h>
39#include <CoreFoundation/CFURL.h>
40#include <CoreFoundation/CFLocale.h>
41#include <CoreFoundation/CFDate.h>
42#include <CoreFoundation/CFSet.h>
43#include <math.h>
44
45
46
47#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
48#include <CoreFoundation/CFMachPort.h>
49#include <CoreFoundation/CFMessagePort.h>
50#endif
51
52#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32
53#include <CoreFoundation/CFRunLoop.h>
54#include <CoreFoundation/CFSocket.h>
55#include <CoreFoundation/CFBundlePriv.h>
56#endif
57
58CF_EXTERN_C_BEGIN
59
60CF_EXPORT intptr_t _CFDoOperation(intptr_t code, intptr_t subcode1, intptr_t subcode2);
61
62CF_EXPORT void _CFRuntimeSetCFMPresent(void *a);
63
64CF_EXPORT const char *_CFProcessPath(void);
65CF_EXPORT const char **_CFGetProcessPath(void);
66CF_EXPORT const char **_CFGetProgname(void);
67
68
69#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX))
70CF_EXPORT void _CFRunLoopSetCurrent(CFRunLoopRef rl);
71#endif
72
73#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
74CF_EXPORT CFRunLoopRef CFRunLoopGetMain(void);
75CF_EXPORT SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled);
76
77
78CF_EXPORT void _CFRunLoopStopMode(CFRunLoopRef rl, CFStringRef modeName);
79
80CF_EXPORT CFIndex CFMachPortGetQueuedMessageCount(CFMachPortRef mp);
81
82CF_EXPORT CFPropertyListRef _CFURLCopyPropertyListRepresentation(CFURLRef url);
83#endif
84CF_EXPORT CFPropertyListRef _CFURLCopyPropertyListRepresentation(CFURLRef url);
85CF_EXPORT CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFPropertyListRef pListRepresentation);
86
87CF_EXPORT void CFPreferencesFlushCaches(void);
88
89
90
91#if TARGET_OS_WIN32
92CF_EXPORT Boolean _CFURLGetWideFileSystemRepresentation(CFURLRef url, Boolean resolveAgainstBase, wchar_t *buffer, CFIndex bufferLength);
93#endif
94
95#if !__LP64__
96#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
97struct FSSpec;
98CF_EXPORT
99Boolean _CFGetFSSpecFromURL(CFAllocatorRef alloc, CFURLRef url, struct FSSpec *spec);
100
101CF_EXPORT
102CFURLRef _CFCreateURLFromFSSpec(CFAllocatorRef alloc, const struct FSSpec *voidspec, Boolean isDirectory);
103#endif
104#endif
105
106typedef CF_ENUM(CFIndex, CFURLComponentDecomposition) {
107	kCFURLComponentDecompositionNonHierarchical,
108	kCFURLComponentDecompositionRFC1808, /* use this for RFC 1738 decompositions as well */
109	kCFURLComponentDecompositionRFC2396
110};
111
112typedef struct {
113	CFStringRef scheme;
114	CFStringRef schemeSpecific;
115} CFURLComponentsNonHierarchical;
116
117typedef struct {
118	CFStringRef scheme;
119	CFStringRef user;
120	CFStringRef password;
121	CFStringRef host;
122	CFIndex port; /* kCFNotFound means ignore/omit */
123	CFArrayRef pathComponents;
124	CFStringRef parameterString;
125	CFStringRef query;
126	CFStringRef fragment;
127	CFURLRef baseURL;
128} CFURLComponentsRFC1808;
129
130typedef struct {
131	CFStringRef scheme;
132
133	/* if the registered name form of the net location is used, userinfo is NULL, port is kCFNotFound, and host is the entire registered name. */
134	CFStringRef userinfo;
135	CFStringRef host;
136	CFIndex port;
137
138	CFArrayRef pathComponents;
139	CFStringRef query;
140	CFStringRef fragment;
141	CFURLRef baseURL;
142} CFURLComponentsRFC2396;
143
144/* Fills components and returns TRUE if the URL can be decomposed according to decompositionType; FALSE (leaving components unchanged) otherwise.  components should be a pointer to the CFURLComponents struct defined above that matches decompositionStyle */
145CF_EXPORT
146Boolean _CFURLCopyComponents(CFURLRef url, CFURLComponentDecomposition decompositionType, void *components);
147
148/* Creates and returns the URL described by components; components should point to the CFURLComponents struct defined above that matches decompositionType. */
149CF_EXPORT
150CFURLRef _CFURLCreateFromComponents(CFAllocatorRef alloc, CFURLComponentDecomposition decompositionType, const void *components);
151#define CFURLCopyComponents _CFURLCopyComponents
152#define CFURLCreateFromComponents _CFURLCreateFromComponents
153
154
155
156CF_EXPORT Boolean _CFStringGetFileSystemRepresentation(CFStringRef string, UInt8 *buffer, CFIndex maxBufLen);
157
158/* If this is publicized, we might need to create a GetBytesPtr type function as well. */
159CF_EXPORT CFStringRef _CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const UInt8 *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator);
160
161/* These return NULL on MacOS 8 */
162// This one leaks the returned string in order to be thread-safe.
163// CF cannot help you in this matter if you continue to use this SPI.
164CF_EXPORT
165CFStringRef CFGetUserName(void);
166
167CF_EXPORT
168CFStringRef CFCopyUserName(void);
169
170CF_EXPORT
171CFURLRef CFCopyHomeDirectoryURLForUser(CFStringRef uName);	/* Pass NULL for the current user's home directory */
172
173
174/*
175	CFCopySearchPathForDirectoriesInDomains returns the various
176	standard system directories where apps, resources, etc get
177	installed. Because queries can return multiple directories,
178	you get back a CFArray (which you should free when done) of
179	CFURLs. The directories are returned in search path order;
180	that is, the first place to look is returned first. This API
181	may return directories that do not exist yet. If NSUserDomain
182	is included in a query, then the results will contain "~" to
183	refer to the user's directory. Specify expandTilde to expand
184	this to the current user's home. Some calls might return no
185	directories!
186	??? On MacOS 8 this function currently returns an empty array.
187*/
188typedef CF_ENUM(CFIndex, CFSearchPathDirectory) {
189    kCFApplicationDirectory = 1,	/* supported applications (Applications) */
190    kCFDemoApplicationDirectory,	/* unsupported applications, demonstration versions (Demos) */
191    kCFDeveloperApplicationDirectory,	/* developer applications (Developer/Applications) */
192    kCFAdminApplicationDirectory,	/* system and network administration applications (Administration) */
193    kCFLibraryDirectory, 		/* various user-visible documentation, support, and configuration files, resources (Library) */
194    kCFDeveloperDirectory,		/* developer resources (Developer) */
195    kCFUserDirectory,			/* user home directories (Users) */
196    kCFDocumentationDirectory,		/* documentation (Documentation) */
197    kCFDocumentDirectory,		/* documents (Library/Documents) */
198
199    kCFCoreServiceDirectory = 10,            // location of CoreServices directory (System/Library/CoreServices)
200    kCFAutosavedInformationDirectory = 11,   // location of autosaved documents (Documents/Autosaved)
201    kCFDesktopDirectory = 12,                // location of user's desktop
202    kCFCachesDirectory = 13,                 // location of discardable cache files (Library/Caches)
203    kCFApplicationSupportDirectory = 14,     // location of application support files (plug-ins, etc) (Library/Application Support)
204    kCFDownloadsDirectory = 15,              // location of the user's "Downloads" directory
205    kCFInputMethodsDirectory = 16,           // input methods (Library/Input Methods)
206    kCFMoviesDirectory = 17,                 // location of user's Movies directory (~/Movies)
207    kCFMusicDirectory = 18,                  // location of user's Music directory (~/Music)
208    kCFPicturesDirectory = 19,               // location of user's Pictures directory (~/Pictures)
209    kCFPrinterDescriptionDirectory = 20,     // location of system's PPDs directory (Library/Printers/PPDs)
210    kCFSharedPublicDirectory = 21,           // location of user's Public sharing directory (~/Public)
211    kCFPreferencePanesDirectory = 22,        // location of the PreferencePanes directory for use with System Preferences (Library/PreferencePanes)
212
213    kCFAllApplicationsDirectory = 100,	/* all directories where applications can occur (ie Applications, Demos, Administration, Developer/Applications) */
214    kCFAllLibrariesDirectory = 101	/* all directories where resources can occur (Library, Developer) */
215};
216
217typedef CF_OPTIONS(CFOptionFlags, CFSearchPathDomainMask) {
218    kCFUserDomainMask = 1,	/* user's home directory --- place to install user's personal items (~) */
219    kCFLocalDomainMask = 2,	/* local to the current machine --- place to install items available to everyone on this machine (/Local) */
220    kCFNetworkDomainMask = 4, 	/* publically available location in the local area network --- place to install items available on the network (/Network) */
221    kCFSystemDomainMask = 8,	/* provided by Apple, unmodifiable (/System) */
222    kCFAllDomainsMask = 0x0ffff	/* all domains: all of the above and more, future items */
223};
224
225CF_EXPORT
226CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directory, CFSearchPathDomainMask domainMask, Boolean expandTilde);
227
228
229/* Obsolete keys */
230CF_EXPORT const CFStringRef kCFFileURLExists;
231CF_EXPORT const CFStringRef kCFFileURLPOSIXMode;
232CF_EXPORT const CFStringRef kCFFileURLSize;
233CF_EXPORT const CFStringRef kCFFileURLDirectoryContents;
234CF_EXPORT const CFStringRef kCFFileURLLastModificationTime;
235CF_EXPORT const CFStringRef kCFHTTPURLStatusCode;
236CF_EXPORT const CFStringRef kCFHTTPURLStatusLine;
237
238
239/* System Version file access */
240CF_EXPORT CFStringRef CFCopySystemVersionString(void);			// Human-readable string containing both marketing and build version
241CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
242CF_EXPORT CFDictionaryRef _CFCopyServerVersionDictionary(void);
243CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
244CF_EXPORT const CFStringRef _kCFSystemVersionProductCopyrightKey;
245CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
246CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionExtraKey;
247CF_EXPORT const CFStringRef _kCFSystemVersionProductUserVisibleVersionKey;	// For loginwindow; see 2987512
248CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;
249CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionStringKey;	// Localized string for the string "Version"
250CF_EXPORT const CFStringRef _kCFSystemVersionBuildStringKey;		// Localized string for the string "Build"
251
252
253CF_EXPORT void CFMergeSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFunction comparator, void *context);
254CF_EXPORT void CFQSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFunction comparator, void *context);
255
256/* _CFExecutableLinkedOnOrAfter(releaseVersionName) will return YES if the current executable seems to be linked on or after the specified release. Example: If you specify CFSystemVersionPuma (10.1), you will get back true for executables linked on Puma or Jaguar(10.2), but false for those linked on Cheetah (10.0) or any of its software updates (10.0.x). You will also get back false for any app whose version info could not be figured out.
257    This function caches its results, so no need to cache at call sites.
258
259  Note that for non-MACH this function always returns true.
260*/
261typedef CF_ENUM(CFIndex, CFSystemVersion) {
262    CFSystemVersionCheetah = 0,         /* 10.0 */
263    CFSystemVersionPuma = 1,            /* 10.1 */
264    CFSystemVersionJaguar = 2,          /* 10.2 */
265    CFSystemVersionPanther = 3,         /* 10.3 */
266    CFSystemVersionTiger = 4,           /* 10.4 */
267    CFSystemVersionLeopard = 5,         /* 10.5 */
268    CFSystemVersionSnowLeopard = 6,	/* 10.6 */
269    CFSystemVersionLion = 7,		/* 10.7 */
270    CFSystemVersionMountainLion = 8,    /* 10.8 */
271    CFSystemVersionMax,                 /* This should bump up when new entries are added */
272
273};
274
275CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version);
276
277
278typedef CF_ENUM(CFIndex, CFStringCharacterClusterType) {
279    kCFStringGraphemeCluster = 1, /* Unicode Grapheme Cluster */
280    kCFStringComposedCharacterCluster = 2, /* Compose all non-base (including spacing marks) */
281    kCFStringCursorMovementCluster = 3, /* Cluster suitable for cursor movements */
282    kCFStringBackwardDeletionCluster = 4 /* Cluster suitable for backward deletion */
283};
284
285CF_EXPORT CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex charIndex, CFStringCharacterClusterType type);
286
287// Compatibility kCFCompare flags. Use the new public kCFCompareDiacriticInsensitive
288enum {
289    kCFCompareDiacriticsInsensitive = 128 /* Use kCFCompareDiacriticInsensitive */
290};
291
292/* kCFCompare flags planned to be publicized (Aki 10/20/2008 Does not work with kCFCompareForceOrdering/CFStringFold). see <rdar://problem/6305147>)
293 */
294enum {
295    kCFCompareIgnoreNonAlphanumeric = (1UL << 16), // Ignores characters NOT in kCFCharacterSetAlphaNumeric
296};
297
298
299/* CFStringEncoding SPI */
300/* When set, CF encoding conversion engine keeps ASCII compatibility. (i.e. ASCII backslash <-> Unicode backslash in MacJapanese */
301CF_EXPORT void _CFStringEncodingSetForceASCIICompatibility(Boolean flag);
302
303extern void __CFSetCharToUniCharFunc(Boolean (*func)(UInt32 flags, UInt8 ch, UniChar *unicodeChar));
304extern UniChar __CFCharToUniCharTable[256];
305
306
307#if defined(CF_INLINE)
308CF_INLINE const UniChar *CFStringGetCharactersPtrFromInlineBuffer(CFStringInlineBuffer *buf, CFRange desiredRange) {
309    if ((desiredRange.location < 0) || ((desiredRange.location + desiredRange.length) > buf->rangeToBuffer.length)) return NULL;
310
311    if (buf->directUniCharBuffer) {
312        return buf->directUniCharBuffer + buf->rangeToBuffer.location + desiredRange.location;
313    } else {
314        if (desiredRange.length > __kCFStringInlineBufferLength) return NULL;
315
316        if (((desiredRange.location + desiredRange.length) > buf->bufferedRangeEnd) || (desiredRange.location < buf->bufferedRangeStart)) {
317            buf->bufferedRangeStart = desiredRange.location;
318            buf->bufferedRangeEnd = buf->bufferedRangeStart + __kCFStringInlineBufferLength;
319            if (buf->bufferedRangeEnd > buf->rangeToBuffer.length) buf->bufferedRangeEnd = buf->rangeToBuffer.length;
320            CFIndex location = buf->rangeToBuffer.location + buf->bufferedRangeStart;
321            CFIndex length = buf->bufferedRangeEnd - buf->bufferedRangeStart;
322            if (buf->directCStringBuffer) {
323                UniChar *bufPtr = buf->buffer;
324                while (length--) *bufPtr++ = (UniChar)buf->directCStringBuffer[location++];
325            } else {
326                CFStringGetCharacters(buf->theString, CFRangeMake(location, length), buf->buffer);
327            }
328        }
329
330        return buf->buffer + (desiredRange.location - buf->bufferedRangeStart);
331    }
332}
333
334CF_INLINE void CFStringGetCharactersFromInlineBuffer(CFStringInlineBuffer *buf, CFRange desiredRange, UniChar *outBuf) {
335    if (buf->directUniCharBuffer) {
336        memmove(outBuf, buf->directUniCharBuffer + buf->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar));
337    } else {
338        if ((desiredRange.location >= buf->bufferedRangeStart) && (desiredRange.location < buf->bufferedRangeEnd)) {
339            CFIndex bufLen = desiredRange.length;
340
341            if (bufLen > (buf->bufferedRangeEnd - desiredRange.location)) bufLen = (buf->bufferedRangeEnd - desiredRange.location);
342
343            memmove(outBuf, buf->buffer + (desiredRange.location - buf->bufferedRangeStart), bufLen * sizeof(UniChar));
344            outBuf += bufLen; desiredRange.location += bufLen; desiredRange.length -= bufLen;
345        } else {
346            CFIndex desiredRangeMax = (desiredRange.location + desiredRange.length);
347
348            if ((desiredRangeMax > buf->bufferedRangeStart) && (desiredRangeMax < buf->bufferedRangeEnd)) {
349                desiredRange.length = (buf->bufferedRangeStart - desiredRange.location);
350                memmove(outBuf + desiredRange.length, buf->buffer, (desiredRangeMax - buf->bufferedRangeStart) * sizeof(UniChar));
351            }
352        }
353
354        if (desiredRange.length > 0) {
355            CFIndex location = buf->rangeToBuffer.location + desiredRange.location;
356            CFIndex length = desiredRange.length;
357            if (buf->directCStringBuffer) {
358                UniChar *bufPtr = outBuf;
359                while (length--) *bufPtr++ = (UniChar)buf->directCStringBuffer[location++];
360            } else {
361                CFStringGetCharacters(buf->theString, CFRangeMake(location, length), outBuf);
362            }
363        }
364    }
365}
366
367#else
368#define CFStringGetCharactersPtrFromInlineBuffer(buf, desiredRange) ((buf)->directUniCharBuffer ? (buf)->directUniCharBuffer + (buf)->rangeToBuffer.location + desiredRange.location : NULL)
369
370#define CFStringGetCharactersFromInlineBuffer(buf, desiredRange, outBuf) \
371    if (buf->directUniCharBuffer) memmove(outBuf, (buf)->directUniCharBuffer + (buf)->rangeToBuffer.location + desiredRange.location, desiredRange.length * sizeof(UniChar)); \
372    else CFStringGetCharacters((buf)->theString, CFRangeMake((buf)->rangeToBuffer.location + desiredRange.location, desiredRange.length), outBuf);
373
374#endif /* CF_INLINE */
375
376
377#if defined(CF_INLINE)
378
379#ifndef __kCFStringAppendBufferLength
380    #define __kCFStringAppendBufferLength 1024
381#endif
382typedef struct {
383    UniChar buffer[__kCFStringAppendBufferLength];
384    CFIndex bufferIndex;
385    CFMutableStringRef theString;
386} CFStringAppendBuffer;
387
388
389// Initializes CFStringAppendBuffer with new mutable string.
390CF_INLINE void CFStringInitAppendBuffer(CFAllocatorRef alloc, CFStringAppendBuffer *buf)
391{
392    buf->bufferIndex = 0;
393    buf->theString = CFStringCreateMutable(alloc, 0);
394}
395
396// Appends the characters of a string to the CFStringAppendBuffer.
397CF_INLINE void CFStringAppendStringToAppendBuffer(CFStringAppendBuffer *buf, CFStringRef appendedString)
398{
399    CFIndex numChars = CFStringGetLength(appendedString);
400    if ( numChars > __kCFStringAppendBufferLength ) {
401        if ( buf->bufferIndex ) {
402            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
403            buf->bufferIndex = 0;
404        }
405        CFStringAppend(buf->theString, appendedString);
406    }
407    else {
408        if ( (buf->bufferIndex + numChars) > __kCFStringAppendBufferLength ) {
409            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
410            buf->bufferIndex = 0;
411        }
412        CFStringGetCharacters(appendedString, CFRangeMake(0, numChars), &buf->buffer[buf->bufferIndex]);
413        buf->bufferIndex += numChars;
414    }
415}
416
417// Appends a buffer of Unicode characters to the CFStringAppendBuffer.
418CF_INLINE void CFStringAppendCharactersToAppendBuffer(CFStringAppendBuffer *buf, const UniChar *chars, CFIndex numChars)
419{
420    if ( numChars > __kCFStringAppendBufferLength ) {
421        if ( buf->bufferIndex ) {
422            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
423            buf->bufferIndex = 0;
424        }
425        CFStringAppendCharacters(buf->theString, chars, numChars);
426    }
427    else {
428        if ( (buf->bufferIndex + numChars) > __kCFStringAppendBufferLength ) {
429            CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
430            buf->bufferIndex = 0;
431        }
432        memcpy(&buf->buffer[buf->bufferIndex], chars, numChars * sizeof(UniChar));
433        buf->bufferIndex += numChars;
434    }
435}
436
437// Returns a mutable string from the CFStringAppendBuffer.
438CF_INLINE CFMutableStringRef CFStringCreateMutableWithAppendBuffer(CFStringAppendBuffer *buf)
439{
440    if ( buf->bufferIndex ) {
441        CFStringAppendCharacters(buf->theString, buf->buffer, buf->bufferIndex);
442        buf->bufferIndex = 0;
443    }
444    CFMutableStringRef result = buf->theString;
445    buf->theString = NULL;
446    return ( result );
447}
448
449#endif /* CF_INLINE */
450
451/*
452 CFCharacterSetInlineBuffer related declarations
453 */
454/*!
455@typedef CFCharacterSetInlineBuffer
456 @field cset The character set this inline buffer is initialized with.
457 The object is not retained by the structure.
458 @field flags The field is a bit mask that carries various settings.
459 @field rangeStart The beginning of the character range that contains all members.
460 It is guaranteed that there is no member below this value.
461 @field rangeLimit The end of the character range that contains all members.
462 It is guaranteed that there is no member above and equal to this value.
463 @field bitmap The bitmap data representing the membership of the Basic Multilingual Plane characters.
464 If NULL, all BMP characters inside the range are members of the character set.
465 */
466typedef struct {
467    CFCharacterSetRef cset;
468    uint32_t flags;
469    uint32_t rangeStart;
470    uint32_t rangeLimit;
471    const uint8_t *bitmap;
472} CFCharacterSetInlineBuffer;
473
474// Bits for flags field
475enum {
476    kCFCharacterSetIsCompactBitmap = (1UL << 0),
477    kCFCharacterSetNoBitmapAvailable = (1UL << 1),
478    kCFCharacterSetIsInverted = (1UL << 2)
479};
480
481/*!
482@function CFCharacterSetInitInlineBuffer
483 Initializes buffer with cset.
484 @param cset The character set used to initialized the buffer.
485 If this parameter is not a valid CFCharacterSet, the behavior is undefined.
486 @param buffer The reference to the inline buffer to be initialized.
487 */
488CF_EXPORT
489void CFCharacterSetInitInlineBuffer(CFCharacterSetRef cset, CFCharacterSetInlineBuffer *buffer);
490
491/*!
492@function CFCharacterSetInlineBufferIsLongCharacterMember
493 Reports whether or not the UTF-32 character is in the character set.
494	@param buffer The reference to the inline buffer to be searched.
495	@param character The UTF-32 character for which to test against the
496 character set.
497 @result true, if the value is in the character set, otherwise false.
498 */
499#if defined(CF_INLINE)
500CF_INLINE bool CFCharacterSetInlineBufferIsLongCharacterMember(CFCharacterSetInlineBuffer *buffer, UTF32Char character) {
501    bool isInverted = ((0 == (buffer->flags & kCFCharacterSetIsInverted)) ? false : true);
502
503    if ((character >= buffer->rangeStart) && (character < buffer->rangeLimit)) {
504        if ((character > 0xFFFF) || (0 != (buffer->flags & kCFCharacterSetNoBitmapAvailable))) return (CFCharacterSetIsLongCharacterMember(buffer->cset, character) != 0);
505        if (NULL == buffer->bitmap) {
506            if (0 == (buffer->flags & kCFCharacterSetIsCompactBitmap)) isInverted = !isInverted;
507        } else if (0 == (buffer->flags & kCFCharacterSetIsCompactBitmap)) {
508            if (buffer->bitmap[character >> 3] & (1UL << (character & 7))) isInverted = !isInverted;
509        } else {
510            uint8_t value = buffer->bitmap[character >> 8];
511
512            if (value == 0xFF) {
513                isInverted = !isInverted;
514            } else if (value > 0) {
515                const uint8_t *segment = buffer->bitmap + (256 + (32 * (value - 1)));
516                character &= 0xFF;
517                if (segment[character >> 3] & (1UL << (character % 8))) isInverted = !isInverted;
518            }
519        }
520    }
521    return isInverted;
522}
523#else /* CF_INLINE */
524#define CFCharacterSetInlineBufferIsLongCharacterMember(buffer, character) (CFCharacterSetIsLongCharacterMember(buffer->cset, character))
525#endif /* CF_INLINE */
526
527
528#if TARGET_OS_WIN32
529CF_EXPORT CFMutableStringRef _CFCreateApplicationRepositoryPath(CFAllocatorRef alloc, int nFolder);
530#endif
531
532CF_EXPORT CFTypeRef _CFTryRetain(CFTypeRef cf);
533CF_EXPORT Boolean _CFIsDeallocating(CFTypeRef cf);
534
535/*
536 CFLocaleGetLanguageRegionEncodingForLocaleIdentifier gets the appropriate language and region codes,
537 and the default legacy script code and encoding, for the specified locale (or language) string.
538 Returns false if CFLocale has no information about the given locale; otherwise may set
539 *langCode and/or *regCode to -1 if there is no appropriate legacy value for the locale.
540 This is a replacement for the CFBundle SPI CFBundleGetLocalizationInfoForLocalization (which was intended to be temporary and transitional);
541 this function is more up-to-date in its handling of locale strings, and is in CFLocale where this functionality should belong. Compared
542 to CFBundleGetLocalizationInfoForLocalization, this function does not spcially interpret a NULL localeIdentifier to mean use the single most
543 preferred localization in the current context (this function returns NO for a NULL localeIdentifier); and in this function
544 langCode, regCode, and scriptCode are all SInt16* (not SInt32* like the equivalent parameters in CFBundleGetLocalizationInfoForLocalization).
545*/
546CF_EXPORT
547Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeIdentifier, LangCode *langCode, RegionCode *regCode, ScriptCode *scriptCode, CFStringEncoding *stringEncoding);
548
549#if TARGET_OS_WIN32
550CF_EXPORT CFMutableStringRef _CFCreateApplicationRepositoryPath(CFAllocatorRef alloc, int nFolder);
551#endif
552
553#if TARGET_OS_WIN32
554#include <CoreFoundation/CFMessagePort.h>
555
556#define CF_MESSAGE_PORT_CLONE_MESSAGE_ID -1209
557CF_EXPORT CFMessagePortRef	CFMessagePortCreateUber(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo, Boolean isRemote);
558CF_EXPORT void CFMessagePortSetCloneCallout(CFMessagePortRef ms, CFMessagePortCallBack cloneCallout);
559#endif
560
561#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
562#include <CoreFoundation/CFMessagePort.h>
563
564CF_EXPORT CFMessagePortRef CFMessagePortCreatePerProcessLocal(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo);
565CF_EXPORT CFMessagePortRef CFMessagePortCreatePerProcessRemote(CFAllocatorRef allocator, CFStringRef name, CFIndex pid);
566
567
568typedef CFDataRef (*CFMessagePortCallBackEx)(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info, void *trailer, uintptr_t);
569
570CF_EXPORT CFMessagePortRef _CFMessagePortCreateLocalEx(CFAllocatorRef allocator, CFStringRef name, Boolean perPID, uintptr_t unused, CFMessagePortCallBackEx callout2, CFMessagePortContext *context, Boolean *shouldFreeInfo);
571
572#endif
573
574#if TARGET_OS_MAC || TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX
575#include <pthread.h>
576#else
577// Avoid including the pthread header
578#ifndef HAVE_STRUCT_TIMESPEC
579#define HAVE_STRUCT_TIMESPEC 1
580struct timespec { long tv_sec; long tv_nsec; };
581#endif
582#endif
583
584CF_INLINE CFAbsoluteTime _CFAbsoluteTimeFromFileTimeSpec(struct timespec ts) {
585    return (CFAbsoluteTime)((CFTimeInterval)ts.tv_sec - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * (CFTimeInterval)ts.tv_nsec);
586}
587
588CF_INLINE struct timespec _CFFileTimeSpecFromAbsoluteTime(CFAbsoluteTime at) {
589   struct timespec ts;
590   double sec = 0.0;
591   double frac = modf(at, &sec);
592   if (frac < 0.0) {
593       frac += 1.0;
594       sec -= 1.0;
595   }
596#if TARGET_OS_WIN32
597   ts.tv_sec = (long)(sec + kCFAbsoluteTimeIntervalSince1970);
598#else
599   ts.tv_sec = (time_t)(sec + kCFAbsoluteTimeIntervalSince1970);
600#endif
601   ts.tv_nsec = (long)(1000000000UL * frac + 0.5);
602   return ts;
603}
604
605// The 'filtered' function below is preferred to this older one
606CF_EXPORT bool _CFPropertyListCreateSingleValue(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFStringRef keyPath, CFPropertyListRef *value, CFErrorRef *error);
607
608// 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.
609CF_EXPORT bool _CFPropertyListCreateFiltered(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags option, CFSetRef keyPaths, CFPropertyListRef *value, CFErrorRef *error) CF_AVAILABLE(10_8, 6_0);
610
611#if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) || (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE) || TARGET_OS_WIN32
612
613// 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.
614typedef CF_OPTIONS(CFOptionFlags, _CFBundleFilteredPlistOptions) {
615    _CFBundleFilteredPlistMemoryMapped = 1
616} CF_ENUM_AVAILABLE(10_8, 6_0);
617
618CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) CF_AVAILABLE(10_8, 6_0);
619CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredLocalizedInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, CFStringRef localizationName, _CFBundleFilteredPlistOptions options) CF_AVAILABLE(10_8, 6_0);
620#endif
621
622#if TARGET_OS_WIN32
623#include <CoreFoundation/CFNotificationCenter.h>
624
625CF_EXPORT CFStringRef _CFGetWindowsAppleAppDataDirectory(void);
626CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void);
627CF_EXPORT CFStringRef _CFGetWindowsAppleSystemLibraryDirectory(void);
628
629// If your Windows application does not use a CFRunLoop on the main thread (perhaps because it is reserved for handling UI events via Windows API), then call this function to make distributed notifications arrive using a different run loop.
630CF_EXPORT void _CFNotificationCenterSetRunLoop(CFNotificationCenterRef nc, CFRunLoopRef rl);
631
632CF_EXPORT uint32_t /*DWORD*/ _CFRunLoopGetWindowsMessageQueueMask(CFRunLoopRef rl, CFStringRef modeName);
633CF_EXPORT void _CFRunLoopSetWindowsMessageQueueMask(CFRunLoopRef rl, uint32_t /*DWORD*/ mask, CFStringRef modeName);
634
635CF_EXPORT uint32_t /*DWORD*/ _CFRunLoopGetWindowsThreadID(CFRunLoopRef rl);
636
637typedef void (*CFWindowsMessageQueueHandler)(void);
638
639// Run Loop parameter must be the current thread's run loop for the next two functions; you cannot use another thread's run loop
640CF_EXPORT CFWindowsMessageQueueHandler _CFRunLoopGetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeName);
641CF_EXPORT void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeName, CFWindowsMessageQueueHandler func);
642
643#endif
644
645
646CF_EXPORT CFArrayRef CFDateFormatterCreateDateFormatsFromTemplates(CFAllocatorRef allocator, CFArrayRef tmplates, CFOptionFlags options, CFLocaleRef locale);
647
648#if (TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)
649// Available for internal use on embedded
650CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
651#endif
652
653CF_EXPORT const CFStringRef kCFNumberFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);	// CFBoolean
654CF_EXPORT const CFStringRef kCFDateFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);	// CFBoolean
655
656
657CF_EXTERN_C_END
658
659#endif /* ! __COREFOUNDATION_CFPRIV__ */
660
661