/ CFNumber.c
CFNumber.c
   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  /*	CFNumber.c
  25  	Copyright (c) 1999-2014, Apple Inc. All rights reserved.
  26  	Responsibility: Ali Ozer
  27  */
  28  
  29  #include <CoreFoundation/CFNumber.h>
  30  #include "CFInternal.h"
  31  #include <CoreFoundation/CFPriv.h>
  32  #include <math.h>
  33  #include <float.h>
  34  
  35  
  36  #if DEPLOYMENT_TARGET_WINDOWS
  37  #define isnan(A) _isnan(A)
  38  #define isinf(A) !_finite(A)
  39  #define copysign(A, B) _copysign(A, B)
  40  #endif
  41  
  42  #define __CFAssertIsBoolean(cf) __CFGenericValidateType(cf, CFBooleanGetTypeID())
  43  
  44  struct __CFBoolean {
  45      CFRuntimeBase _base;
  46  };
  47  
  48  struct __CFBoolean __kCFBooleanTrue = {
  49      INIT_CFRUNTIME_BASE()
  50  };
  51  const CFBooleanRef kCFBooleanTrue = &__kCFBooleanTrue;
  52  
  53  struct __CFBoolean __kCFBooleanFalse = {
  54      INIT_CFRUNTIME_BASE()
  55  };
  56  const CFBooleanRef kCFBooleanFalse = &__kCFBooleanFalse;
  57  
  58  static CFStringRef __CFBooleanCopyDescription(CFTypeRef cf) {
  59      CFBooleanRef boolean = (CFBooleanRef)cf;
  60      return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFBoolean %p [%p]>{value = %s}"), cf, CFGetAllocator(cf), (boolean == kCFBooleanTrue) ? "true" : "false");
  61  }
  62  
  63  CF_PRIVATE CFStringRef __CFBooleanCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
  64      CFBooleanRef boolean = (CFBooleanRef)cf;
  65      return (CFStringRef)CFRetain((boolean == kCFBooleanTrue) ? CFSTR("true") : CFSTR("false"));
  66  }
  67  
  68  static CFHashCode __CFBooleanHash(CFTypeRef cf) {
  69      CFBooleanRef boolean = (CFBooleanRef)cf;
  70      return (boolean == kCFBooleanTrue) ? _CFHashInt(1) : _CFHashInt(0);
  71  }
  72  
  73  static void __CFBooleanDeallocate(CFTypeRef cf) {
  74      CFAssert(false, __kCFLogAssertion, "Deallocated CFBoolean!");
  75  }
  76  
  77  static CFTypeID __kCFBooleanTypeID = _kCFRuntimeNotATypeID;
  78  
  79  static const CFRuntimeClass __CFBooleanClass = {
  80      0,
  81      "CFBoolean",
  82      NULL,      // init
  83      NULL,      // copy
  84      __CFBooleanDeallocate,
  85      NULL,
  86      __CFBooleanHash,
  87      __CFBooleanCopyFormattingDescription,
  88      __CFBooleanCopyDescription
  89  };
  90  
  91  CFTypeID CFBooleanGetTypeID(void) {
  92      static dispatch_once_t initOnce;
  93      dispatch_once(&initOnce, ^{
  94          __kCFBooleanTypeID = _CFRuntimeRegisterClass(&__CFBooleanClass); // initOnce covered
  95          _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanTrue, __kCFBooleanTypeID);
  96          _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFBooleanFalse, __kCFBooleanTypeID);
  97      });
  98      return __kCFBooleanTypeID;
  99  }
 100  
 101  Boolean CFBooleanGetValue(CFBooleanRef boolean) {
 102      CF_OBJC_FUNCDISPATCHV(CFBooleanGetTypeID(), Boolean, (NSNumber *)boolean, boolValue);
 103      return (boolean == kCFBooleanTrue) ? true : false;
 104  }
 105  
 106  
 107  /*** CFNumber ***/
 108  
 109  #define OLD_CRAP_TOO 0
 110  
 111  #if OLD_CRAP_TOO
 112  
 113  // old implementation, for runtime comparison purposes
 114  
 115  typedef union {
 116      SInt32 valSInt32;
 117      int64_t valSInt64;
 118      Float32 valFloat32;
 119      Float64 valFloat64;
 120  } __CFNumberValue_old;
 121  
 122  struct __CFNumber_old {             /* Only as many bytes as necessary are allocated */
 123      CFRuntimeBase _base;
 124      __CFNumberValue_old value;
 125  };
 126  
 127  static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2);
 128  static CFHashCode __CFNumberHash_old(CFTypeRef cf);
 129  static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf);
 130  CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf);
 131  static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions);
 132  static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr);
 133  static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number);
 134  static CFIndex CFNumberGetByteSize_old(struct __CFNumber_old * number);
 135  static Boolean CFNumberIsFloatType_old(struct __CFNumber_old * number);
 136  static Boolean CFNumberGetValue_old(struct __CFNumber_old * number, CFNumberType type, void *valuePtr);
 137  static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, struct __CFNumber_old * number2, void *context);
 138  
 139  #endif
 140  
 141  
 142  #define __CFAssertIsNumber(cf) __CFGenericValidateType(cf, CFNumberGetTypeID())
 143  #define __CFAssertIsValidNumberType(type) CFAssert2((0 < type && type <= kCFNumberMaxType) || (type == kCFNumberSInt128Type), __kCFLogAssertion, "%s(): bad CFNumber type %d", __PRETTY_FUNCTION__, type);
 144  
 145  /* The IEEE bit patterns... Also have:
 146  0x7f800000		float +Inf
 147  0x7fc00000		float NaN
 148  0xff800000		float -Inf
 149  */
 150  #define BITSFORDOUBLENAN	((uint64_t)0x7ff8000000000000ULL)
 151  #define BITSFORDOUBLEPOSINF	((uint64_t)0x7ff0000000000000ULL)
 152  #define BITSFORDOUBLENEGINF	((uint64_t)0xfff0000000000000ULL)
 153  
 154  #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI || DEPLOYMENT_TARGET_LINUX
 155  #define FLOAT_POSITIVE_2_TO_THE_64	0x1.0p+64L
 156  #define FLOAT_NEGATIVE_2_TO_THE_127	-0x1.0p+127L
 157  #define FLOAT_POSITIVE_2_TO_THE_127	0x1.0p+127L
 158  #elif DEPLOYMENT_TARGET_WINDOWS
 159  #define FLOAT_POSITIVE_2_TO_THE_64	18446744073709551616.0
 160  #define FLOAT_NEGATIVE_2_TO_THE_127	-170141183460469231731687303715884105728.0
 161  #define FLOAT_POSITIVE_2_TO_THE_127	170141183460469231731687303715884105728.0
 162  #else
 163  #error Unknown or unspecified DEPLOYMENT_TARGET
 164  #endif
 165  
 166  typedef struct {	// NOTE WELL: these two fields may switch position someday, do not use '= {high, low}' -style initialization
 167      int64_t high;
 168      uint64_t low;
 169  } CFSInt128Struct;
 170  
 171  enum {
 172      kCFNumberSInt128Type = 17
 173  };
 174  
 175  static uint8_t isNeg128(const CFSInt128Struct *in) {
 176      return in->high < 0;
 177  }
 178  
 179  static CFComparisonResult cmp128(const CFSInt128Struct *in1, const CFSInt128Struct *in2) {
 180      if (in1->high < in2->high) return kCFCompareLessThan;
 181      if (in1->high > in2->high) return kCFCompareGreaterThan;
 182      if (in1->low < in2->low) return kCFCompareLessThan;
 183      if (in1->low > in2->low) return kCFCompareGreaterThan;
 184      return kCFCompareEqualTo;
 185  }
 186  
 187  // allows out to be the same as in1 or in2
 188  static void add128(CFSInt128Struct *out, CFSInt128Struct *in1, CFSInt128Struct *in2) {
 189      CFSInt128Struct tmp;
 190      tmp.low = in1->low + in2->low;
 191      tmp.high = in1->high + in2->high;
 192      if (UINT64_MAX - in1->low < in2->low) {
 193          tmp.high++;
 194      }
 195      *out = tmp;
 196  }
 197  
 198  // allows out to be the same as in
 199  static void neg128(CFSInt128Struct *out, CFSInt128Struct *in) {
 200      uint64_t tmplow = ~in->low;
 201      out->low = tmplow + 1;
 202      out->high = ~in->high;
 203      if (UINT64_MAX == tmplow) {
 204  	out->high++;
 205      }
 206  }
 207  
 208  static const CFSInt128Struct powersOf10[] = {
 209      { 0x4B3B4CA85A86C47ALL, 0x098A224000000000ULL },
 210      { 0x0785EE10D5DA46D9LL, 0x00F436A000000000ULL },
 211      { 0x00C097CE7BC90715LL, 0xB34B9F1000000000ULL },
 212      { 0x0013426172C74D82LL, 0x2B878FE800000000ULL },
 213      { 0x0001ED09BEAD87C0LL, 0x378D8E6400000000ULL },
 214      { 0x0000314DC6448D93LL, 0x38C15B0A00000000ULL },
 215      { 0x000004EE2D6D415BLL, 0x85ACEF8100000000ULL },
 216      { 0x0000007E37BE2022LL, 0xC0914B2680000000ULL },
 217      { 0x0000000C9F2C9CD0LL, 0x4674EDEA40000000ULL },
 218      { 0x00000001431E0FAELL, 0x6D7217CAA0000000ULL },
 219      { 0x00000000204FCE5ELL, 0x3E25026110000000ULL },
 220      { 0x00000000033B2E3CLL, 0x9FD0803CE8000000ULL },
 221      { 0x000000000052B7D2LL, 0xDCC80CD2E4000000ULL },
 222      { 0x0000000000084595LL, 0x161401484A000000ULL },
 223      { 0x000000000000D3C2LL, 0x1BCECCEDA1000000ULL },
 224      { 0x000000000000152DLL, 0x02C7E14AF6800000ULL },
 225      { 0x000000000000021ELL, 0x19E0C9BAB2400000ULL },
 226      { 0x0000000000000036LL, 0x35C9ADC5DEA00000ULL },
 227      { 0x0000000000000005LL, 0x6BC75E2D63100000ULL },
 228      { 0x0000000000000000LL, 0x8AC7230489E80000ULL },
 229      { 0x0000000000000000LL, 0x0DE0B6B3A7640000ULL },
 230      { 0x0000000000000000LL, 0x016345785D8A0000ULL },
 231      { 0x0000000000000000LL, 0x002386F26FC10000ULL },
 232      { 0x0000000000000000LL, 0x00038D7EA4C68000ULL },
 233      { 0x0000000000000000LL, 0x00005AF3107A4000ULL },
 234      { 0x0000000000000000LL, 0x000009184E72A000ULL },
 235      { 0x0000000000000000LL, 0x000000E8D4A51000ULL },
 236      { 0x0000000000000000LL, 0x000000174876E800ULL },
 237      { 0x0000000000000000LL, 0x00000002540BE400ULL },
 238      { 0x0000000000000000LL, 0x000000003B9ACA00ULL },
 239      { 0x0000000000000000LL, 0x0000000005F5E100ULL },
 240      { 0x0000000000000000LL, 0x0000000000989680ULL },
 241      { 0x0000000000000000LL, 0x00000000000F4240ULL },
 242      { 0x0000000000000000LL, 0x00000000000186A0ULL },
 243      { 0x0000000000000000LL, 0x0000000000002710ULL },
 244      { 0x0000000000000000LL, 0x00000000000003E8ULL },
 245      { 0x0000000000000000LL, 0x0000000000000064ULL },
 246      { 0x0000000000000000LL, 0x000000000000000AULL },
 247      { 0x0000000000000000LL, 0x0000000000000001ULL },
 248  };
 249  
 250  static const CFSInt128Struct neg_powersOf10[] = {
 251      { 0xB4C4B357A5793B85LL, 0xF675DDC000000000ULL },
 252      { 0xF87A11EF2A25B926LL, 0xFF0BC96000000000ULL },
 253      { 0xFF3F68318436F8EALL, 0x4CB460F000000000ULL },
 254      { 0xFFECBD9E8D38B27DLL, 0xD478701800000000ULL },
 255      { 0xFFFE12F64152783FLL, 0xC872719C00000000ULL },
 256      { 0xFFFFCEB239BB726CLL, 0xC73EA4F600000000ULL },
 257      { 0xFFFFFB11D292BEA4LL, 0x7A53107F00000000ULL },
 258      { 0xFFFFFF81C841DFDDLL, 0x3F6EB4D980000000ULL },
 259      { 0xFFFFFFF360D3632FLL, 0xB98B1215C0000000ULL },
 260      { 0xFFFFFFFEBCE1F051LL, 0x928DE83560000000ULL },
 261      { 0xFFFFFFFFDFB031A1LL, 0xC1DAFD9EF0000000ULL },
 262      { 0xFFFFFFFFFCC4D1C3LL, 0x602F7FC318000000ULL },
 263      { 0xFFFFFFFFFFAD482DLL, 0x2337F32D1C000000ULL },
 264      { 0xFFFFFFFFFFF7BA6ALL, 0xE9EBFEB7B6000000ULL },
 265      { 0xFFFFFFFFFFFF2C3DLL, 0xE43133125F000000ULL },
 266      { 0xFFFFFFFFFFFFEAD2LL, 0xFD381EB509800000ULL },
 267      { 0xFFFFFFFFFFFFFDE1LL, 0xE61F36454DC00000ULL },
 268      { 0xFFFFFFFFFFFFFFC9LL, 0xCA36523A21600000ULL },
 269      { 0xFFFFFFFFFFFFFFFALL, 0x9438A1D29CF00000ULL },
 270      { 0xFFFFFFFFFFFFFFFFLL, 0x7538DCFB76180000ULL },
 271      { 0xFFFFFFFFFFFFFFFFLL, 0xF21F494C589C0000ULL },
 272      { 0xFFFFFFFFFFFFFFFFLL, 0xFE9CBA87A2760000ULL },
 273      { 0xFFFFFFFFFFFFFFFFLL, 0xFFDC790D903F0000ULL },
 274      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFC72815B398000ULL },
 275      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFA50CEF85C000ULL },
 276      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFF6E7B18D6000ULL },
 277      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFF172B5AF000ULL },
 278      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFE8B7891800ULL },
 279      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFDABF41C00ULL },
 280      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFC4653600ULL },
 281      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFA0A1F00ULL },
 282      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFF676980ULL },
 283      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFF0BDC0ULL },
 284      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFE7960ULL },
 285      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFD8F0ULL },
 286      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFC18ULL },
 287      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFF9CULL },
 288      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFF6ULL },
 289      { 0xFFFFFFFFFFFFFFFFLL, 0xFFFFFFFFFFFFFFFFULL },
 290  };
 291  
 292  static void emit128(char *buffer, const CFSInt128Struct *in, Boolean forcePlus) {
 293      CFSInt128Struct tmp = *in;
 294      if (isNeg128(&tmp)) {
 295  	neg128(&tmp, &tmp);
 296  	*buffer++ = '-';
 297      } else if (forcePlus) {
 298  	*buffer++ = '+';
 299      }
 300      Boolean doneOne = false;
 301      int idx;
 302      for (idx = 0; idx < sizeof(powersOf10) / sizeof(powersOf10[0]); idx++) {
 303  	int count = 0;
 304          while (cmp128(&powersOf10[idx], &tmp) <= 0) {
 305  	    add128(&tmp, &tmp, (CFSInt128Struct *)&neg_powersOf10[idx]);
 306  	    count++;
 307  	}
 308  	if (0 != count || doneOne) {
 309  	    *buffer++ = '0' + count;
 310  	    doneOne = true;
 311  	}
 312      }
 313      if (!doneOne) {
 314  	*buffer++ = '0';
 315      }
 316      *buffer = '\0';
 317  }
 318  
 319  static void cvtSInt128ToFloat64(Float64 *out, const CFSInt128Struct *in) {
 320      // switching to a positive number results in better accuracy
 321      // for negative numbers close to zero, because the multiply
 322      // of -1 by 2^64 (scaling the Float64 high) is avoided
 323      Boolean wasNeg = false;
 324      CFSInt128Struct tmp = *in;
 325      if (isNeg128(&tmp)) {
 326  	neg128(&tmp, &tmp);
 327  	wasNeg = true;
 328      }
 329      Float64 d = (Float64)tmp.high * FLOAT_POSITIVE_2_TO_THE_64 + (Float64)tmp.low;
 330      if (wasNeg) d = -d;
 331      *out = d;
 332  }
 333  
 334  static void cvtFloat64ToSInt128(CFSInt128Struct *out, const Float64 *in) {
 335      CFSInt128Struct i;
 336      Float64 d = *in;
 337      if (d < FLOAT_NEGATIVE_2_TO_THE_127) {
 338  	i.high = 0x8000000000000000LL;
 339  	i.low = 0x0000000000000000ULL;
 340  	*out = i;
 341  	return;
 342      }
 343      if (FLOAT_POSITIVE_2_TO_THE_127<= d) {
 344  	i.high = 0x7fffffffffffffffLL;
 345  	i.low = 0xffffffffffffffffULL;
 346  	*out = i;
 347  	return;
 348      }
 349      Float64 t = floor(d / FLOAT_POSITIVE_2_TO_THE_64);
 350      i.high = (int64_t)t;
 351      i.low = (uint64_t)(d - t * FLOAT_POSITIVE_2_TO_THE_64);
 352      *out = i;
 353  }
 354  
 355  struct __CFNumber {
 356      CFRuntimeBase _base;
 357  #if OLD_CRAP_TOO
 358      struct __CFNumber_old *__old__;
 359      void * __dummy__;
 360  #endif
 361      uint64_t _pad; // need this space here for the constant objects
 362      /* 0 or 8 more bytes allocated here */
 363  };
 364  
 365  /* Seven bits in base:
 366      Bits 6..5: unused
 367      Bits 4..0: CFNumber type
 368  */
 369  
 370  static struct __CFNumber __kCFNumberNaN = {
 371      INIT_CFRUNTIME_BASE(), 0ULL
 372  };
 373  const CFNumberRef kCFNumberNaN = &__kCFNumberNaN;
 374  
 375  static struct __CFNumber __kCFNumberNegativeInfinity = {
 376      INIT_CFRUNTIME_BASE(), 0ULL
 377  };
 378  const CFNumberRef kCFNumberNegativeInfinity = &__kCFNumberNegativeInfinity;
 379  
 380  static struct __CFNumber __kCFNumberPositiveInfinity = {
 381      INIT_CFRUNTIME_BASE(), 0ULL
 382  };
 383  const CFNumberRef kCFNumberPositiveInfinity = &__kCFNumberPositiveInfinity;
 384  
 385  static const struct {
 386      uint16_t canonicalType:5;	// canonical fixed-width type
 387      uint16_t floatBit:1;	// is float
 388      uint16_t storageBit:1;	// storage size (0: (float ? 4 : 8), 1: (float ? 8 : 16) bits)
 389      uint16_t lgByteSize:3;	// base-2 log byte size of public type
 390      uint16_t unused:6;
 391  } __CFNumberTypeTable[] = {
 392      /* 0 */			{0, 0, 0, 0},
 393  
 394      /* kCFNumberSInt8Type */	{kCFNumberSInt8Type, 0, 0, 0, 0},
 395      /* kCFNumberSInt16Type */	{kCFNumberSInt16Type, 0, 0, 1, 0},
 396      /* kCFNumberSInt32Type */	{kCFNumberSInt32Type, 0, 0, 2, 0},
 397      /* kCFNumberSInt64Type */	{kCFNumberSInt64Type, 0, 0, 3, 0},
 398      /* kCFNumberFloat32Type */	{kCFNumberFloat32Type, 1, 0, 2, 0},
 399      /* kCFNumberFloat64Type */	{kCFNumberFloat64Type, 1, 1, 3, 0},
 400  
 401      /* kCFNumberCharType */	{kCFNumberSInt8Type, 0, 0, 0, 0},
 402      /* kCFNumberShortType */	{kCFNumberSInt16Type, 0, 0, 1, 0},
 403      /* kCFNumberIntType */	{kCFNumberSInt32Type, 0, 0, 2, 0},
 404  #if __LP64__
 405      /* kCFNumberLongType */	{kCFNumberSInt64Type, 0, 0, 3, 0},
 406  #else
 407      /* kCFNumberLongType */	{kCFNumberSInt32Type, 0, 0, 2, 0},
 408  #endif
 409      /* kCFNumberLongLongType */	{kCFNumberSInt64Type, 0, 0, 3, 0},
 410      /* kCFNumberFloatType */	{kCFNumberFloat32Type, 1, 0, 2, 0},
 411      /* kCFNumberDoubleType */	{kCFNumberFloat64Type, 1, 1, 3, 0},
 412  
 413  #if __LP64__
 414      /* kCFNumberCFIndexType */	{kCFNumberSInt64Type, 0, 0, 3, 0},
 415      /* kCFNumberNSIntegerType */ {kCFNumberSInt64Type, 0, 0, 3, 0},
 416      /* kCFNumberCGFloatType */	{kCFNumberFloat64Type, 1, 1, 3, 0},
 417  #else
 418      /* kCFNumberCFIndexType */	{kCFNumberSInt32Type, 0, 0, 2, 0},
 419      /* kCFNumberNSIntegerType */ {kCFNumberSInt32Type, 0, 0, 2, 0},
 420      /* kCFNumberCGFloatType */	{kCFNumberFloat32Type, 1, 0, 2, 0},
 421  #endif
 422  
 423      /* kCFNumberSInt128Type */	{kCFNumberSInt128Type, 0, 1, 4, 0},
 424  };
 425  
 426  CF_INLINE CFNumberType __CFNumberGetType(CFNumberRef num) {
 427      return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0);
 428  }
 429  
 430  #define CVT(SRC_TYPE, DST_TYPE, DST_MIN, DST_MAX) do { \
 431  	SRC_TYPE sv; memmove(&sv, data, sizeof(SRC_TYPE)); \
 432  	DST_TYPE dv = (sv < DST_MIN) ? (DST_TYPE)DST_MIN : (DST_TYPE)(((DST_MAX < sv) ? DST_MAX : sv)); \
 433  	memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
 434  	SRC_TYPE vv = (SRC_TYPE)dv; return (vv == sv); \
 435  	} while (0)
 436  
 437  #define CVT128ToInt(SRC_TYPE, DST_TYPE, DST_MIN, DST_MAX) do { \
 438          SRC_TYPE sv; memmove(&sv, data, sizeof(SRC_TYPE)); \
 439  	DST_TYPE dv; Boolean noLoss = false; \
 440  	if (0 < sv.high || (0 == sv.high && (int64_t)DST_MAX < sv.low)) { \
 441  	    dv = DST_MAX; \
 442  	} else if (sv.high < -1 || (-1 == sv.high && sv.low < (int64_t)DST_MIN)) { \
 443  	    dv = DST_MIN; \
 444  	} else { \
 445  	    dv = (DST_TYPE)sv.low; \
 446  	    noLoss = true; \
 447  	} \
 448          memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
 449          return noLoss; \
 450          } while (0)
 451  
 452  // returns false if the output value is not the same as the number's value, which
 453  // can occur due to accuracy loss and the value not being within the target range
 454  static Boolean __CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) {
 455      type = __CFNumberTypeTable[type].canonicalType;
 456      CFNumberType ntype = __CFNumberGetType(number);
 457      const void *data = &(number->_pad);
 458      switch (type) {
 459      case kCFNumberSInt8Type:
 460  	if (__CFNumberTypeTable[ntype].floatBit) {
 461  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 462  		CVT(Float32, int8_t, INT8_MIN, INT8_MAX);
 463  	    } else {
 464  		CVT(Float64, int8_t, INT8_MIN, INT8_MAX);
 465  	    }
 466  	} else {
 467  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 468  		CVT(int64_t, int8_t, INT8_MIN, INT8_MAX);
 469  	    } else {
 470  		CVT128ToInt(CFSInt128Struct, int8_t, INT8_MIN, INT8_MAX);
 471  	    }
 472  	}
 473  	return true;
 474      case kCFNumberSInt16Type:
 475  	if (__CFNumberTypeTable[ntype].floatBit) {
 476  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 477                  CVT(Float32, int16_t, INT16_MIN, INT16_MAX);
 478  	    } else {
 479                  CVT(Float64, int16_t, INT16_MIN, INT16_MAX);
 480  	    }
 481  	} else {
 482  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 483                  CVT(int64_t, int16_t, INT16_MIN, INT16_MAX);
 484  	    } else {
 485  		CVT128ToInt(CFSInt128Struct, int16_t, INT16_MIN, INT16_MAX);
 486  	    }
 487  	}
 488  	return true;
 489      case kCFNumberSInt32Type:
 490  	if (__CFNumberTypeTable[ntype].floatBit) {
 491  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 492                  CVT(Float32, int32_t, INT32_MIN, INT32_MAX);
 493  	    } else {
 494                  CVT(Float64, int32_t, INT32_MIN, INT32_MAX);
 495  	    }
 496  	} else {
 497  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 498                  CVT(int64_t, int32_t, INT32_MIN, INT32_MAX);
 499  	    } else {
 500  		CVT128ToInt(CFSInt128Struct, int32_t, INT32_MIN, INT32_MAX);
 501  	    }
 502  	}
 503  	return true;
 504      case kCFNumberSInt64Type:
 505  	if (__CFNumberTypeTable[ntype].floatBit) {
 506  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 507                  CVT(Float32, int64_t, INT64_MIN, INT64_MAX);
 508  	    } else {
 509                  CVT(Float64, int64_t, INT64_MIN, INT64_MAX);
 510  	    }
 511  	} else {
 512  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 513  		memmove(valuePtr, data, 8);
 514  	    } else {
 515  		CVT128ToInt(CFSInt128Struct, int64_t, INT64_MIN, INT64_MAX);
 516  	    }
 517  	}
 518  	return true;
 519      case kCFNumberSInt128Type:
 520  	if (__CFNumberTypeTable[ntype].floatBit) {
 521  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 522  		Float32 f;
 523  		memmove(&f, data, 4);
 524  		Float64 d = f;
 525  		CFSInt128Struct i;
 526  		cvtFloat64ToSInt128(&i, &d);
 527  		memmove(valuePtr, &i, 16);
 528  		Float64 d2;
 529  		cvtSInt128ToFloat64(&d2, &i);
 530  		Float32 f2 = (Float32)d2;
 531  		return (f2 == f);
 532  	    } else {
 533  		Float64 d;
 534  		memmove(&d, data, 8);
 535  		CFSInt128Struct i;
 536  		cvtFloat64ToSInt128(&i, &d);
 537  		memmove(valuePtr, &i, 16);
 538  		Float64 d2;
 539  		cvtSInt128ToFloat64(&d2, &i);
 540  		return (d2 == d);
 541  	    }
 542  	} else {
 543  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 544  		int64_t j;
 545  		memmove(&j, data, 8);
 546  		CFSInt128Struct i;
 547  		i.low = j;
 548  		i.high = (j < 0) ? -1LL : 0LL;
 549  		memmove(valuePtr, &i, 16);
 550  	    } else {
 551  		memmove(valuePtr, data, 16);
 552  	    }
 553  	}
 554  	return true;
 555      case kCFNumberFloat32Type:
 556  	if (__CFNumberTypeTable[ntype].floatBit) {
 557  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 558  		memmove(valuePtr, data, 4);
 559  	    } else {
 560  		double d;
 561  		memmove(&d, data, 8);
 562  		if (isnan(d)) {
 563  		    uint32_t l = 0x7fc00000;
 564  		    memmove(valuePtr, &l, 4);
 565  		    return true;
 566  		} else if (isinf(d)) {
 567  		    uint32_t l = 0x7f800000;
 568  		    if (d < 0.0) l += 0x80000000UL;
 569  		    memmove(valuePtr, &l, 4);
 570  		    return true;
 571  		}
 572  		CVT(Float64, Float32, -FLT_MAX, FLT_MAX);
 573  	    }
 574  	} else {
 575  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 576  		CVT(int64_t, Float32, -FLT_MAX, FLT_MAX);
 577  	    } else {
 578  		CFSInt128Struct i;
 579  		memmove(&i, data, 16);
 580  		Float64 d;
 581  		cvtSInt128ToFloat64(&d, &i);
 582  		Float32 f = (Float32)d;
 583  		memmove(valuePtr, &f, 4);
 584  		d = f;
 585  		CFSInt128Struct i2;
 586  		cvtFloat64ToSInt128(&i2, &d);
 587  		return cmp128(&i2, &i) == kCFCompareEqualTo;
 588  	    }
 589  	}
 590  	return true;
 591      case kCFNumberFloat64Type:
 592  	if (__CFNumberTypeTable[ntype].floatBit) {
 593  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 594  		float f;
 595  		memmove(&f, data, 4);
 596  		if (isnan(f)) {
 597  		    uint64_t l = BITSFORDOUBLENAN;
 598  		    memmove(valuePtr, &l, 8);
 599  		    return true;
 600  		} else if (isinf(f)) {
 601  		    uint64_t l = BITSFORDOUBLEPOSINF;
 602  		    if (f < 0.0) l += 0x8000000000000000ULL;
 603  		    memmove(valuePtr, &l, 8);
 604  		    return true;
 605  		}
 606  		CVT(Float32, Float64, -DBL_MAX, DBL_MAX);
 607  	    } else {
 608  		memmove(valuePtr, data, 8);
 609  	    }
 610  	} else {
 611  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 612  		CVT(int64_t, Float64, -DBL_MAX, DBL_MAX);
 613  	    } else {
 614                  CFSInt128Struct i;
 615                  memmove(&i, data, 16);
 616                  Float64 d;
 617                  cvtSInt128ToFloat64(&d, &i);
 618                  memmove(valuePtr, &d, 8);
 619                  CFSInt128Struct i2;
 620                  cvtFloat64ToSInt128(&i2, &d);
 621                  return cmp128(&i2, &i) == kCFCompareEqualTo;
 622  	    }
 623  	}
 624  	return true;
 625      }
 626      return false;
 627  }
 628  
 629  #define CVT_COMPAT(SRC_TYPE, DST_TYPE, FT) do { \
 630  	SRC_TYPE sv; memmove(&sv, data, sizeof(SRC_TYPE)); \
 631  	DST_TYPE dv = (DST_TYPE)(sv); \
 632  	memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
 633  	SRC_TYPE vv = (SRC_TYPE)dv; return (FT) || (vv == sv); \
 634  	} while (0)
 635  
 636  #define CVT128ToInt_COMPAT(SRC_TYPE, DST_TYPE) do { \
 637          SRC_TYPE sv; memmove(&sv, data, sizeof(SRC_TYPE)); \
 638  	DST_TYPE dv; dv = (DST_TYPE)sv.low; \
 639          memmove(valuePtr, &dv, sizeof(DST_TYPE)); \
 640  	uint64_t vv = (uint64_t)dv; return (vv == sv.low); \
 641          } while (0)
 642  
 643  // this has the old cast-style behavior
 644  static Boolean __CFNumberGetValueCompat(CFNumberRef number, CFNumberType type, void *valuePtr) {
 645      type = __CFNumberTypeTable[type].canonicalType;
 646      CFNumberType ntype = __CFNumberGetType(number);
 647      const void *data = &(number->_pad);
 648      switch (type) {
 649      case kCFNumberSInt8Type:
 650  	if (__CFNumberTypeTable[ntype].floatBit) {
 651  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 652  		CVT_COMPAT(Float32, int8_t, 0);
 653  	    } else {
 654  		CVT_COMPAT(Float64, int8_t, 0);
 655  	    }
 656  	} else {
 657  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 658  		// Leopard's implemenation of this always returned true. We should only return true when the conversion is lossless. However, there are some clients who use CFNumber with small unsigned values disguised as signed values. Since there is no CFNumber API yet for unsigned values, we need to accomodate those clients for now. <rdar://problem/6471866>
 659  		// This accomodation should be removed if CFNumber ever provides API for unsigned values. <rdar://problem/6473890>
 660  		int64_t sv; memmove(&sv, data, sizeof(int64_t));
 661  		int8_t dv = (int8_t)(sv);
 662  		memmove(valuePtr, &dv, sizeof(int8_t));
 663  		int64_t vv = (int64_t)dv; return !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard) || ((sv >> 8LL) == 0LL) || (vv == sv);
 664  	    } else {
 665  		CVT128ToInt_COMPAT(CFSInt128Struct, int8_t);
 666  	    }
 667  	}
 668  	return true;
 669      case kCFNumberSInt16Type:
 670  	if (__CFNumberTypeTable[ntype].floatBit) {
 671  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 672  		CVT_COMPAT(Float32, int16_t, 0);
 673  	    } else {
 674  		CVT_COMPAT(Float64, int16_t, 0);
 675  	    }
 676  	} else {
 677  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 678  		// Leopard's implemenation of this always returned true. We should only return true when the conversion is lossless. However, there are some clients who use CFNumber with small unsigned values disguised as signed values. Since there is no CFNumber API yet for unsigned values, we need to accomodate those clients for now. <rdar://problem/6471866>
 679  		// This accomodation should be removed if CFNumber ever provides API for unsigned values. <rdar://problem/6473890>
 680  		int64_t sv; memmove(&sv, data, sizeof(int64_t));
 681  		int16_t dv = (int16_t)(sv);
 682  		memmove(valuePtr, &dv, sizeof(int16_t));
 683  		int64_t vv = (int64_t)dv; return !_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard) || ((sv >> 16LL) == 0LL) || (vv == sv);
 684  	    } else {
 685  		CVT128ToInt_COMPAT(CFSInt128Struct, int16_t);
 686  	    }
 687  	}
 688  	return true;
 689      case kCFNumberSInt32Type:
 690  	if (__CFNumberTypeTable[ntype].floatBit) {
 691  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 692  		CVT_COMPAT(Float32, int32_t, 0);
 693  	    } else {
 694  		CVT_COMPAT(Float64, int32_t, 0);
 695  	    }
 696  	} else {
 697  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 698                  CVT_COMPAT(int64_t, int32_t, 0);
 699  	    } else {
 700  		CVT128ToInt_COMPAT(CFSInt128Struct, int32_t);
 701  	    }
 702  	}
 703  	return true;
 704      case kCFNumberSInt64Type:
 705  	if (__CFNumberTypeTable[ntype].floatBit) {
 706  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 707  		CVT_COMPAT(Float32, int64_t, 0);
 708  	    } else {
 709  		CVT_COMPAT(Float64, int64_t, 0);
 710  	    }
 711  	} else {
 712  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 713                  CVT_COMPAT(int64_t, int64_t, 0);
 714  	    } else {
 715  		CVT128ToInt_COMPAT(CFSInt128Struct, int64_t);
 716  	    }
 717  	}
 718  	return true;
 719      case kCFNumberSInt128Type:
 720  	if (__CFNumberTypeTable[ntype].floatBit) {
 721  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 722  		Float32 f;
 723  		memmove(&f, data, 4);
 724  		Float64 d = f;
 725  		CFSInt128Struct i;
 726  		cvtFloat64ToSInt128(&i, &d);
 727  		memmove(valuePtr, &i, 16);
 728  		Float64 d2;
 729  		cvtSInt128ToFloat64(&d2, &i);
 730  		Float32 f2 = (Float32)d2;
 731  		return (f2 == f);
 732  	    } else {
 733  		Float64 d;
 734  		memmove(&d, data, 8);
 735  		CFSInt128Struct i;
 736  		cvtFloat64ToSInt128(&i, &d);
 737  		memmove(valuePtr, &i, 16);
 738  		Float64 d2;
 739  		cvtSInt128ToFloat64(&d2, &i);
 740  		return (d2 == d);
 741  	    }
 742  	} else {
 743  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 744  		int64_t j;
 745  		memmove(&j, data, 8);
 746  		CFSInt128Struct i;
 747  		i.low = j;
 748  		i.high = (j < 0) ? -1LL : 0LL;
 749  		memmove(valuePtr, &i, 16);
 750  	    } else {
 751  		memmove(valuePtr, data, 16);
 752  	    }
 753  	}
 754  	return true;
 755      case kCFNumberFloat32Type:
 756  	if (__CFNumberTypeTable[ntype].floatBit) {
 757  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 758  		memmove(valuePtr, data, 4);
 759  	    } else {
 760  		CVT_COMPAT(Float64, Float32, 0);
 761  	    }
 762  	} else {
 763  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 764  		CVT_COMPAT(int64_t, Float32, 0);
 765  	    } else {
 766  		CFSInt128Struct i;
 767  		memmove(&i, data, 16);
 768  		Float64 d;
 769  		cvtSInt128ToFloat64(&d, &i);
 770  		Float32 f = (Float32)d;
 771  		memmove(valuePtr, &f, 4);
 772  		d = f;
 773  		CFSInt128Struct i2;
 774  		cvtFloat64ToSInt128(&i2, &d);
 775  		return cmp128(&i2, &i) == kCFCompareEqualTo;
 776  	    }
 777  	}
 778  	return true;
 779      case kCFNumberFloat64Type:
 780  	if (__CFNumberTypeTable[ntype].floatBit) {
 781  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 782  		CVT_COMPAT(Float32, Float64, 0);
 783  	    } else {
 784  		memmove(valuePtr, data, 8);
 785  	    }
 786  	} else {
 787  	    if (0 == __CFNumberTypeTable[ntype].storageBit) {
 788  		CVT_COMPAT(int64_t, Float64, 0);
 789  	    } else {
 790  		CFSInt128Struct i;
 791  		memmove(&i, data, 16);
 792  		Float64 d;
 793  		cvtSInt128ToFloat64(&d, &i);
 794  		memmove(valuePtr, &d, 8);
 795  		CFSInt128Struct i2;
 796  		cvtFloat64ToSInt128(&i2, &d);
 797  		return cmp128(&i2, &i) == kCFCompareEqualTo;
 798  	    }
 799  	}
 800  	return true;
 801      }
 802      return false;
 803  }
 804  
 805  #if OLD_CRAP_TOO
 806  static void FAIL(void) {}
 807  #endif
 808  
 809  static CFStringRef __CFNumberCopyDescription(CFTypeRef cf) {
 810      CFNumberRef number = (CFNumberRef)cf;
 811      CFNumberType type = __CFNumberGetType(number);
 812      CFMutableStringRef mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
 813      CFStringAppendFormat(mstr, NULL, CFSTR("<CFNumber %p [%p]>{value = "), cf, CFGetAllocator(cf));
 814      if (__CFNumberTypeTable[type].floatBit) {
 815  	Float64 d;
 816          __CFNumberGetValue(number, kCFNumberFloat64Type, &d);
 817  	if (isnan(d)) {
 818  	    CFStringAppend(mstr, CFSTR("nan"));
 819  	} else if (isinf(d)) {
 820  	    CFStringAppend(mstr, (0.0 < d) ? CFSTR("+infinity") : CFSTR("-infinity"));
 821  	} else if (0.0 == d) {
 822  	    CFStringAppend(mstr, (copysign(1.0, d) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0"));
 823  	} else {
 824  	    CFStringAppendFormat(mstr, NULL, CFSTR("%+.*f"), (__CFNumberTypeTable[type].storageBit ? 20 : 10), d);
 825  	}
 826  	const char *typeName = "unknown float";
 827  	switch (type) {
 828  	case kCFNumberFloat32Type: typeName = "kCFNumberFloat32Type"; break;
 829  	case kCFNumberFloat64Type: typeName = "kCFNumberFloat64Type"; break;
 830  	}
 831  	CFStringAppendFormat(mstr, NULL, CFSTR(", type = %s}"), typeName);
 832      } else {
 833  	CFSInt128Struct i;
 834  	__CFNumberGetValue(number, kCFNumberSInt128Type, &i);
 835  	char buffer[128];
 836  	emit128(buffer, &i, true);
 837  	const char *typeName = "unknown integer";
 838  	switch (type) {
 839  	case kCFNumberSInt8Type: typeName = "kCFNumberSInt8Type"; break;
 840  	case kCFNumberSInt16Type: typeName = "kCFNumberSInt16Type"; break;
 841  	case kCFNumberSInt32Type: typeName = "kCFNumberSInt32Type"; break;
 842  	case kCFNumberSInt64Type: typeName = "kCFNumberSInt64Type"; break;
 843  	case kCFNumberSInt128Type: typeName = "kCFNumberSInt128Type"; break;
 844  	}
 845  	CFStringAppendFormat(mstr, NULL, CFSTR("%s, type = %s}"), buffer, typeName);
 846      }
 847  #if OLD_CRAP_TOO
 848  if (! number->__old__) {
 849  
 850  printf("*** Test skipped in __CFNumberCopyDescription for number %p\n", cf);
 851  } else {
 852  CFStringRef test = __CFNumberCopyDescription_old(number->__old__);
 853  if (!CFEqual(test, mstr)) {
 854  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyDescription: '%@' '%@'"), test, mstr);  FAIL();
 855  }
 856  }
 857  #endif
 858      return mstr;
 859  }
 860  
 861  // This function separated out from __CFNumberCopyFormattingDescription() so the plist creation can use it as well.
 862  
 863  static CFStringRef __CFNumberCreateFormattingDescriptionAsFloat64(CFAllocatorRef allocator, CFTypeRef cf) {
 864      Float64 d;
 865      CFNumberGetValue((CFNumberRef)cf, kCFNumberFloat64Type, &d);
 866      if (isnan(d)) {
 867  	return (CFStringRef)CFRetain(CFSTR("nan"));
 868      }
 869      if (isinf(d)) {
 870  	return (CFStringRef)CFRetain((0.0 < d) ? CFSTR("+infinity") : CFSTR("-infinity"));
 871      }
 872      if (0.0 == d) {
 873  	return (CFStringRef)CFRetain(CFSTR("0.0"));
 874      }
 875      // if %g is used here, need to use DBL_DIG + 2 on Mac OS X, but %f needs +1
 876      return CFStringCreateWithFormat(allocator, NULL, CFSTR("%.*g"), DBL_DIG + 2, d);
 877  }
 878  
 879  CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64(CFTypeRef cf) {
 880      CFStringRef result = __CFNumberCreateFormattingDescriptionAsFloat64(kCFAllocatorSystemDefault, cf);
 881  #if OLD_CRAP_TOO
 882  CFNumberRef number = (CFNumberRef)cf;
 883  if (! number->__old__) {
 884  printf("*** Test skipped in __CFNumberCopyFormattingDescriptionAsFloat64 for number %p\n", cf);
 885  } else {
 886  CFStringRef test = __CFNumberCopyFormattingDescriptionAsFloat64_old(number->__old__);
 887  if (!CFEqual(test, result)) {
 888  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyFormattingDescriptionAsFloat64: '%@' '%@'"), test, result);  FAIL();
 889  }
 890  }
 891  #endif
 892      return result;
 893  }
 894  
 895  CF_PRIVATE CFStringRef __CFNumberCreateFormattingDescription(CFAllocatorRef allocator, CFTypeRef cf, CFDictionaryRef formatOptions) {
 896      CFNumberRef number = (CFNumberRef)cf;
 897      CFNumberType type = __CFNumberGetType(number);
 898      if (__CFNumberTypeTable[type].floatBit) {
 899          return __CFNumberCreateFormattingDescriptionAsFloat64(allocator, number);
 900      }
 901      CFSInt128Struct i;
 902      __CFNumberGetValue(number, kCFNumberSInt128Type, &i);
 903      char buffer[128];
 904      emit128(buffer, &i, false);
 905      return CFStringCreateWithFormat(allocator, NULL, CFSTR("%s"), buffer);
 906  }
 907  
 908  static CFStringRef __CFNumberCopyFormattingDescription_new(CFTypeRef cf, CFDictionaryRef formatOptions) {
 909      CFNumberRef number = (CFNumberRef)cf;
 910      CFNumberType type = __CFNumberGetType(number);
 911      if (__CFNumberTypeTable[type].floatBit) {
 912          return __CFNumberCopyFormattingDescriptionAsFloat64(number);
 913      }
 914      CFSInt128Struct i;
 915      __CFNumberGetValue(number, kCFNumberSInt128Type, &i);
 916      char buffer[128];
 917      emit128(buffer, &i, false);
 918      return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%s"), buffer);
 919  }
 920  
 921  CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
 922      CFStringRef result = __CFNumberCopyFormattingDescription_new(cf, formatOptions);
 923  #if OLD_CRAP_TOO
 924  CFNumberRef number = (CFNumberRef)cf;
 925  if (! number->__old__) {
 926  printf("*** Test skipped in __CFNumberCopyFormattingDescription for number %p\n", cf);
 927  } else {
 928  CFStringRef test = __CFNumberCopyFormattingDescription_old(number->__old__, formatOptions);
 929  if (!CFEqual(test, result)) {
 930  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberCopyFormattingDescription: '%@' '%@'"), test, result);  FAIL();
 931  }
 932  }
 933  #endif
 934      return result;
 935  }
 936  
 937  
 938  static Boolean __CFNumberEqual(CFTypeRef cf1, CFTypeRef cf2) {
 939      Boolean b = CFNumberCompare((CFNumberRef)cf1, (CFNumberRef)cf2, 0) == kCFCompareEqualTo;
 940  #if OLD_CRAP_TOO
 941  CFNumberRef number1 = (CFNumberRef)cf1;
 942  CFNumberRef number2 = (CFNumberRef)cf2;
 943  if (! number1->__old__ || !number2->__old__) {
 944  printf("*** Test skipped in __CFNumberEqual for numbers %p %p\n", cf1, cf2);
 945  } else {
 946  Boolean b2 = __CFNumberEqual_old(number1->__old__, number2->__old__);
 947  if (b2 != b) {
 948  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberEqual: '%d' '%d'"), b2, b);  FAIL();
 949  }
 950  }
 951  #endif
 952      return b;
 953  }
 954  
 955  static CFHashCode __CFNumberHash(CFTypeRef cf) {
 956      CFHashCode h;
 957      CFNumberRef number = (CFNumberRef)cf;
 958      switch (__CFNumberGetType(number)) {
 959  	case kCFNumberSInt8Type:
 960  	case kCFNumberSInt16Type:
 961  	case kCFNumberSInt32Type: {
 962  	    SInt32 i;
 963  	    __CFNumberGetValue(number, kCFNumberSInt32Type, &i);
 964  	    h = _CFHashInt(i);
 965  	    break;
 966  	}
 967  	default: {
 968  	    Float64 d;
 969  	    __CFNumberGetValue(number, kCFNumberFloat64Type, &d);
 970  	    h = _CFHashDouble((double)d);
 971  	    break;
 972  	}
 973      }
 974  #if OLD_CRAP_TOO
 975  CFNumberRef number1 = (CFNumberRef)cf;
 976  if (! number1->__old__) {
 977  printf("*** Test skipped in __CFNumberHash for number %p\n", cf);
 978  } else {
 979  CFHashCode h2 = __CFNumberHash_old(number1->__old__);
 980  if (h2 != h) {
 981  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in __CFNumberHash: '%d' '%d'"), h2, h);  FAIL();
 982  }
 983  }
 984  #endif
 985      return h;
 986  }
 987  
 988  static CFTypeID __kCFNumberTypeID = _kCFRuntimeNotATypeID;
 989  
 990  enum {
 991    kCFNumberCachingEnabled = 0,
 992    kCFNumberCachingDisabled = 1,
 993    kCFNumberCachingFullyDisabled = 2
 994  };
 995  static char __CFNumberCaching = kCFNumberCachingEnabled;
 996  
 997  static const CFRuntimeClass __CFNumberClass = {
 998      0,
 999      "CFNumber",
1000      NULL,      // init
1001      NULL,      // copy
1002      NULL,
1003      __CFNumberEqual,
1004      __CFNumberHash,
1005      __CFNumberCopyFormattingDescription,
1006      __CFNumberCopyDescription
1007  };
1008  
1009  
1010  CFTypeID CFNumberGetTypeID(void) {
1011      static dispatch_once_t initOnce;
1012      dispatch_once(&initOnce, ^{
1013          __kCFNumberTypeID = _CFRuntimeRegisterClass(&__CFNumberClass); // initOnce covered
1014  
1015          _CFRuntimeSetInstanceTypeIDAndIsa(&__kCFNumberNaN, __kCFNumberTypeID);
1016          __CFBitfieldSetValue(__kCFNumberNaN._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
1017          __kCFNumberNaN._pad = BITSFORDOUBLENAN;
1018  
1019          _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberNegativeInfinity, __kCFNumberTypeID);
1020          __CFBitfieldSetValue(__kCFNumberNegativeInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
1021          __kCFNumberNegativeInfinity._pad = BITSFORDOUBLENEGINF;
1022  
1023          _CFRuntimeSetInstanceTypeIDAndIsa(& __kCFNumberPositiveInfinity, __kCFNumberTypeID);
1024          __CFBitfieldSetValue(__kCFNumberPositiveInfinity._base._cfinfo[CF_INFO_BITS], 4, 0, kCFNumberFloat64Type);
1025          __kCFNumberPositiveInfinity._pad = BITSFORDOUBLEPOSINF;
1026  
1027  
1028          const char *caching = __CFgetenv("CFNumberDisableCache");	// "all" to disable caching and tagging; anything else to disable caching; nothing to leave both enabled
1029          if (caching) __CFNumberCaching = (!strcmp(caching, "all")) ? kCFNumberCachingFullyDisabled : kCFNumberCachingDisabled;	// initial state above is kCFNumberCachingEnabled
1030      });
1031      return __kCFNumberTypeID;
1032  }
1033  
1034  #define MinCachedInt (-1)
1035  #define MaxCachedInt (12)
1036  #define NotToBeCached (MinCachedInt - 1)
1037  static CFNumberRef __CFNumberCache[MaxCachedInt - MinCachedInt + 1] = {NULL};	// Storing CFNumberRefs for range MinCachedInt..MaxCachedInt
1038  
1039  CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) {
1040      __CFAssertIsValidNumberType(type);
1041  //printf("+ [%p] CFNumberCreate(%p, %d, %p)\n", pthread_self(), allocator, type, valuePtr);
1042  
1043      if (!allocator) allocator = __CFGetDefaultAllocator();
1044  
1045  
1046      // Look for cases where we can return a cached instance.
1047      // We only use cached objects if the allocator is the system
1048      // default allocator, except for the special floating point
1049      // constant objects, where we return the cached object
1050      // regardless of allocator, since that is what has always
1051      // been done (and now must for compatibility).
1052      int64_t valToBeCached = NotToBeCached;
1053  
1054      if (__CFNumberTypeTable[type].floatBit) {
1055  	CFNumberRef cached = NULL;
1056  	if (0 == __CFNumberTypeTable[type].storageBit) {
1057  	    Float32 f = *(Float32 *)valuePtr;
1058  	    if (isnan(f)) cached = kCFNumberNaN;
1059  	    if (isinf(f)) cached = (f < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity;
1060  	} else {
1061              Float64 d = *(Float64 *)valuePtr;
1062  	    if (isnan(d)) cached = kCFNumberNaN;
1063  	    if (isinf(d)) cached = (d < 0.0) ? kCFNumberNegativeInfinity : kCFNumberPositiveInfinity;
1064  	}
1065  	if (cached) return (CFNumberRef)CFRetain(cached);
1066      } else if (_CFAllocatorIsSystemDefault(allocator) && (__CFNumberCaching == kCFNumberCachingEnabled)) {
1067  	switch (__CFNumberTypeTable[type].canonicalType) {
1068  	case kCFNumberSInt8Type:   {int8_t  val = *(int8_t *)valuePtr;  if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;}
1069  	case kCFNumberSInt16Type:  {int16_t val = *(int16_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;}
1070  	case kCFNumberSInt32Type:  {int32_t val = *(int32_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;}
1071  	case kCFNumberSInt64Type:  {int64_t val = *(int64_t *)valuePtr; if (MinCachedInt <= val && val <= MaxCachedInt) valToBeCached = (int64_t)val; break;}
1072  	}
1073  	if (NotToBeCached != valToBeCached) {
1074  	    CFNumberRef cached = __CFNumberCache[valToBeCached - MinCachedInt];	    // Atomic to access the value in the cache
1075  	    if (NULL != cached) return (CFNumberRef)CFRetain(cached);
1076  	}
1077      }
1078  
1079      CFIndex size = 8 + ((!__CFNumberTypeTable[type].floatBit && __CFNumberTypeTable[type].storageBit) ? 8 : 0);
1080  #if OLD_CRAP_TOO
1081      size += 2 * sizeof(void *);
1082  #endif
1083      CFNumberRef result = (CFNumberRef)_CFRuntimeCreateInstance(allocator, CFNumberGetTypeID(), size, NULL);
1084      if (NULL == result) {
1085  	return NULL;
1086      }
1087      __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)__CFNumberTypeTable[type].canonicalType);
1088  
1089  #if OLD_CRAP_TOO
1090      ((struct __CFNumber *)result)->__old__ = CFNumberCreate_old(allocator, type, valuePtr);
1091  CFLog(kCFLogLevelWarning, CFSTR("+++ Create old number '%@'"), __CFNumberCopyDescription_old(result->__old__));
1092  
1093  #endif
1094  
1095      // for a value to be cached, we already have the value handy
1096      if (NotToBeCached != valToBeCached) {
1097  	memmove((void *)&result->_pad, &valToBeCached, 8);
1098  	// Put this in the cache unless the cache is already filled (by another thread).  If we do put it in the cache, retain it an extra time for the cache.
1099  	// Note that we don't bother freeing this result and returning the cached value if the cache was filled, since cached CFNumbers are not guaranteed unique.
1100  	// Barrier assures that the number that is placed in the cache is properly formed.
1101  	CFNumberType origType = __CFNumberGetType(result);
1102  	// Force all cached numbers to have the same type, so that the type does not
1103  	// depend on the order and original type in/with which the numbers are created.
1104  	// Forcing the type AFTER it was cached would cause a race condition with other
1105  	// threads pulling the number object out of the cache and using it.
1106  	__CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)kCFNumberSInt32Type);
1107  	if (OSAtomicCompareAndSwapPtrBarrier(NULL, (void *)result, (void *volatile *)&__CFNumberCache[valToBeCached - MinCachedInt])) {
1108  	    CFRetain(result);
1109  	} else {
1110  	    // Did not cache the number object, put original type back.
1111  	    __CFBitfieldSetValue(((struct __CFNumber *)result)->_base._cfinfo[CF_INFO_BITS], 4, 0, (uint8_t)origType);
1112  	}
1113  	return result;
1114      }
1115  
1116      uint64_t value;
1117      switch (__CFNumberTypeTable[type].canonicalType) {
1118      case kCFNumberSInt8Type:   value = (uint64_t)(int64_t)*(int8_t *)valuePtr; goto smallVal;
1119      case kCFNumberSInt16Type:  value = (uint64_t)(int64_t)*(int16_t *)valuePtr; goto smallVal;
1120      case kCFNumberSInt32Type:  value = (uint64_t)(int64_t)*(int32_t *)valuePtr; goto smallVal;
1121  			smallVal: memmove((void *)&result->_pad, &value, 8); break;
1122      case kCFNumberSInt64Type:  memmove((void *)&result->_pad, valuePtr, 8); break;
1123      case kCFNumberSInt128Type: memmove((void *)&result->_pad, valuePtr, 16); break;
1124      case kCFNumberFloat32Type: memmove((void *)&result->_pad, valuePtr, 4); break;
1125      case kCFNumberFloat64Type: memmove((void *)&result->_pad, valuePtr, 8); break;
1126      }
1127  //printf("  => %p\n", result);
1128      return result;
1129  }
1130  
1131  CFNumberType CFNumberGetType(CFNumberRef number) {
1132  //printf("+ [%p] CFNumberGetType(%p)\n", pthread_self(), number);
1133      CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType);
1134      __CFAssertIsNumber(number);
1135      CFNumberType type = __CFNumberGetType(number);
1136      if (kCFNumberSInt128Type == type) type = kCFNumberSInt64Type; // must hide this type, since it is not public
1137  //printf("  => %d\n", type);
1138  #if OLD_CRAP_TOO
1139  if (! number->__old__) {
1140  printf("*** Test skipped in CFNumberGetType for number %p\n", number);
1141  } else {
1142  CFNumberType t2 = CFNumberGetType_old(number->__old__);
1143  if (t2 != type) {
1144  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberGetType: '%d' '%d'"), t2, type);  FAIL();
1145  }
1146  }
1147  #endif
1148      return type;
1149  }
1150  
1151  CF_EXPORT CFNumberType _CFNumberGetType2(CFNumberRef number) {
1152      CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFNumberType, (NSNumber *)number, _cfNumberType);
1153      __CFAssertIsNumber(number);
1154      return __CFNumberGetType(number);
1155  }
1156  
1157  CFIndex CFNumberGetByteSize(CFNumberRef number) {
1158  //printf("+ [%p] CFNumberGetByteSize(%p)\n", pthread_self(), number);
1159      __CFAssertIsNumber(number);
1160      CFIndex r = 1 << __CFNumberTypeTable[CFNumberGetType(number)].lgByteSize;
1161  //printf("  => %d\n", r);
1162  #if OLD_CRAP_TOO
1163  if (! number->__old__) {
1164  printf("*** Test skipped in CFNumberGetByteSize for number %p\n", number);
1165  } else {
1166  CFIndex r2 = CFNumberGetByteSize_old(number->__old__);
1167  if (r2 != r) {
1168  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberGetByteSize: '%d' '%d'"), r2, r);  FAIL();
1169  }
1170  }
1171  #endif
1172      return r;
1173  }
1174  
1175  Boolean CFNumberIsFloatType(CFNumberRef number) {
1176  //printf("+ [%p] CFNumberIsFloatType(%p)\n", pthread_self(), number);
1177      __CFAssertIsNumber(number);
1178      Boolean r = __CFNumberTypeTable[CFNumberGetType(number)].floatBit;
1179  //printf("  => %d\n", r);
1180  #if OLD_CRAP_TOO
1181  if (! number->__old__) {
1182  printf("*** Test skipped in CFNumberIsFloatType for number %p\n", number);
1183  } else {
1184  Boolean r2 = CFNumberIsFloatType_old(number->__old__);
1185  if (r2 != r) {
1186  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberIsFloatType: '%d' '%d'"), r2, r);  FAIL();
1187  }
1188  }
1189  #endif
1190      return r;
1191  }
1192  
1193  Boolean CFNumberGetValue(CFNumberRef number, CFNumberType type, void *valuePtr) {
1194  //printf("+ [%p] CFNumberGetValue(%p, %d, %p)\n", pthread_self(), number, type, valuePtr);
1195  
1196      CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), Boolean, (NSNumber *)number, _getValue:(void *)valuePtr forType:(CFNumberType)__CFNumberTypeTable[type].canonicalType);
1197      __CFAssertIsNumber(number);
1198      __CFAssertIsValidNumberType(type);
1199      uint8_t localMemory[128];
1200      Boolean r = __CFNumberGetValueCompat(number, type, valuePtr ? valuePtr : localMemory);
1201  //printf("  => %d\n", r);
1202  #if OLD_CRAP_TOO
1203  if (! number->__old__) {
1204  printf("*** Test skipped in CFNumberGetValue for number %p\n", number);
1205  } else {
1206      uint8_t localMemory2[128];
1207  Boolean r2 = CFNumberGetValue_old(number->__old__, type, localMemory2);
1208  if (r2 != r) {
1209  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL 1 in CFNumberGetValue: '%d' '%d'"), r2, r);  FAIL();
1210  }
1211  if (0 != memcmp(localMemory2, valuePtr, CFNumberGetByteSize(number))) {
1212  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL 2 in CFNumberGetValue: BYTES NOT SAME"));  FAIL();
1213  }
1214  }
1215  #endif
1216      return r;
1217  }
1218  
1219  static CFComparisonResult CFNumberCompare_new(CFNumberRef number1, CFNumberRef number2, void *context) {
1220      CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFComparisonResult, (NSNumber *)number1, compare:(NSNumber *)number2);
1221      CF_OBJC_FUNCDISPATCHV(CFNumberGetTypeID(), CFComparisonResult, (NSNumber *)number2, _reverseCompare:(NSNumber *)number1);
1222      __CFAssertIsNumber(number1);
1223      __CFAssertIsNumber(number2);
1224  
1225      CFNumberType type1 = __CFNumberGetType(number1);
1226      CFNumberType type2 = __CFNumberGetType(number2);
1227      // Both numbers are integers
1228      if (!__CFNumberTypeTable[type1].floatBit && !__CFNumberTypeTable[type2].floatBit) {
1229          CFSInt128Struct i1, i2;
1230          __CFNumberGetValue(number1, kCFNumberSInt128Type, &i1);
1231          __CFNumberGetValue(number2, kCFNumberSInt128Type, &i2);
1232          return cmp128(&i1, &i2);
1233      }
1234      // Both numbers are floats
1235      if (__CFNumberTypeTable[type1].floatBit && __CFNumberTypeTable[type2].floatBit) {
1236  	Float64 d1, d2;
1237          __CFNumberGetValue(number1, kCFNumberFloat64Type, &d1);
1238          __CFNumberGetValue(number2, kCFNumberFloat64Type, &d2);
1239  	double s1 = copysign(1.0, d1);
1240  	double s2 = copysign(1.0, d2);
1241  	if (isnan(d1) && isnan(d2)) return kCFCompareEqualTo;
1242  	if (isnan(d1)) return (s2 < 0.0) ? kCFCompareGreaterThan : kCFCompareLessThan;
1243  	if (isnan(d2)) return (s1 < 0.0) ? kCFCompareLessThan : kCFCompareGreaterThan;
1244  	// at this point, we know we don't have any NaNs
1245  	if (s1 < s2) return kCFCompareLessThan;
1246  	if (s2 < s1) return kCFCompareGreaterThan;
1247  	// at this point, we know the signs are the same; do not combine these tests
1248  	if (d1 < d2) return kCFCompareLessThan;
1249  	if (d2 < d1) return kCFCompareGreaterThan;
1250          return kCFCompareEqualTo;
1251      }
1252      // One float, one integer; swap if necessary so number1 is the float
1253      Boolean swapResult = false;
1254      if (__CFNumberTypeTable[type2].floatBit) {
1255          CFNumberRef tmp = number1;
1256  	number1 = number2;
1257  	number2 = tmp;
1258  	swapResult = true;
1259      }
1260      // At large integer values, the precision of double is quite low
1261      // e.g. all values roughly 2^127 +- 2^73 are represented by 1 double, 2^127.
1262      // If we just used double compare, that would make the 2^73 largest 128-bit
1263      // integers look equal, so we have to use integer comparison when possible.
1264      Float64 d1, d2;
1265      __CFNumberGetValue(number1, kCFNumberFloat64Type, &d1);
1266      // if the double value is really big, cannot be equal to integer
1267      // nan d1 will not compare true here
1268      if (d1 < FLOAT_NEGATIVE_2_TO_THE_127) {
1269  	return !swapResult ? kCFCompareLessThan : kCFCompareGreaterThan;
1270      }
1271      if (FLOAT_POSITIVE_2_TO_THE_127 <= d1) {
1272  	return !swapResult ? kCFCompareGreaterThan : kCFCompareLessThan;
1273      }
1274      CFSInt128Struct i1, i2;
1275      __CFNumberGetValue(number1, kCFNumberSInt128Type, &i1);
1276      __CFNumberGetValue(number2, kCFNumberSInt128Type, &i2);
1277      CFComparisonResult res = cmp128(&i1, &i2);
1278      if (kCFCompareEqualTo != res) {
1279  	return !swapResult ? res : -res;
1280      }
1281      // now things are equal, but perhaps due to rounding or nan
1282      if (isnan(d1)) {
1283  	if (isNeg128(&i2)) {
1284  	    return !swapResult ? kCFCompareGreaterThan : kCFCompareLessThan;
1285  	}
1286  	// nan compares less than positive 0 too
1287  	return !swapResult ? kCFCompareLessThan : kCFCompareGreaterThan;
1288      }
1289      // at this point, we know we don't have NaN
1290      double s1 = copysign(1.0, d1);
1291      double s2 = isNeg128(&i2) ? -1.0 : 1.0;
1292      if (s1 < s2) return !swapResult ? kCFCompareLessThan : kCFCompareGreaterThan;
1293      if (s2 < s1) return !swapResult ? kCFCompareGreaterThan : kCFCompareLessThan;
1294      // at this point, we know the signs are the same; do not combine these tests
1295      __CFNumberGetValue(number2, kCFNumberFloat64Type, &d2);
1296      if (d1 < d2) return !swapResult ? kCFCompareLessThan : kCFCompareGreaterThan;
1297      if (d2 < d1) return !swapResult ? kCFCompareGreaterThan : kCFCompareLessThan;
1298      return kCFCompareEqualTo;
1299  }
1300  
1301  CFComparisonResult CFNumberCompare(CFNumberRef number1, CFNumberRef number2, void *context) {
1302  //printf("+ [%p] CFNumberCompare(%p, %p, %p)\n", pthread_self(), number1, number2, context);
1303      CFComparisonResult r = CFNumberCompare_new(number1, number2, context);
1304  //printf("  => %d\n", r);
1305  #if OLD_CRAP_TOO
1306  if (! number1->__old__ || !number2->__old__) {
1307  printf("*** Test skipped in CFNumberCompare for numbers %p %p\n", number1, number2);
1308  } else {
1309  CFComparisonResult r2 = CFNumberCompare_old(number1->__old__, number2->__old__, context);
1310  if (r2 != r) {
1311  CFLog(kCFLogLevelWarning, CFSTR("*** TEST FAIL in CFNumberCompare: '%d' '%d'"), r2, r);  FAIL();
1312  }
1313  }
1314  #endif
1315      return r;
1316  }
1317  
1318  #if OLD_CRAP_TOO
1319  
1320  static const unsigned char __CFNumberCanonicalType[kCFNumberMaxType + 1] = {
1321      0, kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
1322      kCFNumberSInt8Type, kCFNumberSInt16Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
1323      kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type
1324  };
1325  
1326  static const unsigned char __CFNumberStorageType[kCFNumberMaxType + 1] = {
1327      0, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
1328      kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberSInt64Type, kCFNumberFloat32Type, kCFNumberFloat64Type,
1329      kCFNumberSInt32Type, kCFNumberSInt32Type, kCFNumberFloat32Type
1330  };
1331  
1332  
1333  
1334  // Returns the type that is used to store the specified type
1335  static CFNumberType __CFNumberGetStorageTypeForType_old(CFNumberType type) {
1336      return __CFNumberStorageType[type];
1337  }
1338  
1339  // Returns the canonical type used to represent the specified type
1340  static CFNumberType __CFNumberGetCanonicalTypeForType_old(CFNumberType type) {
1341      return __CFNumberCanonicalType[type];
1342  }
1343  
1344  // Extracts and returns the type out of the CFNumber
1345  static CFNumberType __CFNumberGetType_old(struct __CFNumber_old * num) {
1346      return __CFBitfieldGetValue(num->_base._cfinfo[CF_INFO_BITS], 4, 0);
1347  }
1348  
1349  // Returns true if the argument type is float or double
1350  static Boolean __CFNumberTypeIsFloat_old(CFNumberType type) {
1351      return (type == kCFNumberFloat64Type) || (type == kCFNumberFloat32Type) || (type == kCFNumberDoubleType) || (type == kCFNumberFloatType);
1352  }
1353  
1354  // Returns the number of bytes necessary to store the specified type
1355  // Needs to handle all canonical types
1356  static CFIndex __CFNumberSizeOfType_old(CFNumberType type) {
1357      switch (type) {
1358          case kCFNumberSInt8Type:        return sizeof(int8_t);
1359          case kCFNumberSInt16Type:       return sizeof(int16_t);
1360          case kCFNumberSInt32Type:       return sizeof(SInt32);
1361          case kCFNumberSInt64Type:       return sizeof(int64_t);
1362          case kCFNumberFloat32Type:      return sizeof(Float32);
1363          case kCFNumberFloat64Type:      return sizeof(Float64);
1364          default:                        printf("*** WARNING: 0 size from __CFNumberSizeOfType_old \n"); return 0;
1365      }
1366  }
1367  
1368  // Copies an external value of a given type into the appropriate slot in the union (does no type conversion)
1369  // Needs to handle all canonical types
1370  #define SET_VALUE(valueUnion, type, valuePtr)   \
1371      switch (type) {                             \
1372          case kCFNumberSInt8Type:        (valueUnion)->valSInt32 = *(int8_t *)(valuePtr); break; \
1373          case kCFNumberSInt16Type:       (valueUnion)->valSInt32 = *(int16_t *)(valuePtr); break;        \
1374          case kCFNumberSInt32Type:       (valueUnion)->valSInt32 = *(SInt32 *)(valuePtr); break; \
1375          case kCFNumberSInt64Type:       (valueUnion)->valSInt64 = *(int64_t *)(valuePtr); break;        \
1376          case kCFNumberFloat32Type:      (valueUnion)->valFloat32 = *(Float32 *)(valuePtr); break;       \
1377          case kCFNumberFloat64Type:      (valueUnion)->valFloat64 = *(Float64 *)(valuePtr); break;       \
1378          default: printf("*** WARNING: default case in SET_VALUE \n"); break; \
1379      }
1380  
1381  // Casts the specified value into the specified type and copies it into the provided memory
1382  // Needs to handle all canonical types
1383  #define GET_VALUE(value, type, resultPtr)       \
1384      switch (type) {                             \
1385          case kCFNumberSInt8Type:        *(int8_t *)(resultPtr) = (int8_t)value; break;  \
1386          case kCFNumberSInt16Type:       *(int16_t *)(resultPtr) = (int16_t)value; break;        \
1387          case kCFNumberSInt32Type:       *(SInt32 *)(resultPtr) = (SInt32)value; break;  \
1388          case kCFNumberSInt64Type:       *(int64_t *)(resultPtr) = (int64_t)value; break;        \
1389          case kCFNumberFloat32Type:      *(Float32 *)(resultPtr) = (Float32)value; break;        \
1390          case kCFNumberFloat64Type:      *(Float64 *)(resultPtr) = (Float64)value; break;        \
1391          default: printf("*** WARNING: default case in GET_VALUE \n"); break; \
1392      }
1393  
1394  // Extracts the stored type out of the union and copies it in the desired type into the provided memory
1395  // Needs to handle all storage types
1396  static void __CFNumberGetValue_old(const __CFNumberValue_old *value, CFNumberType numberType, CFNumberType typeToGet, void *valuePtr) {
1397      switch (numberType) {
1398          case kCFNumberSInt32Type:       GET_VALUE(value->valSInt32, typeToGet, valuePtr); break;
1399          case kCFNumberSInt64Type:       GET_VALUE(value->valSInt64, typeToGet, valuePtr); break;
1400          case kCFNumberFloat32Type:      GET_VALUE(value->valFloat32, typeToGet, valuePtr); break;
1401          case kCFNumberFloat64Type:      GET_VALUE(value->valFloat64, typeToGet, valuePtr); break;
1402          default: printf("*** WARNING: default case in __CFNumberGetValue_old \n"); break; \
1403      }
1404  }
1405  
1406  // Sees if two value union structs have the same value (will do type conversion)
1407  static Boolean __CFNumberEqualValue_old(const __CFNumberValue_old *value1, CFNumberType type1, const __CFNumberValue_old *value2, CFNumberType type2) {
1408      if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) {
1409          Float64 d1, d2;
1410          __CFNumberGetValue_old(value1, type1, kCFNumberFloat64Type, &d1);
1411          __CFNumberGetValue_old(value2, type2, kCFNumberFloat64Type, &d2);
1412              if (isnan(d1) && isnan(d2)) return true;    // Not mathematically sound, but required
1413          return d1 == d2;
1414      } else {
1415          int64_t i1, i2;
1416          __CFNumberGetValue_old(value1, type1, kCFNumberSInt64Type, &i1);
1417          __CFNumberGetValue_old(value2, type2, kCFNumberSInt64Type, &i2);
1418          return i1 == i2;
1419      }
1420  }
1421  
1422  static Boolean __CFNumberEqual_old(CFTypeRef cf1, CFTypeRef cf2) {
1423      struct __CFNumber_old * number1 = (struct __CFNumber_old *)cf1;
1424      struct __CFNumber_old * number2 = (struct __CFNumber_old *)cf2;
1425      return __CFNumberEqualValue_old(&(number1->value), __CFNumberGetType_old(number1), &(number2->value), __CFNumberGetType_old(number2));
1426  }
1427  
1428  static CFHashCode __CFNumberHash_old(CFTypeRef cf) {
1429      struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
1430      switch (__CFNumberGetType_old((struct __CFNumber_old *)cf)) {
1431          case kCFNumberSInt32Type: return _CFHashInt(number->value.valSInt32);
1432          case kCFNumberSInt64Type: return _CFHashDouble((double)(number->value.valSInt64));
1433          case kCFNumberFloat32Type: return _CFHashDouble((double)(number->value.valFloat32));
1434          case kCFNumberFloat64Type: return _CFHashDouble((double)(number->value.valFloat64));
1435          default: printf("*** WARNING default case in __CFNumberHash_old\n");
1436              return 0;
1437      }
1438  }
1439  
1440  #define BUFFER_SIZE 100
1441  #define emitChar(ch) \
1442      {if (buf - stackBuf == BUFFER_SIZE) {CFStringAppendCharacters(mstr, stackBuf, BUFFER_SIZE); buf = stackBuf;} *buf++ = ch;}
1443                   
1444  static void __CFNumberEmitInt64_old(CFMutableStringRef mstr, int64_t value, int32_t width, UniChar pad, bool explicitPlus) {
1445      UniChar stackBuf[BUFFER_SIZE], *buf = stackBuf;
1446      uint64_t uvalue, factor, tmp;
1447      int32_t w;
1448      bool neg;
1449  
1450      neg = (value < 0) ? true : false;
1451      uvalue = (neg) ? -value : value;
1452      if (neg || explicitPlus) width--;
1453      width--;
1454      factor = 1;
1455      tmp = uvalue;
1456      while (9 < tmp) {
1457          width--;
1458          factor *= 10;
1459          tmp /= 10;
1460      }
1461      for (w = 0; w < width; w++) emitChar(pad);
1462      if (neg) {
1463          emitChar('-');
1464      } else if (explicitPlus) {
1465          emitChar('+');
1466      }
1467      while (0 < factor) {
1468          UniChar ch = '0' + (UniChar)(uvalue / factor);
1469          uvalue %= factor;
1470          emitChar(ch);
1471          factor /= 10;
1472      }
1473      if (buf > stackBuf) CFStringAppendCharacters(mstr, stackBuf, buf - stackBuf);
1474  }
1475  
1476  static CFStringRef __CFNumberCopyDescription_old(CFTypeRef cf) {
1477      struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
1478      CFMutableStringRef mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
1479      CFStringAppendFormat(mstr, NULL, CFSTR("<CFNumber %p [%p]>{value = "), cf, CFGetAllocator(cf));
1480      switch (__CFNumberGetType_old(number)) {
1481      case kCFNumberSInt32Type:
1482          __CFNumberEmitInt64_old(mstr, number->value.valSInt32, 0, ' ', true);
1483          CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt32Type}"));
1484          break;
1485      case kCFNumberSInt64Type:
1486          __CFNumberEmitInt64_old(mstr, number->value.valSInt64, 0, ' ', true);
1487          CFStringAppendFormat(mstr, NULL, CFSTR(", type = kCFNumberSInt64Type}"));
1488          break;
1489      case kCFNumberFloat32Type:
1490          // debugging formatting is intentionally more verbose and explicit about the value of the number
1491          if (isnan(number->value.valFloat32)) {
1492              CFStringAppend(mstr, CFSTR("nan"));
1493          } else if (isinf(number->value.valFloat32)) {
1494              CFStringAppend(mstr, (0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity"));
1495          } else if (0.0f == number->value.valFloat32) {
1496              CFStringAppend(mstr, (copysign(1.0, number->value.valFloat32) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0"));
1497          } else {
1498              CFStringAppendFormat(mstr, NULL, CFSTR("%+.10f"), number->value.valFloat32);
1499          }
1500          CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat32Type}"));
1501          break;
1502      case kCFNumberFloat64Type:
1503          // debugging formatting is intentionally more verbose and explicit about the value of the number
1504          if (isnan(number->value.valFloat64)) {
1505              CFStringAppend(mstr, CFSTR("nan"));
1506          } else if (isinf(number->value.valFloat64)) {
1507              CFStringAppend(mstr, (0.0 < number->value.valFloat64) ? CFSTR("+infinity") : CFSTR("-infinity"));
1508          } else if (0.0 == number->value.valFloat64) {
1509              CFStringAppend(mstr, (copysign(1.0, number->value.valFloat64) < 0.0) ? CFSTR("-0.0") : CFSTR("+0.0"));
1510          } else {
1511              CFStringAppendFormat(mstr, NULL, CFSTR("%+.20f"), number->value.valFloat64);
1512          }
1513          CFStringAppend(mstr, CFSTR(", type = kCFNumberFloat64Type}"));
1514          break;
1515      default:
1516          CFRelease(mstr);
1517          return NULL;
1518      }
1519      return mstr;
1520  }
1521  
1522  // This function separated out from __CFNumberCopyFormattingDescription() so the plist creation can use it as well.
1523  
1524  CF_PRIVATE CFStringRef __CFNumberCopyFormattingDescriptionAsFloat64_old(CFTypeRef cf) {
1525      double d;
1526      CFNumberGetValue_old((struct __CFNumber_old *)cf, kCFNumberFloat64Type, &d);
1527          if (isnan(d)) {
1528              return (CFStringRef)CFRetain(CFSTR("nan"));
1529          }
1530          if (isinf(d)) {
1531              return (CFStringRef)CFRetain((0.0 < d) ? CFSTR("+infinity") : CFSTR("-infinity"));
1532          }
1533          if (0.0 == d) {
1534              return (CFStringRef)CFRetain(CFSTR("0.0"));
1535          }
1536          // if %g is used here, need to use DBL_DIG + 2 on Mac OS X, but %f needs +1
1537          return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), DBL_DIG + 2, d);
1538  }
1539  
1540  static CFStringRef __CFNumberCopyFormattingDescription_old(CFTypeRef cf, CFDictionaryRef formatOptions) {
1541      struct __CFNumber_old * number = (struct __CFNumber_old *)cf;
1542      CFMutableStringRef mstr;
1543      int64_t value;
1544      switch (__CFNumberGetType_old(number)) {
1545      case kCFNumberSInt32Type:
1546      case kCFNumberSInt64Type: 
1547          value = (__CFNumberGetType_old(number) == kCFNumberSInt32Type) ? number->value.valSInt32 : number->value.valSInt64;
1548          mstr = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
1549          __CFNumberEmitInt64_old(mstr, value, 0, ' ', false);
1550          return mstr;
1551      case kCFNumberFloat32Type:
1552              if (isnan(number->value.valFloat32)) {
1553                  return (CFStringRef)CFRetain(CFSTR("nan"));
1554              }
1555              if (isinf(number->value.valFloat32)) {
1556                  return (CFStringRef)CFRetain((0.0f < number->value.valFloat32) ? CFSTR("+infinity") : CFSTR("-infinity"));
1557              }
1558              if (0.0f == number->value.valFloat32) {
1559                  return (CFStringRef)CFRetain(CFSTR("0.0"));
1560              }
1561              // if %g is used here, need to use FLT_DIG + 2 on Mac OS X, but %f needs +1
1562              return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("%.*g"), FLT_DIG + 2, number->value.valFloat32);
1563      case kCFNumberFloat64Type:
1564          return __CFNumberCopyFormattingDescriptionAsFloat64_old(number);
1565          break;
1566      default:
1567          return NULL;
1568      }
1569  }
1570  
1571  
1572  
1573  static struct __CFNumber_old * CFNumberCreate_old(CFAllocatorRef allocator, CFNumberType type, const void *valuePtr) {
1574      struct __CFNumber_old * num;
1575      CFNumberType equivType, storageType;
1576  
1577  if (type == 17) {
1578  CFSInt128Struct *s = valuePtr;
1579  s->high = (int64_t)s->low;
1580  type = kCFNumberSInt64Type;
1581  }
1582  
1583      
1584      equivType = __CFNumberGetCanonicalTypeForType_old(type);
1585  
1586      storageType = __CFNumberGetStorageTypeForType_old(type);
1587  
1588      num = (struct __CFNumber_old *)_CFRuntimeCreateInstance(allocator, CFNumberGetTypeID(), __CFNumberSizeOfType_old(storageType), NULL);
1589      if (NULL == num) {
1590          return NULL;
1591      }
1592      SET_VALUE((__CFNumberValue_old *)&(num->value), equivType, valuePtr);
1593      __CFBitfieldSetValue(((struct __CFNumber_old *)num)->_base._cfinfo[CF_INFO_BITS], 6, 0, (uint8_t)storageType);
1594      
1595  if (__CFNumberGetType_old(num) == 0) printf("*** ERROR: new number %p type is 0 (%d)\n", num, storageType);
1596      return num;
1597  }
1598  
1599  static CFNumberType CFNumberGetType_old(struct __CFNumber_old * number) {
1600  
1601      return __CFNumberGetType_old(number);
1602  }
1603  
1604  static CFIndex CFNumberGetByteSize_old(struct __CFNumber_old * number) {
1605      return __CFNumberSizeOfType_old(CFNumberGetType_old(number));
1606  }
1607  
1608  static Boolean CFNumberIsFloatType_old(struct __CFNumber_old * number) {
1609      return __CFNumberTypeIsFloat_old(CFNumberGetType_old(number));
1610  }
1611  
1612  static Boolean CFNumberGetValue_old(struct __CFNumber_old * number, CFNumberType type, void *valuePtr) {
1613      uint8_t localMemory[sizeof(__CFNumberValue_old)];
1614      __CFNumberValue_old localValue;
1615      CFNumberType numType;
1616      CFNumberType storageTypeForType;
1617  
1618  if (type == 17) type = kCFNumberSInt64Type;
1619  
1620      storageTypeForType = __CFNumberGetStorageTypeForType_old(type);
1621      type = __CFNumberGetCanonicalTypeForType_old(type);
1622      if (!valuePtr) valuePtr = &localMemory;
1623  
1624      numType = __CFNumberGetType_old(number);
1625      __CFNumberGetValue_old((__CFNumberValue_old *)&(number->value), numType, type, valuePtr);
1626  
1627      // If the types match, then we're fine!
1628      if (numType == storageTypeForType) return true;
1629  
1630      // Test to see if the returned value is intact...
1631      SET_VALUE(&localValue, type, valuePtr);
1632      return __CFNumberEqualValue_old(&localValue, storageTypeForType, &(number->value), numType);
1633  }
1634  
1635  static CFComparisonResult CFNumberCompare_old(struct __CFNumber_old * number1, struct __CFNumber_old * number2, void *context) {
1636      CFNumberType type1, type2;
1637  
1638  
1639      type1 = __CFNumberGetType_old(number1);
1640      type2 = __CFNumberGetType_old(number2);
1641  
1642      if (__CFNumberTypeIsFloat_old(type1) || __CFNumberTypeIsFloat_old(type2)) {
1643          Float64 d1, d2;
1644          double s1, s2;
1645          __CFNumberGetValue_old(&(number1->value), type1, kCFNumberFloat64Type, &d1);
1646          __CFNumberGetValue_old(&(number2->value), type2, kCFNumberFloat64Type, &d2);
1647          s1 = copysign(1.0, d1);
1648          s2 = copysign(1.0, d2);
1649          if (isnan(d1) && isnan(d2)) return kCFCompareEqualTo;
1650          if (isnan(d1)) return (s2 < 0.0) ? kCFCompareGreaterThan : kCFCompareLessThan;
1651          if (isnan(d2)) return (s1 < 0.0) ? kCFCompareLessThan : kCFCompareGreaterThan;
1652          // at this point, we know we don't have any NaNs
1653          if (s1 < s2) return kCFCompareLessThan;
1654          if (s2 < s1) return kCFCompareGreaterThan;
1655          // at this point, we know the signs are the same; do not combine these tests
1656          if (d1 < d2) return kCFCompareLessThan;
1657          if (d2 < d1) return kCFCompareGreaterThan;
1658          return kCFCompareEqualTo;
1659      } else {
1660          int64_t i1, i2;
1661          __CFNumberGetValue_old(&(number1->value), type1, kCFNumberSInt64Type, &i1);
1662          __CFNumberGetValue_old(&(number2->value), type2, kCFNumberSInt64Type, &i2);
1663          return (i1 > i2) ? kCFCompareGreaterThan : ((i1 < i2) ? kCFCompareLessThan : kCFCompareEqualTo);
1664      }
1665  }
1666  
1667  #endif
1668  
1669  
1670  #undef __CFAssertIsBoolean
1671  #undef __CFAssertIsNumber
1672  #undef __CFAssertIsValidNumberType
1673  #undef BITSFORDOUBLENAN
1674  #undef BITSFORDOUBLEPOSINF
1675  #undef BITSFORDOUBLENEGINF
1676  #undef MinCachedInt
1677  #undef MaxCachedInt
1678  #undef NotToBeCached
1679