X-Git-Url: https://git.saurik.com/apple/cf.git/blobdiff_plain/47a9ab1f151d80a00a045f81937ddac81c51a463..bd5b749cf7786ae858ab372fc8f64179736c6515:/Base.subproj/CFUtilities.c?ds=sidebyside diff --git a/Base.subproj/CFUtilities.c b/Base.subproj/CFUtilities.c deleted file mode 100644 index fed064f..0000000 --- a/Base.subproj/CFUtilities.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2005 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -/* CFUtilities.c - Copyright 1998-2002, Apple, Inc. All rights reserved. - Responsibility: Christopher Kane -*/ - -#include "CFUtilitiesPriv.h" -#include "CFInternal.h" -#include "CFPriv.h" -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__MACH__) - #include - #include - #include - #include - #include - #include - #include - #include -#endif -#if defined(__WIN32__) - #include - #include -#endif -#if defined(__LINUX__) || defined(__FREEBSD__) - #include - #include -#endif - -#define LESS16(A, W) do { if (A < ((uint64_t)1 << (W))) LESS8(A, (W) - 8); LESS8(A, (W) + 8); } while (0) -#define LESS8(A, W) do { if (A < ((uint64_t)1 << (W))) LESS4(A, (W) - 4); LESS4(A, (W) + 4); } while (0) -#define LESS4(A, W) do { if (A < ((uint64_t)1 << (W))) LESS2(A, (W) - 2); LESS2(A, (W) + 2); } while (0) -#define LESS2(A, W) do { if (A < ((uint64_t)1 << (W))) LESS1(A, (W) - 1); LESS1(A, (W) + 1); } while (0) -#define LESS1(A, W) do { if (A < ((uint64_t)1 << (W))) return (W) - 1; return (W); } while (0) - -uint32_t CFLog2(uint64_t x) { - if (x < ((uint64_t)1 << 32)) - LESS16(x, 16); - LESS16(x, 48); - return 0; -} - -#if 0 -// faster version for PPC -int Lg2d(unsigned x) { -// use PPC-specific instruction to count leading zeros - int ret; - if (0 == x) return 0; - __asm__ volatile("cntlzw %0,%1" : "=r" (ret) : "r" (x)); - return 31 - ret; -} -#endif - -#undef LESS1 -#undef LESS2 -#undef LESS4 -#undef LESS8 -#undef LESS16 - -/* Comparator is passed the address of the values. */ -/* Binary searches a sorted-increasing array of some type. - Return value is either 1) the index of the element desired, - if the target value exists in the list, 2) greater than or - equal to count, if the element is greater than all the values - in the list, or 3) the index of the element greater than the - target value. - - For example, a search in the list of integers: - 2 3 5 7 11 13 17 - - For... Will Return... - 2 0 - 5 2 - 23 7 - 1 0 - 9 4 - - For instance, if you just care about found/not found: - index = CFBSearch(list, count, elem); - if (count <= index || list[index] != elem) { - * Not found * - } else { - * Found * - } - - This isn't optimal yet. -*/ -__private_extern__ CFIndex CFBSearch(const void *element, CFIndex elementSize, const void *list, CFIndex count, CFComparatorFunction comparator, void *context) { - SInt32 idx, lg; - const char *ptr = (const char *)list; - if (count < 4) { - switch (count) { - case 3: if (comparator(ptr + elementSize * 2, element, context) < 0) return 3; - case 2: if (comparator(ptr + elementSize * 1, element, context) < 0) return 2; - case 1: if (comparator(ptr + elementSize * 0, element, context) < 0) return 1; - } - return 0; - } - if (comparator(ptr + elementSize * (count - 1), element, context) < 0) return count; - if (comparator(element, ptr + elementSize * 0, context) < 0) return 0; - lg = CFLog2(count); /* This takes about 1/3rd of the time, discounting calls to comparator */ - idx = (comparator(ptr + elementSize * (-1 + (1 << lg)), element, context) < 0) ? count - (1 << lg) : -1; - switch (--lg) { - case 30: if (comparator(ptr + elementSize * (idx + (1 << 30)), element, context) < 0) idx += (1 << 30); - case 29: if (comparator(ptr + elementSize * (idx + (1 << 29)), element, context) < 0) idx += (1 << 29); - case 28: if (comparator(ptr + elementSize * (idx + (1 << 28)), element, context) < 0) idx += (1 << 28); - case 27: if (comparator(ptr + elementSize * (idx + (1 << 27)), element, context) < 0) idx += (1 << 27); - case 26: if (comparator(ptr + elementSize * (idx + (1 << 26)), element, context) < 0) idx += (1 << 26); - case 25: if (comparator(ptr + elementSize * (idx + (1 << 25)), element, context) < 0) idx += (1 << 25); - case 24: if (comparator(ptr + elementSize * (idx + (1 << 24)), element, context) < 0) idx += (1 << 24); - case 23: if (comparator(ptr + elementSize * (idx + (1 << 23)), element, context) < 0) idx += (1 << 23); - case 22: if (comparator(ptr + elementSize * (idx + (1 << 22)), element, context) < 0) idx += (1 << 22); - case 21: if (comparator(ptr + elementSize * (idx + (1 << 21)), element, context) < 0) idx += (1 << 21); - case 20: if (comparator(ptr + elementSize * (idx + (1 << 20)), element, context) < 0) idx += (1 << 20); - case 19: if (comparator(ptr + elementSize * (idx + (1 << 19)), element, context) < 0) idx += (1 << 19); - case 18: if (comparator(ptr + elementSize * (idx + (1 << 18)), element, context) < 0) idx += (1 << 18); - case 17: if (comparator(ptr + elementSize * (idx + (1 << 17)), element, context) < 0) idx += (1 << 17); - case 16: if (comparator(ptr + elementSize * (idx + (1 << 16)), element, context) < 0) idx += (1 << 16); - case 15: if (comparator(ptr + elementSize * (idx + (1 << 15)), element, context) < 0) idx += (1 << 15); - case 14: if (comparator(ptr + elementSize * (idx + (1 << 14)), element, context) < 0) idx += (1 << 14); - case 13: if (comparator(ptr + elementSize * (idx + (1 << 13)), element, context) < 0) idx += (1 << 13); - case 12: if (comparator(ptr + elementSize * (idx + (1 << 12)), element, context) < 0) idx += (1 << 12); - case 11: if (comparator(ptr + elementSize * (idx + (1 << 11)), element, context) < 0) idx += (1 << 11); - case 10: if (comparator(ptr + elementSize * (idx + (1 << 10)), element, context) < 0) idx += (1 << 10); - case 9: if (comparator(ptr + elementSize * (idx + (1 << 9)), element, context) < 0) idx += (1 << 9); - case 8: if (comparator(ptr + elementSize * (idx + (1 << 8)), element, context) < 0) idx += (1 << 8); - case 7: if (comparator(ptr + elementSize * (idx + (1 << 7)), element, context) < 0) idx += (1 << 7); - case 6: if (comparator(ptr + elementSize * (idx + (1 << 6)), element, context) < 0) idx += (1 << 6); - case 5: if (comparator(ptr + elementSize * (idx + (1 << 5)), element, context) < 0) idx += (1 << 5); - case 4: if (comparator(ptr + elementSize * (idx + (1 << 4)), element, context) < 0) idx += (1 << 4); - case 3: if (comparator(ptr + elementSize * (idx + (1 << 3)), element, context) < 0) idx += (1 << 3); - case 2: if (comparator(ptr + elementSize * (idx + (1 << 2)), element, context) < 0) idx += (1 << 2); - case 1: if (comparator(ptr + elementSize * (idx + (1 << 1)), element, context) < 0) idx += (1 << 1); - case 0: if (comparator(ptr + elementSize * (idx + (1 << 0)), element, context) < 0) idx += (1 << 0); - } - return ++idx; -} - - -#define ELF_STEP(B) T1 = (H << 4) + B; T2 = T1 & 0xF0000000; if (T2) T1 ^= (T2 >> 24); T1 &= (~T2); H = T1; - -CFHashCode CFHashBytes(uint8_t *bytes, CFIndex length) { - /* The ELF hash algorithm, used in the ELF object file format */ - UInt32 H = 0, T1, T2; - SInt32 rem = length; - while (3 < rem) { - ELF_STEP(bytes[length - rem]); - ELF_STEP(bytes[length - rem + 1]); - ELF_STEP(bytes[length - rem + 2]); - ELF_STEP(bytes[length - rem + 3]); - rem -= 4; - } - switch (rem) { - case 3: ELF_STEP(bytes[length - 3]); - case 2: ELF_STEP(bytes[length - 2]); - case 1: ELF_STEP(bytes[length - 1]); - case 0: ; - } - return H; -} - -#undef ELF_STEP - -#if defined(__WIN32__) -struct _args { - void *func; - void *arg; - HANDLE handle; -}; -static __stdcall unsigned __CFWinThreadFunc(void *arg) { - struct _args *args = arg; - ((void (*)(void *))args->func)(args->arg); - CloseHandle(args->handle); - CFAllocatorDeallocate(kCFAllocatorSystemDefault, arg); - _endthreadex(0); - return 0; -} -#endif - -__private_extern__ void *__CFStartSimpleThread(void *func, void *arg) { -#if defined(__MACH__) || defined(__LINUX__) || defined(__FREEBSD__) - pthread_attr_t attr; - pthread_t tid; - pthread_attr_init(&attr); - pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attr, 60 * 1024); // 60K stack for our internal threads is sufficient - pthread_create(&tid, &attr, func, arg); - pthread_attr_destroy(&attr); -//warning CF: we dont actually know that a pthread_t is the same size as void * - return (void *)tid; -#else - unsigned tid; - struct _args *args = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(struct _args), 0); - if (__CFOASafe) __CFSetLastAllocationEventName(args, "CFUtilities (thread-args)"); - HANDLE handle; - args->func = func; - args->arg = arg; - /* The thread is created suspended, because otherwise there would be a race between the assignment below of the handle field, and it's possible use in the thread func above. */ - args->handle = (HANDLE)_beginthreadex(NULL, 0, (void *)__CFWinThreadFunc, args, CREATE_SUSPENDED, &tid); - handle = args->handle; - ResumeThread(handle); - return handle; -#endif -} - -__private_extern__ CFStringRef _CFCreateLimitedUniqueString() { - /* this unique string is only unique to the current host during the current boot */ - uint64_t tsr = __CFReadTSR(); - UInt32 tsrh = (tsr >> 32), tsrl = (tsr & (int64_t)0xFFFFFFFF); - return CFStringCreateWithFormat(NULL, NULL, CFSTR("CFUniqueString-%lu%lu$"), tsrh, tsrl); -} - - -// Looks for localized version of "nonLocalized" in the SystemVersion bundle -// If not found, and returnNonLocalizedFlag == true, will return the non localized string (retained of course), otherwise NULL -// If bundlePtr != NULL, will use *bundlePtr and will return the bundle in there; otherwise bundle is created and released - -static CFStringRef _CFCopyLocalizedVersionKey(CFBundleRef *bundlePtr, CFStringRef nonLocalized) { - CFStringRef localized = NULL; - CFBundleRef locBundle = bundlePtr ? *bundlePtr : NULL; - if (!locBundle) { - CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("/System/Library/CoreServices/SystemVersion.bundle"), kCFURLPOSIXPathStyle, false); - if (url) { - locBundle = CFBundleCreate(kCFAllocatorDefault, url); - CFRelease(url); - } - } - if (locBundle) { - localized = CFBundleCopyLocalizedString(locBundle, nonLocalized, nonLocalized, CFSTR("SystemVersion")); - if (bundlePtr) *bundlePtr = locBundle; else CFRelease(locBundle); - } - return localized ? localized : CFRetain(nonLocalized); -} - -static CFDictionaryRef _CFCopyVersionDictionary(CFStringRef path) { - CFPropertyListRef plist = NULL; - CFDataRef data; - CFURLRef url; - - url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, path, kCFURLPOSIXPathStyle, false); - if (url && CFURLCreateDataAndPropertiesFromResource(kCFAllocatorDefault, url, &data, NULL, NULL, NULL)) { - plist = CFPropertyListCreateFromXMLData(kCFAllocatorSystemDefault, data, kCFPropertyListMutableContainers, NULL); - CFRelease(data); - } - if (url) CFRelease(url); - - if (plist) { - CFBundleRef locBundle = NULL; - CFStringRef fullVersion, vers, versExtra, build; - CFStringRef versionString = _CFCopyLocalizedVersionKey(&locBundle, _kCFSystemVersionProductVersionStringKey); - CFStringRef buildString = _CFCopyLocalizedVersionKey(&locBundle, _kCFSystemVersionBuildStringKey); - CFStringRef fullVersionString = _CFCopyLocalizedVersionKey(&locBundle, CFSTR("FullVersionString")); - if (locBundle) CFRelease(locBundle); - - // Now build the full version string - if (CFEqual(fullVersionString, CFSTR("FullVersionString"))) { - CFRelease(fullVersionString); - fullVersionString = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ %%@ (%@ %%@)"), versionString, buildString); - } - vers = CFDictionaryGetValue(plist, _kCFSystemVersionProductVersionKey); - versExtra = CFDictionaryGetValue(plist, _kCFSystemVersionProductVersionExtraKey); - if (vers && versExtra) vers = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@ %@"), vers, versExtra); - build = CFDictionaryGetValue(plist, _kCFSystemVersionBuildVersionKey); - fullVersion = CFStringCreateWithFormat(NULL, NULL, fullVersionString, (vers ? vers : CFSTR("?")), build ? build : CFSTR("?")); - if (vers && versExtra) CFRelease(vers); - - CFDictionarySetValue((CFMutableDictionaryRef)plist, _kCFSystemVersionProductVersionStringKey, versionString); - CFDictionarySetValue((CFMutableDictionaryRef)plist, _kCFSystemVersionBuildStringKey, buildString); - CFDictionarySetValue((CFMutableDictionaryRef)plist, CFSTR("FullVersionString"), fullVersion); - CFRelease(versionString); - CFRelease(buildString); - CFRelease(fullVersionString); - CFRelease(fullVersion); - } - return plist; -} - -CFStringRef CFCopySystemVersionString(void) { - CFStringRef versionString; - CFDictionaryRef dict = _CFCopyServerVersionDictionary(); - if (!dict) dict = _CFCopySystemVersionDictionary(); - versionString = CFDictionaryGetValue(dict, CFSTR("FullVersionString")); - if (versionString) CFRetain(versionString); - CFRelease(dict); - return versionString; -} - -// Obsolete: These two functions cache the dictionaries to avoid calling _CFCopyVersionDictionary() more than once per dict desired -// In fact, they do not cache any more, because the file can change after -// apps are running in some situations, and apps need the new info. -// Proper caching and testing to see if the file has changed, without race -// conditions, would require semi-convoluted use of fstat(). - -CFDictionaryRef _CFCopySystemVersionDictionary(void) { - CFPropertyListRef plist = NULL; - plist = _CFCopyVersionDictionary(CFSTR("/System/Library/CoreServices/SystemVersion.plist")); - return plist; -} - -CFDictionaryRef _CFCopyServerVersionDictionary(void) { - CFPropertyListRef plist = NULL; - plist = _CFCopyVersionDictionary(CFSTR("/System/Library/CoreServices/ServerVersion.plist")); - return plist; -} - -CONST_STRING_DECL(_kCFSystemVersionProductNameKey, "ProductName") -CONST_STRING_DECL(_kCFSystemVersionProductCopyrightKey, "ProductCopyright") -CONST_STRING_DECL(_kCFSystemVersionProductVersionKey, "ProductVersion") -CONST_STRING_DECL(_kCFSystemVersionProductVersionExtraKey, "ProductVersionExtra") -CONST_STRING_DECL(_kCFSystemVersionProductUserVisibleVersionKey, "ProductUserVisibleVersion") -CONST_STRING_DECL(_kCFSystemVersionBuildVersionKey, "ProductBuildVersion") -CONST_STRING_DECL(_kCFSystemVersionProductVersionStringKey, "Version") -CONST_STRING_DECL(_kCFSystemVersionBuildStringKey, "Build") - -#if defined(__MACH__) - -typedef struct { - uint16_t primaryVersion; - uint8_t secondaryVersion; - uint8_t tertiaryVersion; -} CFLibraryVersion; - -CFLibraryVersion CFGetExecutableLinkedLibraryVersion(CFStringRef libraryName) { - CFLibraryVersion ret = {0xFFFF, 0xFF, 0xFF}; - char library[CFMaxPathSize]; // search specs larger than this are pointless - if (!CFStringGetCString(libraryName, library, sizeof(library), kCFStringEncodingUTF8)) return ret; - int32_t version = NSVersionOfLinkTimeLibrary(library); - if (-1 != version) { - ret.primaryVersion = version >> 16; - ret.secondaryVersion = (version >> 8) & 0xff; - ret.tertiaryVersion = version & 0xff; - } - return ret; -} - -CFLibraryVersion CFGetExecutingLibraryVersion(CFStringRef libraryName) { - CFLibraryVersion ret = {0xFFFF, 0xFF, 0xFF}; - char library[CFMaxPathSize]; // search specs larger than this are pointless - if (!CFStringGetCString(libraryName, library, sizeof(library), kCFStringEncodingUTF8)) return ret; - int32_t version = NSVersionOfRunTimeLibrary(library); - if (-1 != version) { - ret.primaryVersion = version >> 16; - ret.secondaryVersion = (version >> 8) & 0xff; - ret.tertiaryVersion = version & 0xff; - } - return ret; -} - - -/* -If - (vers != 0xFFFF): We know the version number of the library this app was linked against - and (versionInfo[version].VERSIONFIELD != 0xFFFF): And we know what version number started the specified release - and ((version == 0) || (versionInfo[version-1].VERSIONFIELD < versionInfo[version].VERSIONFIELD)): And it's distinct from the prev release -Then - If the version the app is linked against is less than the version recorded for the specified release - Then stop checking and return false - Else stop checking and return YES -Else - Continue checking (the next library) -*/ -#define checkLibrary(LIBNAME, VERSIONFIELD) \ - {uint16_t vers = (NSVersionOfLinkTimeLibrary(LIBNAME) >> 16); \ - if ((vers != 0xFFFF) && (versionInfo[version].VERSIONFIELD != 0xFFFF) && ((version == 0) || (versionInfo[version-1].VERSIONFIELD < versionInfo[version].VERSIONFIELD))) return (results[version] = ((vers < versionInfo[version].VERSIONFIELD) ? false : true)); } - -CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version) { - // The numbers in the below table should be the numbers for any version of the framework in the release. - // When adding new entries to this table for a new build train, it's simplest to use the versions of the - // first new versions of projects submitted to the new train. These can later be updated. One thing to watch for is that software updates - // for the previous release do not increase numbers beyond the number used for the next release! - // For a given train, don't ever use the last versions submitted to the previous train! (This to assure room for software updates.) - // If versions are the same as previous release, use 0xFFFF; this will assure the answer is a conservative NO. - // NOTE: Also update the CFM check below, perhaps to the previous release... (???) - static const struct { - uint16_t libSystemVersion; - uint16_t cocoaVersion; - uint16_t appkitVersion; - uint16_t fouVersion; - uint16_t cfVersion; - uint16_t carbonVersion; - uint16_t applicationServicesVersion; - uint16_t coreServicesVersion; - uint16_t iokitVersion; - } versionInfo[] = { - {50, 5, 577, 397, 196, 113, 16, 9, 52}, /* CFSystemVersionCheetah (used the last versions) */ - {55, 7, 620, 425, 226, 122, 16, 10, 67}, /* CFSystemVersionPuma (used the last versions) */ - {56, 8, 631, 431, 232, 122, 17, 11, 73}, /* CFSystemVersionJaguar */ - {67, 9, 704, 481, 281, 126, 19, 16, 159}, /* CFSystemVersionPanther */ - {73, 10, 750, 505, 305, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, /* CFSystemVersionTiger */ - {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}, /* CFSystemVersionChablis */ - }; - static char results[CFSystemVersionMax] = {-2, -2, -2, -2, -2, -2}; /* We cache the results per-release; there are only a few of these... */ - if (version >= CFSystemVersionMax) return false; /* Actually, we don't know the answer, and something scary is going on */ - if (results[version] != -2) return results[version]; - - if (_CFIsCFM()) { - results[version] = (version <= CFSystemVersionJaguar) ? true : false; - return results[version]; - } - - checkLibrary("System", libSystemVersion); // Pretty much everyone links with this - checkLibrary("Cocoa", cocoaVersion); - checkLibrary("AppKit", appkitVersion); - checkLibrary("Foundation", fouVersion); - checkLibrary("CoreFoundation", cfVersion); - checkLibrary("Carbon", carbonVersion); - checkLibrary("ApplicationServices", applicationServicesVersion); - checkLibrary("CoreServices", coreServicesVersion); - checkLibrary("IOKit", iokitVersion); - - /* If not found, then simply return NO to indicate earlier --- compatibility by default, unfortunately */ - return false; -} -#else -CF_EXPORT Boolean _CFExecutableLinkedOnOrAfter(CFSystemVersion version) { - return true; -} -#endif - - -__private_extern__ void *__CFLookupCarbonCoreFunction(const char *name) { - static void *image = NULL; - if (NULL == image) { - image = dlopen("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CarbonCore.framework/Versions/A/CarbonCore", RTLD_LAZY | RTLD_LOCAL); - } - void *dyfunc = NULL; - if (image) { - dyfunc = dlsym(image, name); - } - return dyfunc; -} - -__private_extern__ void *__CFLookupCFNetworkFunction(const char *name) { - static void *image = NULL; - if (NULL == image) { - image = dlopen("/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/CFNetwork.framework/Versions/A/CFNetwork", RTLD_LAZY | RTLD_LOCAL); - } - void *dyfunc = NULL; - if (image) { - dyfunc = dlsym(image, name); - } - return dyfunc; -} - - - -static void _CFShowToFile(FILE *file, Boolean flush, const void *obj) { - CFStringRef str; - CFIndex idx, cnt; - CFStringInlineBuffer buffer; - bool lastNL = false; - - if (obj) { - if (CFGetTypeID(obj) == CFStringGetTypeID()) { - // Makes Ali marginally happier - str = __CFCopyFormattingDescription(obj, NULL); - if (!str) str = CFCopyDescription(obj); - } else { - str = CFCopyDescription(obj); - } - } else { - str = CFRetain(CFSTR("(null)")); - } - cnt = CFStringGetLength(str); - - // iTunes used OutputDebugStringW(theString); - - CFStringInitInlineBuffer(str, &buffer, CFRangeMake(0, cnt)); - for (idx = 0; idx < cnt; idx++) { - UniChar ch = __CFStringGetCharacterFromInlineBufferQuick(&buffer, idx); - if (ch < 128) { - fprintf(file, "%c", ch); - lastNL = (ch == '\n'); - } else { - fprintf(file, "\\u%04x", ch); - } - } - if (!lastNL) { - fprintf(file, "\n"); - if (flush) fflush(file); - } - - if (str) CFRelease(str); -} - -void CFShow(const void *obj) { - _CFShowToFile(stderr, true, obj); -} - -static CFGregorianDate gregorianDate(void) { - CFTimeZoneRef tz = CFTimeZoneCopySystem(); // specifically choose system time zone for logs - CFGregorianDate gdate = CFAbsoluteTimeGetGregorianDate(CFAbsoluteTimeGetCurrent(), tz); - CFRelease(tz); - gdate.second = gdate.second + 0.0005; - return gdate; -} - -void CFLog(int p, CFStringRef format, ...) { - CFStringRef result; - va_list argList; - static CFSpinLock_t lock = 0; - - va_start(argList, format); - result = CFStringCreateWithFormatAndArguments(NULL, NULL, format, argList); - va_end(argList); - - __CFSpinLock(&lock); -#if defined(__WIN32__) - fprintf(stderr, "*** %s[%ld] CFLog(%d): ", *_CFGetProgname(), GetCurrentProcessId(), p); -#else - CFGregorianDate gdate = gregorianDate(); - // Date format: YYYY '-' MM '-' DD ' ' hh ':' mm ':' ss.fff - fprintf_l(stderr, NULL, "%04d-%02d-%02d %02d:%02d:%06.3f %s[%d] CFLog (%d): ", (int)gdate.year, gdate.month, gdate.day, gdate.hour, gdate.minute, gdate.second, *_CFGetProgname(), getpid(), p); -#endif - - CFShow(result); - __CFSpinUnlock(&lock); - CFRelease(result); -} - -