+#if OLD_CRAP_TOO
+
+static const unsigned char __CFNumberCanonicalType[kCFNumberMaxType + 1] = {
+ 0, kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
+ kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
+ kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type
+};
+
+static const unsigned char __CFNumberStorageType[kCFNumberMaxType + 1] = {
+ 0, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
+ kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
+ kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type
+};
+
+
+
+// Returns the type that is used to store the specified type
+static CFNumberType __CFNumberGetStorageTypeForType_old(CFNumberType type) {
+ return __CFNumberStorageType[type];
+}
+
+// Returns the canonical type used to represent the specified type
+static CFNumberType __CFNumberGetCanonicalTypeForType_old(CFNumberType type) {
+ return __CFNumberCanonicalType[type];
+}
+
+// Extracts and returns the type out of the CFNumber
+static CFNumberType __CFNumberGetType_old(struct __CFNumber_old * num) {
+ return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0);
+}
+
+// Returns true if the argument type is float or double
+static Boolean __CFNumberTypeIsFloat_old(CFNumberType type) {
+ return (type == kCFNumberFloat64Type) || (type == kCFNumberFloat32Type) || (type == kCFNumberDoubleType) || (type == kCFNumberFloatType);
+}
+
+// Returns the number of bytes necessary to store the specified type
+// Needs to handle all canonical types
+static CFIndex __CFNumberSizeOfType_old(CFNumberType type) {
+ switch (type) {
+ case kCFNumberSInt8Type: return sizeof(int8_t);
+ case kCFNumberSInt16Type: return sizeof(int16_t);
+ case kCFNumberSInt32Type: return sizeof(SInt32);
+ case kCFNumberSInt64Type: return sizeof(int64_t);
+ case kCFNumberFloat32Type: return sizeof(Float32);
+ case kCFNumberFloat64Type: return sizeof(Float64);
+ default: printf("*** WARNING: 0 size from __CFNumberSizeOfType_old \n"); return 0;
+ }
+}
+
+// Copies an external value of a given type into the appropriate slot in the union (does no type conversion)
+// Needs to handle all canonical types
+#define SET_VALUE(valueUnion, type, valuePtr) \
+ switch (type) { \
+ case kCFNumberSInt8Type: (valueUnion)->valSInt32 = *(int8_t *)(valuePtr); break; \
+ case kCFNumberSInt16Type: (valueUnion)->valSInt32 = *(int16_t *)(valuePtr); break; \
+ case kCFNumberSInt32Type: (valueUnion)->valSInt32 = *(SInt32 *)(valuePtr); break; \
+ case kCFNumberSInt64Type: (valueUnion)->valSInt64 = *(int64_t *)(valuePtr); break; \
+ case kCFNumberFloat32Type: (valueUnion)->valFloat32 = *(Float32 *)(valuePtr); break; \
+ case kCFNumberFloat64Type: (valueUnion)->valFloat64 = *(Float64 *)(valuePtr); break; \
+ default: printf("*** WARNING: default case in SET_VALUE \n"); break; \
+ }
+
+// Casts the specified value into the specified type and copies it into the provided memory
+// Needs to handle all canonical types
+#define GET_VALUE(value, type, resultPtr) \
+ switch (type) { \
+ case kCFNumberSInt8Type: *(int8_t *)(resultPtr) = (int8_t)value; break; \
+ case kCFNumberSInt16Type: *(int16_t *)(resultPtr) = (int16_t)value; break; \
+ case kCFNumberSInt32Type: *(SInt32 *)(resultPtr) = (SInt32)value; break; \
+ case kCFNumberSInt64Type: *(int64_t *)(resultPtr) = (int64_t)value; break; \
+ case kCFNumberFloat32Type: *(Float32 *)(resultPtr) = (Float32)value; break; \
+ case kCFNumberFloat64Type: *(Float64 *)(resultPtr) = (Float64)value; break; \
+ default: printf("*** WARNING: default case in GET_VALUE \n"); break; \
+ }
+
+// Extracts the stored type out of the union and copies it in the desired type into the provided memory
+// Needs to handle all storage types
+static void __CFNumberGetValue_old(const __CFNumberValue_old *value, CFNumberType numberType, CFNumberType typeToGet, void *valuePtr) {
+ switch (numberType) {
+ case kCFNumberSInt32Type: GET_VALUE(value->valSInt32, typeToGet, valuePtr); break;
+ case kCFNumberSInt64Type: GET_VALUE(value->valSInt64, typeToGet, valuePtr); break;
+ case kCFNumberFloat32Type: GET_VALUE(value->valFloat32, typeToGet, valuePtr); break;
+ case kCFNumberFloat64Type: GET_VALUE(value->valFloat64, typeToGet, valuePtr); break;
+ default: printf("*** WARNING: default case in __CFNumberGetValue_old \n"); break; \
+ }
+}
+
+// Sees if two value union structs have the same value (will do type conversion)
+static Boolean __CFNumberEqualValue_old(const __CFNumberValue_old *value1, CFNumberType type1, const __CFNumberValue_old *value2, CFNumberType type2) {
+ if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) {
+ Float64 d1, d2;
+ __CFNumberGetValue_old(value1, type1, kCFNumberFloat64Type, &d1);
+ __CFNumberGetValue_old(value2, type2, kCFNumberFloat64Type, &d2);
+ if (isnan(d1) && isnan(d2)) return true; // Not mathematically sound, but required
+ return d1 == d2;
+ } else {
+ int64_t i1, i2;
+ __CFNumberGetValue_old(value1, type1, kCFNumberSInt64Type, &i1);
+ __CFNumberGetValue_old(value2, type2, kCFNumberSInt64Type, &i2);
+ return i1 == i2;
+ }
+}
+
+static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2) {
+ struct __CFNumber_old * number1 = (struct __CFNumber_old *)cf1;
+ struct __CFNumber_old * number2 = (struct __CFNumber_old *)cf2;
+ return __CFNumberEqualValue_old(&(number1->value), __CFNumberGetType_old(number1), &(number2->value), __CFNumberGetType_old(number2));
+}
+
+static CFHashCode __CFNumberHash_old(CFTypeRef cf) {
+ struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
+ switch (__CFNumberGetType_old((struct __CFNumber_old *)cf)) {
+ case kCFNumberSInt32Type: return _CFHashInt(number->value.valSInt32);
+ case kCFNumberSInt64Type: return _CFHashDouble((double)(number->value.valSInt64));
+ case kCFNumberFloat32Type: return _CFHashDouble((double)(number->value.valFloat32));
+ case kCFNumberFloat64Type: return _CFHashDouble((double)(number->value.valFloat64));
+ default: printf("*** WARNING default case in __CFNumberHash_old\n");
+ return 0;
+ }
+}
+
+#define BUFFER_SIZE 100
+#define emitChar(ch) \
+ {if (buf - stackBuf == BUFFER_SIZE) {CFStringAppendCharacters(mstr, stackBuf, BUFFER_SIZE); buf = stackBuf;} *buf++ = ch;}
+
+static void __CFNumberEmitInt64_old(CFMutableStringRef mstr, int64_t value, int32_t width, UniChar pad, bool explicitPlus) {
+ UniChar stackBuf[BUFFER_SIZE], *buf = stackBuf;
+ uint64_t uvalue, factor, tmp;
+ int32_t w;
+ bool neg;
+
+ neg = (value < 0) ? true : false;
+ uvalue = (neg) ? -value : value;
+ if (neg || explicitPlus) width--;
+ width--;
+ factor = 1;
+ tmp = uvalue;
+ while (9 < tmp) {
+ width--;
+ factor *= 10;
+ tmp /= 10;
+ }
+ for (w = 0; w < width; w++) emitChar(pad);
+ if (neg) {
+ emitChar('-');
+ } else if (explicitPlus) {
+ emitChar('+');
+ }
+ while (0 < factor) {
+ UniChar ch = '0' + (UniChar)(uvalue / factor);
+ uvalue %= factor;
+ emitChar(ch);
+ factor /= 10;
+ }
+ if (buf > stackBuf) CFStringAppendCharacters(mstr, stackBuf, buf - stackBuf);
+}
+
+static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf) {
+ struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
+ CFMutableStringRef mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
+ CFStringAppendFormat(mstr, NULL, CFSTR("<CFNumber %p [%p]>{value = "), cf, CFGetAllocator(cf));
+ switch (__CFNumberGetType_old(number)) {
+ case kCFNumberSInt32Type:
+ __CFNumberEmitInt64_old(mstr, number->value.valSInt32, 0, ' ', true);
+ CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt32Type}"));
+ break;
+ case kCFNumberSInt64Type:
+ __CFNumberEmitInt64_old(mstr, number->value.valSInt64, 0, ' ', true);
+ CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt64Type}"));
+ break;
+ case kCFNumberFloat32Type:
+ // debugging formatting is intentionally more verbose and explicit about the value of the number
+ if (isnan(number->value.valFloat32)) {
+ CFStringAppend(mstr, CFSTR("nan"));
+ } else if (isinf(number->value.valFloat32)) {
+ CFStringAppend(mstr, (0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity"));
+ } else if (0.0f == number->value.valFloat32) {
+ CFStringAppend(mstr, (copysign(1.0, number->value.valFloat32) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0"));
+ } else {
+ CFStringAppendFormat(mstr, NULL, CFSTR("%+.10f"), number->value.valFloat32);
+ }
+ CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat32Type}"));
+ break;
+ case kCFNumberFloat64Type:
+ // debugging formatting is intentionally more verbose and explicit about the value of the number
+ if (isnan(number->value.valFloat64)) {
+ CFStringAppend(mstr, CFSTR("nan"));
+ } else if (isinf(number->value.valFloat64)) {
+ CFStringAppend(mstr, (0.0 < number->value.valFloat64) ? CFSTR("+infinity") : CFSTR("-infinity"));
+ } else if (0.0 == number->value.valFloat64) {
+ CFStringAppend(mstr, (copysign(1.0, number->value.valFloat64) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0"));
+ } else {
+ CFStringAppendFormat(mstr, NULL, CFSTR("%+.20f"), number->value.valFloat64);
+ }
+ CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat64Type}"));
+ break;
+ default:
+ CFRelease(mstr);
+ return NULL;
+ }
+ return mstr;
+}
+
+// This function separated out from __CFNumberCopyFormattingDescription() so the plist creation can use it as well.
+
+__private_extern__ CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf) {
+ double d;
+ CFNumberGetValue_old((struct __CFNumber_old *)cf, kCFNumberFloat64Type, &d);
+ if (isnan(d)) {
+ return (CFStringRef)CFRetain(CFSTR("nan"));
+ }
+ if (isinf(d)) {
+ return (CFStringRef)CFRetain((0.0 < d) ? CFSTR("+infinity") : CFSTR("-infinity"));
+ }
+ if (0.0 == d) {
+ return (CFStringRef)CFRetain(CFSTR("0.0"));
+ }
+ // if %g is used here, need to use DBL_DIG + 2 on Mac OS X, but %f needs +1
+ return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), DBL_DIG + 2, d);
+}
+
+static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions) {
+ struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
+ CFMutableStringRef mstr;
+ int64_t value;
+ switch (__CFNumberGetType_old(number)) {
+ case kCFNumberSInt32Type:
+ case kCFNumberSInt64Type:
+ value = (__CFNumberGetType_old(number) == kCFNumberSInt32Type) ? number->value.valSInt32 : number->value.valSInt64;
+ mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
+ __CFNumberEmitInt64_old(mstr, value, 0, ' ', false);
+ return mstr;
+ case kCFNumberFloat32Type:
+ if (isnan(number->value.valFloat32)) {
+ return (CFStringRef)CFRetain(CFSTR("nan"));
+ }
+ if (isinf(number->value.valFloat32)) {
+ return (CFStringRef)CFRetain((0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity"));
+ }
+ if (0.0f == number->value.valFloat32) {
+ return (CFStringRef)CFRetain(CFSTR("0.0"));
+ }
+ // if %g is used here, need to use FLT_DIG + 2 on Mac OS X, but %f needs +1
+ return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), FLT_DIG + 2, number->value.valFloat32);
+ case kCFNumberFloat64Type:
+ return __CFNumberCopyFormattingDescriptionAsFloat64_old(number);
+ break;
+ default:
+ return NULL;
+ }
+}
+
+
+
+static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) {
+ struct __CFNumber_old * num;
+ CFNumberType equivType, storageType;
+
+if (type == 17) {
+CFSInt128Struct *s = valuePtr;
+s->high = (int64_t)s->low;
+type = kCFNumberSInt64Type;
+}
+
+
+ equivType = __CFNumberGetCanonicalTypeForType_old(type);
+
+ storageType = __CFNumberGetStorageTypeForType_old(type);
+
+ num = (struct __CFNumber_old *)_CFRuntimeCreateInstance(allocator, __kCFNumberTypeID, __CFNumberSizeOfType_old(storageType), NULL);
+ if (NULL == num) {
+ return NULL;
+ }
+ SET_VALUE((__CFNumberValue_old *)&(num->value), equivType, valuePtr);
+ __CFBitfieldSetValue(((struct __CFNumber_old *)num)->_base._cfinfo[CF_INFO_BITS], 6, 0, (uint8_t)storageType);
+
+if (__CFNumberGetType_old(num) == 0) printf("*** ERROR: new number %p type is 0 (%d)\n", num, storageType);
+ return num;
+}
+
+static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number) {
+
+ return __CFNumberGetType_old(number);
+}
+
+static CFIndex CFNumberGetByteSize_old(struct __CFNumber_old * number) {
+ return __CFNumberSizeOfType_old(CFNumberGetType_old(number));
+}
+
+static Boolean CFNumberIsFloatType_old(struct __CFNumber_old * number) {
+ return __CFNumberTypeIsFloat_old(CFNumberGetType_old(number));
+}
+
+static Boolean CFNumberGetValue_old(struct __CFNumber_old * number, CFNumberType type, void *valuePtr) {
+ uint8_t localMemory[sizeof(__CFNumberValue_old)];
+ __CFNumberValue_old localValue;
+ CFNumberType numType;
+ CFNumberType storageTypeForType;
+
+if (type == 17) type = kCFNumberSInt64Type;
+
+ storageTypeForType = __CFNumberGetStorageTypeForType_old(type);
+ type = __CFNumberGetCanonicalTypeForType_old(type);
+ if (!valuePtr) valuePtr = &localMemory;
+
+ numType = __CFNumberGetType_old(number);
+ __CFNumberGetValue_old((__CFNumberValue_old *)&(number->value), numType, type, valuePtr);
+
+ // If the types match, then we're fine!
+ if (numType == storageTypeForType) return true;
+
+ // Test to see if the returned value is intact...
+ SET_VALUE(&localValue, type, valuePtr);
+ return __CFNumberEqualValue_old(&localValue, storageTypeForType, &(number->value), numType);
+}
+
+static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, struct __CFNumber_old * number2, void *context) {
+ CFNumberType type1, type2;
+
+
+ type1 = __CFNumberGetType_old(number1);
+ type2 = __CFNumberGetType_old(number2);
+
+ if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) {
+ Float64 d1, d2;
+ double s1, s2;
+ __CFNumberGetValue_old(&(number1->value), type1, kCFNumberFloat64Type, &d1);
+ __CFNumberGetValue_old(&(number2->value), type2, kCFNumberFloat64Type, &d2);
+ s1 = copysign(1.0, d1);
+ s2 = copysign(1.0, d2);
+ if (isnan(d1) && isnan(d2)) return kCFCompareEqualTo;
+ if (isnan(d1)) return (s2 < 0.0) ? kCFCompareGreaterThan : kCFCompareLessThan;
+ if (isnan(d2)) return (s1 < 0.0) ? kCFCompareLessThan : kCFCompareGreaterThan;
+ // at this point, we know we don't have any NaNs
+ if (s1 < s2) return kCFCompareLessThan;
+ if (s2 < s1) return kCFCompareGreaterThan;
+ // at this point, we know the signs are the same; do not combine these tests
+ if (d1 < d2) return kCFCompareLessThan;
+ if (d2 < d1) return kCFCompareGreaterThan;
+ return kCFCompareEqualTo;
+ } else {
+ int64_t i1, i2;
+ __CFNumberGetValue_old(&(number1->value), type1, kCFNumberSInt64Type, &i1);
+ __CFNumberGetValue_old(&(number2->value), type2, kCFNumberSInt64Type, &i2);
+ return (i1 > i2) ? kCFCompareGreaterThan : ((i1 < i2) ? kCFCompareLessThan : kCFCompareEqualTo);
+ }
+}
+
+#endif
+
+