/ include / CoreFoundation / CFPriv.h
CFPriv.h
  1  /*
  2   * Copyright (c) 2015 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-2014, 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  
 58  CF_EXTERN_C_BEGIN
 59  
 60  CF_EXPORT intptr_t _CFDoOperation(intptr_t code, intptr_t subcode1, intptr_t subcode2);
 61  
 62  CF_EXPORT void _CFRuntimeSetCFMPresent(void *a);
 63  
 64  CF_EXPORT const char *_CFProcessPath(void);
 65  CF_EXPORT const char **_CFGetProcessPath(void);
 66  CF_EXPORT const char **_CFGetProgname(void);
 67  
 68  
 69  #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE || TARGET_OS_LINUX))
 70  CF_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)
 74  CF_EXPORT CFRunLoopRef CFRunLoopGetMain(void);
 75  CF_EXPORT SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled);
 76  
 77  
 78  CF_EXPORT void _CFRunLoopStopMode(CFRunLoopRef rl, CFStringRef modeName);
 79  
 80  CF_EXPORT CFIndex CFMachPortGetQueuedMessageCount(CFMachPortRef mp);
 81  
 82  CF_EXPORT CFPropertyListRef _CFURLCopyPropertyListRepresentation(CFURLRef url);
 83  #endif
 84  CF_EXPORT CFPropertyListRef _CFURLCopyPropertyListRepresentation(CFURLRef url);
 85  CF_EXPORT CFURLRef _CFURLCreateFromPropertyListRepresentation(CFAllocatorRef alloc, CFPropertyListRef pListRepresentation);
 86  
 87  CF_EXPORT void CFPreferencesFlushCaches(void);
 88  
 89  
 90  
 91  #if TARGET_OS_WIN32
 92  CF_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)
 97  struct FSSpec;
 98  CF_EXPORT
 99  Boolean _CFGetFSSpecFromURL(CFAllocatorRef alloc, CFURLRef url, struct FSSpec *spec);
100  
101  CF_EXPORT
102  CFURLRef _CFCreateURLFromFSSpec(CFAllocatorRef alloc, const struct FSSpec *voidspec, Boolean isDirectory);
103  #endif
104  #endif
105  
106  typedef CF_ENUM(CFIndex, CFURLComponentDecomposition) {
107  	kCFURLComponentDecompositionNonHierarchical,
108  	kCFURLComponentDecompositionRFC1808, /* use this for RFC 1738 decompositions as well */
109  	kCFURLComponentDecompositionRFC2396
110  };
111  
112  typedef struct {
113  	CFStringRef scheme;
114  	CFStringRef schemeSpecific;
115  } CFURLComponentsNonHierarchical;
116  
117  typedef 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  
130  typedef 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 */
145  CF_EXPORT
146  Boolean _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. */
149  CF_EXPORT
150  CFURLRef _CFURLCreateFromComponents(CFAllocatorRef alloc, CFURLComponentDecomposition decompositionType, const void *components);
151  #define CFURLCopyComponents _CFURLCopyComponents
152  #define CFURLCreateFromComponents _CFURLCreateFromComponents
153  
154  
155  
156  CF_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. */
159  CF_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.
164  CF_EXPORT
165  CFStringRef CFGetUserName(void);
166  
167  CF_EXPORT
168  CFStringRef CFCopyUserName(void);
169  
170  CF_EXPORT
171  CFURLRef 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  */
188  typedef 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  
217  typedef 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  
225  CF_EXPORT
226  CFArrayRef CFCopySearchPathForDirectoriesInDomains(CFSearchPathDirectory directory, CFSearchPathDomainMask domainMask, Boolean expandTilde);
227  
228  
229  /* Obsolete keys */
230  CF_EXPORT const CFStringRef kCFFileURLExists;
231  CF_EXPORT const CFStringRef kCFFileURLPOSIXMode;
232  CF_EXPORT const CFStringRef kCFFileURLSize;
233  CF_EXPORT const CFStringRef kCFFileURLDirectoryContents;
234  CF_EXPORT const CFStringRef kCFFileURLLastModificationTime;
235  CF_EXPORT const CFStringRef kCFHTTPURLStatusCode;
236  CF_EXPORT const CFStringRef kCFHTTPURLStatusLine;
237  
238  
239  /* System Version file access */
240  CF_EXPORT CFStringRef CFCopySystemVersionString(void);			// Human-readable string containing both marketing and build version
241  CF_EXPORT CFDictionaryRef _CFCopySystemVersionDictionary(void);
242  CF_EXPORT CFDictionaryRef _CFCopyServerVersionDictionary(void);
243  CF_EXPORT const CFStringRef _kCFSystemVersionProductNameKey;
244  CF_EXPORT const CFStringRef _kCFSystemVersionProductCopyrightKey;
245  CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionKey;
246  CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionExtraKey;
247  CF_EXPORT const CFStringRef _kCFSystemVersionProductUserVisibleVersionKey;	// For loginwindow; see 2987512
248  CF_EXPORT const CFStringRef _kCFSystemVersionBuildVersionKey;		
249  CF_EXPORT const CFStringRef _kCFSystemVersionProductVersionStringKey;	// Localized string for the string "Version"
250  CF_EXPORT const CFStringRef _kCFSystemVersionBuildStringKey;		// Localized string for the string "Build"
251  
252  
253  CF_EXPORT void CFMergeSortArray(void *list, CFIndex count, CFIndex elementSize, CFComparatorFunction comparator, void *context);
254  CF_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  */
261  typedef 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  
275  CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version);
276  
277  
278  typedef 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  
285  CF_EXPORT CFRange CFStringGetRangeOfCharacterClusterAtIndex(CFStringRef string, CFIndex charIndex, CFStringCharacterClusterType type);
286  
287  // Compatibility kCFCompare flags. Use the new public kCFCompareDiacriticInsensitive
288  enum {
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   */
294  enum {
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 */
301  CF_EXPORT void _CFStringEncodingSetForceASCIICompatibility(Boolean flag);
302  
303  extern void __CFSetCharToUniCharFunc(Boolean (*func)(UInt32 flags, UInt8 ch, UniChar *unicodeChar));
304  extern UniChar __CFCharToUniCharTable[256];
305  
306  
307  #if defined(CF_INLINE)
308  CF_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  
334  CF_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
382  typedef struct {
383      UniChar buffer[__kCFStringAppendBufferLength];
384      CFIndex bufferIndex;
385      CFMutableStringRef theString;
386  } CFStringAppendBuffer;
387  
388  
389  // Initializes CFStringAppendBuffer with new mutable string.
390  CF_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.
397  CF_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.
418  CF_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.
438  CF_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   */
466  typedef 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
475  enum {
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   */
488  CF_EXPORT
489  void 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)
500  CF_INLINE bool CFCharacterSetInlineBufferIsLongCharacterMember(const 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
529  CF_EXPORT CFMutableStringRef _CFCreateApplicationRepositoryPath(CFAllocatorRef alloc, int nFolder);
530  #endif
531  
532  CF_EXPORT CFTypeRef _CFTryRetain(CFTypeRef cf);
533  CF_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  */
546  CF_EXPORT
547  Boolean CFLocaleGetLanguageRegionEncodingForLocaleIdentifier(CFStringRef localeIdentifier, LangCode *langCode, RegionCode *regCode, ScriptCode *scriptCode, CFStringEncoding *stringEncoding);
548  
549  #if TARGET_OS_WIN32
550  CF_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
557  CF_EXPORT CFMessagePortRef	CFMessagePortCreateUber(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo, Boolean isRemote);
558  CF_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  
564  CF_EXPORT CFMessagePortRef CFMessagePortCreatePerProcessLocal(CFAllocatorRef allocator, CFStringRef name, CFMessagePortCallBack callout, CFMessagePortContext *context, Boolean *shouldFreeInfo);
565  CF_EXPORT CFMessagePortRef CFMessagePortCreatePerProcessRemote(CFAllocatorRef allocator, CFStringRef name, CFIndex pid);
566  
567  
568  typedef CFDataRef (*CFMessagePortCallBackEx)(CFMessagePortRef local, SInt32 msgid, CFDataRef data, void *info, void *trailer, uintptr_t);
569  
570  CF_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
580  struct timespec { long tv_sec; long tv_nsec; };
581  #endif
582  #endif
583  
584  CF_INLINE CFAbsoluteTime _CFAbsoluteTimeFromFileTimeSpec(struct timespec ts) {
585      return (CFAbsoluteTime)((CFTimeInterval)ts.tv_sec - kCFAbsoluteTimeIntervalSince1970) + (1.0e-9 * (CFTimeInterval)ts.tv_nsec);
586  }
587  
588  CF_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
606  CF_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.
609  CF_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.
614  typedef CF_OPTIONS(CFOptionFlags, _CFBundleFilteredPlistOptions) {
615      _CFBundleFilteredPlistMemoryMapped = 1
616  } CF_ENUM_AVAILABLE(10_8, 6_0);
617  
618  CF_EXPORT CFPropertyListRef _CFBundleCreateFilteredInfoPlist(CFBundleRef bundle, CFSetRef keyPaths, _CFBundleFilteredPlistOptions options) CF_AVAILABLE(10_8, 6_0);
619  CF_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  
625  CF_EXPORT CFStringRef _CFGetWindowsAppleAppDataDirectory(void);
626  CF_EXPORT CFArrayRef _CFGetWindowsBinaryDirectories(void);
627  CF_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.
630  CF_EXPORT void _CFNotificationCenterSetRunLoop(CFNotificationCenterRef nc, CFRunLoopRef rl);
631  
632  CF_EXPORT uint32_t /*DWORD*/ _CFRunLoopGetWindowsMessageQueueMask(CFRunLoopRef rl, CFStringRef modeName);
633  CF_EXPORT void _CFRunLoopSetWindowsMessageQueueMask(CFRunLoopRef rl, uint32_t /*DWORD*/ mask, CFStringRef modeName);
634  
635  CF_EXPORT uint32_t /*DWORD*/ _CFRunLoopGetWindowsThreadID(CFRunLoopRef rl);
636  
637  typedef 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
640  CF_EXPORT CFWindowsMessageQueueHandler _CFRunLoopGetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeName);
641  CF_EXPORT void _CFRunLoopSetWindowsMessageQueueHandler(CFRunLoopRef rl, CFStringRef modeName, CFWindowsMessageQueueHandler func);
642  
643  #endif
644  
645  
646  CF_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
650  CF_EXPORT CFNotificationCenterRef CFNotificationCenterGetDistributedCenter(void);
651  #endif
652  
653  CF_EXPORT const CFStringRef kCFNumberFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);	// CFBoolean
654  CF_EXPORT const CFStringRef kCFDateFormatterUsesCharacterDirection CF_AVAILABLE(10_9, 6_0);	// CFBoolean
655  
656  // Related to macOS app nap
657  enum {
658      __CFRunLoopOptionsTakeAssertion,
659      __CFRunLoopOptionsDropAssertion
660  };
661  void __CFRunLoopSetOptionsReason(int opts, CFStringRef reason);
662  
663  // i'm guessing this is related to Marzipan (Apple's name for UIKit on macOS)
664  int _CFMZEnabled(void);
665  
666  CF_EXTERN_C_END
667  
668  #endif /* ! __COREFOUNDATION_CFPRIV__ */
669