// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//


/*	CFNumberFormatter.c
	Copyright (c) 2002 - 2015 Apple Inc. and the Swift project authors
	Responsibility: David Smith
*/

#include <CoreFoundation/CFNumberFormatter.h>
#include <CoreFoundation/ForFoundationOnly.h>
#include <CoreFoundation/CFBigNumber.h>
#include "CFInternal.h"
#include "CFLocaleInternal.h"
#include "CFICULogging.h"
#include <math.h>
#include <float.h>


static void __CFNumberFormatterCustomize(CFNumberFormatterRef formatter);
static CFStringRef __CFNumberFormatterCreateCompressedString(CFStringRef inString, Boolean isFormat, CFRange *rangep);
static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter, CFStringRef pattern);
static CONST_STRING_DECL(kCFNumberFormatterFormattingContextKey, "kCFNumberFormatterFormattingContextKey");

#define BUFFER_SIZE 768

struct __CFNumberFormatter {
    CFRuntimeBase _base;
    UNumberFormat *_nf;
    CFLocaleRef _locale;
    CFNumberFormatterStyle _style;
    CFStringRef _format;	// NULL for RBNFs
    CFStringRef _defformat;
    CFStringRef _compformat;
    CFNumberRef _multiplier;
    CFStringRef _zeroSym;
    Boolean _isLenient;
    Boolean _userSetMultiplier;
    Boolean _usesCharacterDirection;
};

static CFStringRef __CFNumberFormatterCopyDescription(CFTypeRef cf) {
    CFNumberFormatterRef formatter = (CFNumberFormatterRef)cf;
    return CFStringCreateWithFormat(CFGetAllocator(formatter), NULL, CFSTR("<CFNumberFormatter %p [%p]>"), cf, CFGetAllocator(formatter));
}

static void __CFNumberFormatterDeallocate(CFTypeRef cf) {
    CFNumberFormatterRef formatter = (CFNumberFormatterRef)cf;
    if (formatter->_nf) __cficu_unum_close(formatter->_nf);
    if (formatter->_locale) CFRelease(formatter->_locale);
    if (formatter->_format) CFRelease(formatter->_format);
    if (formatter->_defformat) CFRelease(formatter->_defformat);
    if (formatter->_compformat) CFRelease(formatter->_compformat);
    if (formatter->_multiplier) CFRelease(formatter->_multiplier);
    if (formatter->_zeroSym) CFRelease(formatter->_zeroSym);
}

static CFTypeID __kCFNumberFormatterTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFNumberFormatterClass = {
    0,
    "CFNumberFormatter",
    NULL,	// init
    NULL,	// copy
    __CFNumberFormatterDeallocate,
    NULL,
    NULL,
    NULL,	// 
    __CFNumberFormatterCopyDescription
};

CFTypeID CFNumberFormatterGetTypeID(void) {
    static dispatch_once_t initOnce = 0;
    dispatch_once(&initOnce, ^{ __kCFNumberFormatterTypeID = _CFRuntimeRegisterClass(&__CFNumberFormatterClass); });
    return __kCFNumberFormatterTypeID;
}

CFNumberFormatterRef CFNumberFormatterCreate(CFAllocatorRef allocator, CFLocaleRef locale, CFNumberFormatterStyle style) {
    struct __CFNumberFormatter *memory;
    uint32_t size = sizeof(struct __CFNumberFormatter) - sizeof(CFRuntimeBase);
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(locale, CFLocaleGetTypeID());
    memory = (struct __CFNumberFormatter *)_CFRuntimeCreateInstance(allocator, CFNumberFormatterGetTypeID(), size, NULL);
    if (NULL == memory) {
	return NULL;
    }
    memory->_nf = NULL;
    memory->_locale = NULL;
    memory->_format = NULL;
    memory->_defformat = NULL;
    memory->_compformat = NULL;
    memory->_multiplier = NULL;
    memory->_zeroSym = NULL;
    memory->_isLenient = false;
    memory->_userSetMultiplier = false;
    memory->_usesCharacterDirection = false;
    if (NULL == locale) locale = CFLocaleGetSystem();
    memory->_style = style;
    uint32_t ustyle;
    switch (style) {
    case kCFNumberFormatterNoStyle: ustyle = UNUM_IGNORE; break;
    case kCFNumberFormatterDecimalStyle: ustyle = UNUM_DECIMAL; break;
    case kCFNumberFormatterCurrencyStyle: ustyle = UNUM_CURRENCY; break;
    case kCFNumberFormatterPercentStyle: ustyle = UNUM_PERCENT; break;
    case kCFNumberFormatterScientificStyle: ustyle = UNUM_SCIENTIFIC; break;
    case kCFNumberFormatterSpellOutStyle: ustyle = UNUM_SPELLOUT; break;
    case kCFNumberFormatterOrdinalStyle: ustyle = UNUM_ORDINAL; break;
    case kCFNumberFormatterDurationStyle: ustyle = UNUM_DURATION; break;
    case kCFNumberFormatterCurrencyISOCodeStyle: ustyle = UNUM_CURRENCY_ISO; break;
    case kCFNumberFormatterCurrencyPluralStyle: ustyle = UNUM_CURRENCY_PLURAL; break;
#if U_ICU_VERSION_MAJOR_NUM >= 55
    case kCFNumberFormatterCurrencyAccountingStyle: ustyle = UNUM_CURRENCY_ACCOUNTING; break;
#endif
    default:
	CFAssert(0, __kCFLogAssertion, "%s(): unknown style %d", __PRETTY_FUNCTION__, style);
	ustyle = UNUM_DECIMAL;
	memory->_style = kCFNumberFormatterDecimalStyle;
	break;
    }
    CFStringRef localeName = locale ? CFLocaleGetIdentifier(locale) : CFSTR("");
    char buffer[BUFFER_SIZE];
    const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
    if (NULL == cstr) {
	if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
    }
    if (NULL == cstr) {
	CFRelease(memory);
	return NULL;
    }
    UErrorCode status = U_ZERO_ERROR;
    memory->_nf = __cficu_unum_open((UNumberFormatStyle)ustyle, NULL, 0, cstr, NULL, &status);
    CFAssert(memory->_nf, __kCFLogAssertion, "%s(): error (%d) creating number formatter", __PRETTY_FUNCTION__, status);
    if (NULL == memory->_nf) {
	CFRelease(memory);
	return NULL;
    }
    UChar ubuff[4];
    if (kCFNumberFormatterNoStyle == style) {
        status = U_ZERO_ERROR;
	ubuff[0] = '#'; ubuff[1] = ';'; ubuff[2] = '#';
        __cficu_unum_applyPattern(memory->_nf, false, ubuff, 3, NULL, &status);
	__cficu_unum_setAttribute(memory->_nf, UNUM_MAX_INTEGER_DIGITS, 42);
	__cficu_unum_setAttribute(memory->_nf, UNUM_MAX_FRACTION_DIGITS, 0);
    }
    //Prior to Gala, CFLocaleCreateCopy() always just retained. This caused problems because CFLocaleGetValue(locale, kCFLocaleCalendarKey) would create a calendar, then set its locale to self, leading to a retain cycle
    //Since we're not in that situation here, and this is a frequently used path, we retain as we used to
    memory->_locale = locale ? CFRetain(locale) : CFLocaleGetSystem();
    __CFNumberFormatterCustomize(memory);
    if (kCFNumberFormatterSpellOutStyle != memory->_style && kCFNumberFormatterOrdinalStyle != memory->_style && kCFNumberFormatterCurrencyPluralStyle != memory->_style && kCFNumberFormatterDurationStyle != memory->_style) {
	UChar ubuffer[BUFFER_SIZE];
	status = U_ZERO_ERROR;
	int32_t ret = __cficu_unum_toPattern(memory->_nf, false, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
	    memory->_format = CFStringCreateWithCharacters(allocator, (const UniChar *)ubuffer, ret);
	}
    }
    memory->_defformat = memory->_format ? (CFStringRef)CFRetain(memory->_format) : NULL;
    memory->_compformat = memory->_format ? __CFNumberFormatterCreateCompressedString(memory->_format, true, NULL) : NULL;
    if (kCFNumberFormatterSpellOutStyle != memory->_style && kCFNumberFormatterOrdinalStyle != memory->_style && kCFNumberFormatterCurrencyPluralStyle != memory->_style && kCFNumberFormatterDurationStyle != memory->_style) {
	int32_t n = __cficu_unum_getAttribute(memory->_nf, UNUM_MULTIPLIER);
	if (1 != n) {
	    memory->_multiplier = CFNumberCreate(allocator, kCFNumberSInt32Type, &n);
	    __cficu_unum_setAttribute(memory->_nf, UNUM_MULTIPLIER, 1);
	}
    }
    __cficu_unum_setAttribute(memory->_nf, UNUM_LENIENT_PARSE, 0);
#if U_ICU_VERSION_MAJOR_NUM >= 53
    __cficu_unum_setContext(memory->_nf, UDISPCTX_CAPITALIZATION_NONE, &status);
#endif
    return (CFNumberFormatterRef)memory;
}

extern CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale);

static void __substituteFormatStringFromPrefsNF(CFNumberFormatterRef formatter) {
    CFIndex formatStyle = formatter->_style;
    if (kCFNumberFormatterSpellOutStyle == formatStyle) return;
    if (kCFNumberFormatterOrdinalStyle == formatStyle) return;
    if (kCFNumberFormatterDurationStyle == formatStyle) return;
    if (kCFNumberFormatterCurrencyPluralStyle == formatStyle) return;
    CFStringRef prefName = CFSTR("AppleICUNumberFormatStrings");
    if (kCFNumberFormatterNoStyle != formatStyle) {
	CFStringRef pref = NULL;
	CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
	CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, prefName) : NULL;
	if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
	    CFStringRef key;
	    switch (formatStyle) {
	    case kCFNumberFormatterDecimalStyle: key = CFSTR("1"); break;
	    case kCFNumberFormatterCurrencyStyle: key = CFSTR("2"); break;
	    case kCFNumberFormatterPercentStyle: key = CFSTR("3"); break;
	    case kCFNumberFormatterScientificStyle: key = CFSTR("4"); break;
	    case kCFNumberFormatterSpellOutStyle: key = CFSTR("5"); break;
	    case kCFNumberFormatterOrdinalStyle: key = CFSTR("6"); break;
	    case kCFNumberFormatterDurationStyle: key = CFSTR("7"); break;
	    case kCFNumberFormatterCurrencyISOCodeStyle: key = CFSTR("8"); break;
	    case kCFNumberFormatterCurrencyPluralStyle: key = CFSTR("9"); break;
#if U_ICU_VERSION_MAJOR_NUM >= 55
	    case kCFNumberFormatterCurrencyAccountingStyle: key = CFSTR("10"); break;
#endif
	    default: key = CFSTR("0"); break;
	    }
	    pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
	}
	if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) {
	    int32_t icustyle = UNUM_IGNORE;
	    switch (formatStyle) {
	    case kCFNumberFormatterDecimalStyle: icustyle = UNUM_DECIMAL; break;
	    case kCFNumberFormatterCurrencyStyle: icustyle = UNUM_CURRENCY; break;
	    case kCFNumberFormatterPercentStyle: icustyle = UNUM_PERCENT; break;
	    case kCFNumberFormatterScientificStyle: icustyle = UNUM_SCIENTIFIC; break;
	    case kCFNumberFormatterSpellOutStyle: icustyle = UNUM_SPELLOUT; break;
	    case kCFNumberFormatterOrdinalStyle: icustyle = UNUM_ORDINAL; break;
	    case kCFNumberFormatterDurationStyle: icustyle = UNUM_DURATION; break;
	    case kCFNumberFormatterCurrencyISOCodeStyle: icustyle = UNUM_CURRENCY_ISO; break;
	    case kCFNumberFormatterCurrencyPluralStyle: icustyle = UNUM_CURRENCY_PLURAL; break;
#if U_ICU_VERSION_MAJOR_NUM >= 55
	    case kCFNumberFormatterCurrencyAccountingStyle: icustyle = UNUM_CURRENCY_ACCOUNTING; break;
#endif
	    }
	    CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
	    char buffer[BUFFER_SIZE];
	    const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
	    if (NULL == cstr) {
		if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
	    }
	    UErrorCode status = U_ZERO_ERROR;
	    UNumberFormat *nf = __cficu_unum_open((UNumberFormatStyle)icustyle, NULL, 0, cstr, NULL, &status);
	    if (NULL != nf) {
		UChar ubuffer[BUFFER_SIZE];
		status = U_ZERO_ERROR;
		int32_t number_len = __cficu_unum_toPattern(nf, false, ubuffer, BUFFER_SIZE, &status);
		if (U_SUCCESS(status) && number_len <= BUFFER_SIZE) {
		    CFStringRef numberString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (const UniChar *)ubuffer, number_len);
		    status = U_ZERO_ERROR;
		    int32_t formatter_len = __cficu_unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
		    if (U_SUCCESS(status) && formatter_len <= BUFFER_SIZE) {
			CFMutableStringRef formatString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
			CFStringAppendCharacters(formatString, (const UniChar *)ubuffer, formatter_len);
			// find numberString inside formatString, substitute the pref in that range
			CFRange result;
			if (CFStringFindWithOptions(formatString, numberString, CFRangeMake(0, formatter_len), 0, &result)) {
			    CFStringReplace(formatString, result, pref);
			    __CFNumberFormatterApplyPattern(formatter, formatString);
			}
			CFRelease(formatString);
		    }
		    CFRelease(numberString);
		}
		__cficu_unum_close(nf);
	    }
	}
    }
}

static UniChar __CFNumberFormatterNormalizeCharacter(UniChar c) {
    if (CFCharacterSetIsCharacterMember(CFCharacterSetGetPredefined(kCFCharacterSetWhitespace), c)) {
	return ' ';
    } else {
	return c;
    }
}

/* Attempt to match the unimplemented lenient parsing behavior described at http://www.unicode.org/reports/tr35/#Lenient_Parsing -- specifically any whitespace is ignored that does not exist between two letters or two numbers, and no-break spaces map to spaces. */
static CFStringRef __CFNumberFormatterCreateCompressedString(CFStringRef inString, Boolean isFormat, CFRange *rangep) {
    if (!inString) return NULL;
    CFRange range = { 0, 0 };
    if (rangep) {
	range = *rangep;
    } else {
	range.length = CFStringGetLength(inString);
    }
    CFMutableStringRef outString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
    CFCharacterSetRef letters = CFCharacterSetGetPredefined(kCFCharacterSetLetter);
    CFCharacterSetRef numbers = CFCharacterSetGetPredefined(kCFCharacterSetDecimalDigit);
    UniChar prevCh = 0, nextCh = 0;
    Boolean inQuote = false;
    for (CFIndex in_idx = range.location; in_idx < range.location + range.length; in_idx++) {
        UniChar ch = __CFNumberFormatterNormalizeCharacter(CFStringGetCharacterAtIndex(inString, in_idx));
	nextCh = (in_idx+1 < range.length) ? CFStringGetCharacterAtIndex(inString, in_idx+1) : 0;
	if (isFormat && ch == '\'') inQuote = !inQuote;
	if (inQuote || ch != ' ' || (CFCharacterSetIsCharacterMember(letters, prevCh) && CFCharacterSetIsCharacterMember(letters, nextCh)) || (CFCharacterSetIsCharacterMember(numbers, prevCh) && CFCharacterSetIsCharacterMember(numbers, nextCh))) {
	    CFStringAppendCharacters(outString, &ch, 1);
	    prevCh = ch;
	}
    }
    return outString;
}

// Should not be called for rule-based ICU formatters; not supported
static void __CFNumberFormatterApplySymbolPrefs(const void *key, const void *value, void *context) {
    if (CFGetTypeID(key) == CFStringGetTypeID() && CFGetTypeID(value) == CFStringGetTypeID()) {
	CFNumberFormatterRef formatter = (CFNumberFormatterRef)context;
	UNumberFormatSymbol sym = (UNumberFormatSymbol)CFStringGetIntValue((CFStringRef)key);
	CFStringRef item = (CFStringRef)value;
	CFIndex item_cnt = CFStringGetLength(item);
	STACK_BUFFER_DECL(UChar, item_buffer, item_cnt);
	UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item);
	if (NULL == item_ustr) {
	    CFStringGetCharacters(item, CFRangeMake(0, __CFMin(BUFFER_SIZE, item_cnt)), (UniChar *)item_buffer);
	    item_ustr = item_buffer;
	}
	UErrorCode status = U_ZERO_ERROR;
	__cficu_unum_setSymbol(formatter->_nf, sym, item_ustr, item_cnt, &status);
   }
}

// Should not be called for rule-based ICU formatters
static UErrorCode __CFNumberFormatterApplyPattern(CFNumberFormatterRef formatter, CFStringRef pattern) {
    if (kCFNumberFormatterSpellOutStyle == formatter->_style) return U_UNSUPPORTED_ERROR;
    if (kCFNumberFormatterOrdinalStyle == formatter->_style) return U_UNSUPPORTED_ERROR;
    if (kCFNumberFormatterDurationStyle == formatter->_style) return U_UNSUPPORTED_ERROR;
    if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style) return U_UNSUPPORTED_ERROR;
    CFIndex cnt = CFStringGetLength(pattern);
    STACK_BUFFER_DECL(UChar, ubuffer, cnt);
    const UChar *ustr = (const UChar *)CFStringGetCharactersPtr(pattern);
    if (NULL == ustr) {
	CFStringGetCharacters(pattern, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	ustr = ubuffer;
    }
    UErrorCode status = U_ZERO_ERROR;
    __cficu_unum_applyPattern(formatter->_nf, false, ustr, cnt, NULL, &status);

    // __cficu_unum_applyPattern() may have magically changed other attributes based on
    // the contents of the format string; we simply expose that ICU behavior, except
    // for UNUM_MULTIPLIER, which we re-read and reset, like we did at initialization
    // time though any user-set multiplier state takes precedence.
    if (formatter->_userSetMultiplier) {
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
    } else {
	if (formatter->_multiplier) CFRelease(formatter->_multiplier);
        formatter->_multiplier = NULL;
        int32_t n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MULTIPLIER);
        if (1 != n) {
	    formatter->_multiplier = CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	    __cficu_unum_setAttribute(formatter->_nf, UNUM_MULTIPLIER, 1);
        }
    }
    return status;
}

static void __CFNumberFormatterCustomize(CFNumberFormatterRef formatter) {
    __substituteFormatStringFromPrefsNF(formatter);
    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
    CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUNumberSymbols")) : NULL;
    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
	CFDictionaryApplyFunction((CFDictionaryRef)metapref, __CFNumberFormatterApplySymbolPrefs, formatter);
    }
}

CFLocaleRef CFNumberFormatterGetLocale(CFNumberFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    return formatter->_locale;
}

CFNumberFormatterStyle CFNumberFormatterGetStyle(CFNumberFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    return formatter->_style;
}

CFStringRef CFNumberFormatterGetFormat(CFNumberFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    if (kCFNumberFormatterSpellOutStyle == formatter->_style) return NULL;
    if (kCFNumberFormatterOrdinalStyle == formatter->_style) return NULL;
    if (kCFNumberFormatterDurationStyle == formatter->_style) return NULL;
    if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style) return NULL;
    UChar ubuffer[BUFFER_SIZE];
    CFStringRef newString = NULL;
    UErrorCode status = U_ZERO_ERROR;
    int32_t ret = __cficu_unum_toPattern(formatter->_nf, false, ubuffer, BUFFER_SIZE, &status);
    if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
	newString = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ret);
    }
    if (newString && !formatter->_format) {
	formatter->_format = newString;
	if (formatter->_compformat) CFRelease(formatter->_compformat);
	formatter->_compformat = __CFNumberFormatterCreateCompressedString(formatter->_format, true, NULL);
    } else if (newString && !CFEqual(newString, formatter->_format)) {
	CFRelease(formatter->_format);
	formatter->_format = newString;
	if (formatter->_compformat) CFRelease(formatter->_compformat);
	formatter->_compformat = __CFNumberFormatterCreateCompressedString(formatter->_format, true, NULL);
    } else if (newString) {
	CFRelease(newString);
    }
    return formatter->_format;
}

void CFNumberFormatterSetFormat(CFNumberFormatterRef formatter, CFStringRef formatString) {
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(formatString, CFStringGetTypeID());
    if (kCFNumberFormatterSpellOutStyle == formatter->_style) return;
    if (kCFNumberFormatterOrdinalStyle == formatter->_style) return;
    if (kCFNumberFormatterDurationStyle == formatter->_style) return;
    if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style) return;
    CFIndex cnt = CFStringGetLength(formatString);
    CFAssert(cnt <= 1024, __kCFLogAssertion, "%s(): format string too long", __PRETTY_FUNCTION__);
    if ((!formatter->_format || !CFEqual(formatter->_format, formatString)) && cnt <= 1024) {
	UErrorCode status = __CFNumberFormatterApplyPattern(formatter, formatString);
	if (U_SUCCESS(status)) {
	    UChar ubuffer2[BUFFER_SIZE];
	    status = U_ZERO_ERROR;
	    int32_t ret = __cficu_unum_toPattern(formatter->_nf, false, ubuffer2, BUFFER_SIZE, &status);
	    if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
	        if (formatter->_format) CFRelease(formatter->_format);
		formatter->_format = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer2, ret);
		if (formatter->_compformat) CFRelease(formatter->_compformat);
		formatter->_compformat = __CFNumberFormatterCreateCompressedString(formatter->_format, true, NULL);
	    }
	}
    }
}

#define GET_MULTIPLIER                      \
        double multiplier = 1.0;            \
        double dummy = 0.0;                 \
        if (formatter->_multiplier) {       \
            if (!CFNumberGetValue(formatter->_multiplier, kCFNumberFloat64Type, &multiplier)) { \
                multiplier = 1.0;           \
            }                               \
        }                                   \
        if (modf(multiplier, &dummy) < FLT_EPSILON) {   \
            multiplier = floor(multiplier);             \
        }

CFStringRef CFNumberFormatterCreateStringWithNumber(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFNumberRef number) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(number, CFNumberGetTypeID());
    // The values of CFNumbers with large unsigned 64-bit ints don't survive well through this
    CFNumberType type = CFNumberGetType(number);
    char buffer[64];
    CFNumberGetValue(number, type, buffer);
    return CFNumberFormatterCreateStringWithValue(allocator, formatter, type, buffer);
}

#define FORMAT_FLT(T, FUNC)							\
	T value;\
        memcpy(&value, valuePtr, sizeof(T));\
	if (0 == value && formatter->_zeroSym) { return (CFStringRef)CFRetain(formatter->_zeroSym); }	\
	if (1.0 != multiplier) {					\
		value = (T)(value * multiplier);                     \
	}								\
	status = U_ZERO_ERROR;						\
	used = FUNC(formatter->_nf, value, ubuffer + 1, cnt, NULL, &status); \
	if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {		\
	    cnt = used + 1 + 1;						\
	    ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0); \
	    status = U_ZERO_ERROR;					\
	    used = FUNC(formatter->_nf, value, ustr + 1, cnt, NULL, &status); \
	}

#define FORMAT_INT(T, FUN)   \
        T value;\
        memcpy(&value, valuePtr, sizeof(T));\
        if (0 == value && formatter->_zeroSym) { return (CFStringRef)CFRetain(formatter->_zeroSym); }	\
        if (1.0 != multiplier) {					\
            value = (T)(value * multiplier);                        \
        }                                                           \
        _CFBigNum bignum;                                           \
        FUN(&bignum, value);                                        \
        char buffer[BUFFER_SIZE + 1];                                           \
        _CFBigNumToCString(&bignum, false, true, buffer, BUFFER_SIZE);      \
        status = U_ZERO_ERROR;                                      \
        used = __cficu_unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ubuffer + 1, BUFFER_SIZE, NULL, &status);     \
        if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {      \
            cnt = used + 1 + 1;                                         \
            ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0);                 \
            status = U_ZERO_ERROR;                                  \
            used = __cficu_unum_formatDecimal(formatter->_nf, buffer, strlen(buffer), ustr + 1, cnt, NULL, &status);            \
        }                                                           \

CFStringRef CFNumberFormatterCreateStringWithValue(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFNumberType numberType, const void *valuePtr) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    GET_MULTIPLIER;
    UChar *ustr = NULL, ubuffer[BUFFER_SIZE + 1];
    UErrorCode status = U_ZERO_ERROR;
    CFIndex used, cnt = BUFFER_SIZE;
    if (numberType == kCFNumberFloat64Type || numberType == kCFNumberDoubleType) {
	FORMAT_FLT(double, __cficu_unum_formatDouble)
    } else if (numberType == kCFNumberFloat32Type || numberType == kCFNumberFloatType) {
	FORMAT_FLT(float, __cficu_unum_formatDouble)
    } else if (numberType == kCFNumberSInt64Type || numberType == kCFNumberLongLongType) {
	FORMAT_INT(int64_t, _CFBigNumInitWithInt64)
    } else if (numberType == kCFNumberLongType || numberType == kCFNumberCFIndexType) {
#if __LP64__
	FORMAT_INT(int64_t, _CFBigNumInitWithInt64)
#else
	FORMAT_INT(int32_t, _CFBigNumInitWithInt32)
#endif
    } else if (numberType == kCFNumberSInt32Type || numberType == kCFNumberIntType) {
	FORMAT_INT(int32_t, _CFBigNumInitWithInt32)
    } else if (numberType == kCFNumberSInt16Type || numberType == kCFNumberShortType) {
	FORMAT_INT(int16_t, _CFBigNumInitWithInt16)
    } else if (numberType == kCFNumberSInt8Type || numberType == kCFNumberCharType) {
	FORMAT_INT(int8_t, _CFBigNumInitWithInt8)
    } else {
	CFAssert(0, __kCFLogAssertion, "%s(): unknown CFNumberType (%d)", __PRETTY_FUNCTION__, numberType);
	return NULL;
    }
    CFStringRef string = NULL;
    if (U_SUCCESS(status)) {
        UniChar *bufferToUse = ustr ? (UniChar *)ustr : (UniChar *)ubuffer;
        if (formatter->_usesCharacterDirection && CFLocaleGetLanguageCharacterDirection(CFLocaleGetIdentifier(formatter->_locale)) == kCFLocaleLanguageDirectionRightToLeft) {
            // Insert Unicode RTL marker
            bufferToUse[0] = 0x200F;
            used++;
        } else {
            // Move past direction marker
            bufferToUse++;
        }
        string = CFStringCreateWithCharacters(allocator, bufferToUse, used);
    }
    if (ustr) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ustr);
    return string;
}

#undef FORMAT_FLT
#undef FORMAT_INT
#undef GET_MULTIPLIER

CFNumberRef CFNumberFormatterCreateNumberFromString(CFAllocatorRef allocator, CFNumberFormatterRef formatter, CFStringRef string, CFRange *rangep, CFOptionFlags options) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(string, CFStringGetTypeID());
    char buffer[16] __attribute__ ((aligned (8)));
    CFRange r = rangep ? *rangep : CFRangeMake(0, CFStringGetLength(string));
    CFNumberRef multiplierRef = formatter->_multiplier;
    formatter->_multiplier = NULL;
    Boolean b = CFNumberFormatterGetValueFromString(formatter, string, &r, kCFNumberSInt64Type, buffer);
    formatter->_multiplier = multiplierRef;
    if (b) {
        Boolean passedMultiplier = true;
        // We handle the multiplier case here manually; the final
        // result is supposed to be (parsed value) / (multiplier), but
        // the int case here should only succeed if the parsed value
        // is an exact multiple of the multiplier.
        if (multiplierRef) {
            int64_t tmp = *(int64_t *)buffer;
            double multiplier = 1.0;
            if (!CFNumberGetValue(multiplierRef, kCFNumberFloat64Type, &multiplier)) {
                multiplier = 1.0;
            }
            double dummy;
            if (llabs(tmp) < fabs(multiplier)) {
                passedMultiplier = false;
            } else if (fabs(multiplier) < 1.0) { // We can't handle this math yet
                passedMultiplier = false;
            } else if (modf(multiplier, &dummy) == 0.0) { // multiplier is an integer
                int64_t imult = (int64_t)multiplier;
                int64_t rem = tmp % imult;
                if (rem != 0) passedMultiplier = false;
                if (passedMultiplier) {
                    tmp = tmp / imult;
                    *(int64_t *)buffer = tmp;
                }
            } else if (multiplier == -1.0) { // simple
                tmp = tmp * -1;
                *(int64_t *)buffer = tmp;
            } else if (multiplier != 1.0) {
                // First, throw away integer multiples of the multiplier to
                // bring the value down to less than 2^53, so that we can
                // cast it to double without losing any precision, important
                // for the "remainder is zero" test.
                // Find power of two which, when multiplier is multiplied by it,
                // results in an integer value. pwr will be <= 52 since multiplier
                // is at least 1.
                int pwr = 0;
                double intgrl;
                while (modf(scalbn(multiplier, pwr), &intgrl) != 0.0) pwr++;
                int64_t i2 = (int64_t)intgrl;
                // scale pwr and i2 up to a reasonably large value so the next loop doesn't take forever
                while (llabs(i2) < (1LL << 50)) { i2 *= 2; pwr++; }
                int64_t cnt = 0;
                while ((1LL << 53) <= llabs(tmp)) {
		    // subtract (multiplier * 2^pwr) each time
                    tmp -= i2; // move tmp toward zero
                    cnt += (1LL << pwr); // remember how many 2^pwr we subtracted
                }
                // If the integer is less than 2^53, there is no loss
                // in converting it to double, so we can just do the
                // direct operation now.
                double rem = fmod((double)tmp, multiplier);
                if (rem != 0.0) passedMultiplier = false;
                if (passedMultiplier) {
		    // The original tmp, which we need to divide by multiplier, is at this point:
                    //   tmp + k * 2^n * multiplier, where k is the number of loop iterations
                    // That original value needs to be divided by multiplier and put back in the
                    // buffer.  Noting that k * 2^n == cnt, and after some algebra, we have:
                    tmp = (int64_t)((double)tmp / multiplier) + cnt;
                    *(int64_t *)buffer = tmp;
                }
            }
        }
        if (passedMultiplier && ((r.length == CFStringGetLength(string)) || (options & kCFNumberFormatterParseIntegersOnly))) {
            if (rangep) *rangep = r;
	    return CFNumberCreate(allocator, kCFNumberSInt64Type, buffer);
        }
    }
    if (options & kCFNumberFormatterParseIntegersOnly) return NULL;
    if (CFNumberFormatterGetValueFromString(formatter, string, rangep, kCFNumberFloat64Type, buffer)) {
	return CFNumberCreate(allocator, kCFNumberFloat64Type, buffer);
    }
    return NULL;
}

Boolean CFNumberFormatterGetValueFromString(CFNumberFormatterRef formatter, CFStringRef string, CFRange *rangep, CFNumberType numberType, void *valuePtr) {
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(string, CFStringGetTypeID());
    CFStringRef stringToParse = formatter->_isLenient ? __CFNumberFormatterCreateCompressedString(string, false, rangep) : (CFStringRef)CFRetain(string);
    CFRange range = {0, 0};
    if(formatter->_isLenient) {
        range.length = CFStringGetLength(stringToParse);
    } else {
        if (rangep) {
            range = *rangep;
        } else {
            range.length = CFStringGetLength(stringToParse);
        }
        // __cficu_unum_parse chokes on leading whitespace
        CFCharacterSetRef whitespace = CFCharacterSetGetPredefined(kCFCharacterSetWhitespace);
        while(range.length > 0 && CFCharacterSetIsCharacterMember(whitespace, CFStringGetCharacterAtIndex(stringToParse, range.location))) {
            range.location++;
            range.length--;
        }
    }
    Boolean isZero = false;
    if (formatter->_zeroSym) {
	CFStringRef zeroSym = formatter->_isLenient ? __CFNumberFormatterCreateCompressedString(formatter->_zeroSym, false, NULL) : (CFStringRef)CFRetain(formatter->_zeroSym);
	if (kCFCompareEqualTo == CFStringCompare(stringToParse, zeroSym, 0)) {
	    isZero = true;
	}
	CFRelease(zeroSym);
    }
    if (1024 < range.length) range.length = 1024;
    const UChar *ustr = (const UChar *)CFStringGetCharactersPtr(stringToParse);
    STACK_BUFFER_DECL(UChar, ubuffer, (NULL == ustr) ? range.length : 1);
    if (NULL == ustr) {
	CFStringGetCharacters(stringToParse, range, (UniChar *)ubuffer);
	ustr = ubuffer;
    } else if (!formatter->_isLenient) {
	ustr += range.location;
    }
    CFNumberRef multiplierRef = formatter->_multiplier;
    formatter->_multiplier = NULL;
    if (formatter->_isLenient) {
        __CFNumberFormatterApplyPattern(formatter, formatter->_compformat);
        if (formatter->_multiplier) CFRelease(formatter->_multiplier);
        formatter->_multiplier = NULL;
    }
    Boolean integerOnly = 1;
    switch (numberType) {
    case kCFNumberSInt8Type: case kCFNumberCharType:
    case kCFNumberSInt16Type: case kCFNumberShortType:
    case kCFNumberSInt32Type: case kCFNumberIntType:
    case kCFNumberLongType: case kCFNumberCFIndexType:
    case kCFNumberSInt64Type: case kCFNumberLongLongType:
	__cficu_unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 1); // ignored by ICU for rule-based formatters
	break;
    default:
	__cficu_unum_setAttribute(formatter->_nf, UNUM_PARSE_INT_ONLY, 0); // ignored by ICU for rule-based formatters
	integerOnly = 0;
	break;
    }
    int32_t dpos = 0;
    UErrorCode status = U_ZERO_ERROR;
    int64_t dreti = 0;
    double dretd = 0.0;
    if (isZero) {
	dpos = rangep ? rangep->length : 0;
    } else {
	char buffer[1024];
        memset(buffer, 0, sizeof(buffer));
	int32_t len = __cficu_unum_parseDecimal(formatter->_nf, ustr, range.length, &dpos, buffer, sizeof(buffer), &status);
        if (!U_FAILURE(status) && 0 < len && integerOnly) {
	    char *endptr = NULL;
	    errno = 0;
	    dreti = strtoll_l(buffer, &endptr, 10, NULL);
	    if (!(errno == 0 && *endptr == '\0')) status = U_INVALID_FORMAT_ERROR;
	}
	if (!U_FAILURE(status) && 0 < len) {
	    char *endptr = NULL;
	    errno = 0;
	    dretd = strtod_l(buffer, &endptr, NULL);
	    if (!(errno == 0 && *endptr == '\0')) status = U_INVALID_FORMAT_ERROR;
	}
    }
    if (formatter->_isLenient) {
	if (rangep) {
	    CFIndex uncompEnd = rangep->location + rangep->length;
	    CFIndex uncompIdx = rangep->location;
	    for (CFIndex compIdx = 0; compIdx < dpos && uncompIdx < uncompEnd; compIdx++, uncompIdx++) {
		while (uncompIdx < uncompEnd && ustr[compIdx] != __CFNumberFormatterNormalizeCharacter(CFStringGetCharacterAtIndex(string, uncompIdx))) uncompIdx++;
	    }
	    rangep->length = uncompIdx - rangep->location;
	}
	__CFNumberFormatterApplyPattern(formatter, formatter->_format);
        if (formatter->_multiplier) CFRelease(formatter->_multiplier);
        formatter->_multiplier = NULL;
    } else if (rangep) {
        rangep->length = dpos + (range.location - rangep->location);
    }
    formatter->_multiplier = multiplierRef;
    CFRelease(stringToParse);
    if (U_FAILURE(status)) {
	return false;
    }
    if (formatter->_multiplier) {
        double multiplier = 1.0;
        if (!CFNumberGetValue(formatter->_multiplier, kCFNumberFloat64Type, &multiplier)) {
            multiplier = 1.0;
        }
        dreti = (int64_t)((double)dreti / multiplier); // integer truncation, plus double cast can be lossy for dreti > 2^53
        dretd = dretd / multiplier;
    }
    switch (numberType) {
    case kCFNumberSInt8Type: case kCFNumberCharType:
	if (INT8_MIN <= dreti && dreti <= INT8_MAX) {
	    *(int8_t *)valuePtr = (int8_t)dreti;
	    return true;
	}
	break;
    case kCFNumberSInt16Type: case kCFNumberShortType:
	if (INT16_MIN <= dreti && dreti <= INT16_MAX) {
	    *(int16_t *)valuePtr = (int16_t)dreti;
	    return true;
	}
	break;
    case kCFNumberSInt32Type: case kCFNumberIntType:
#if !__LP64__
    case kCFNumberLongType: case kCFNumberCFIndexType:
#endif
	if (INT32_MIN <= dreti && dreti <= INT32_MAX) {
	    *(int32_t *)valuePtr = (int32_t)dreti;
	    return true;
	}
	break;
    case kCFNumberSInt64Type: case kCFNumberLongLongType:
#if __LP64__
    case kCFNumberLongType: case kCFNumberCFIndexType:
#endif
	if (INT64_MIN <= dreti && dreti <= INT64_MAX) {
	    *(int64_t *)valuePtr = (int64_t)dreti;
	    return true;
	}
	break;
    case kCFNumberFloat32Type: case kCFNumberFloatType:
	if (-FLT_MAX <= dretd && dretd <= FLT_MAX) {
	    *(float *)valuePtr = (float)dretd;
	    return true;
	}
	break;
    case kCFNumberFloat64Type: case kCFNumberDoubleType:
	if (-DBL_MAX <= dretd && dretd <= DBL_MAX) {
	    *(double *)valuePtr = (double)dretd;
	    return true;
	}
	break;
    }
    return false;
}

void CFNumberFormatterSetProperty(CFNumberFormatterRef formatter, CFStringRef key, CFTypeRef value) {
    int32_t n;
    double d;
    UErrorCode status = U_ZERO_ERROR;
    UChar ubuffer[BUFFER_SIZE];
    CFIndex cnt;
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(key, CFStringGetTypeID());
    // rule-based formatters don't do attributes and symbols, except for one
    if (CFEqual(kCFNumberFormatterFormattingContextKey, key)) {
#if U_ICU_VERSION_MAJOR_NUM >= 55
        __CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
        __cficu_unum_setContext(formatter->_nf, n, &status);
#endif
    }
    if (kCFNumberFormatterSpellOutStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return;
    if (kCFNumberFormatterOrdinalStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return;
    if (kCFNumberFormatterDurationStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return;
    if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return;
    if (kCFNumberFormatterCurrencyCodeKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterDecimalSeparatorKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterCurrencyDecimalSeparatorKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterAlwaysShowDecimalSeparatorKey == key) {
	__CFGenericValidateType(value, CFBooleanGetTypeID());
	__cficu_unum_setAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN, (kCFBooleanTrue == value));
    } else if (kCFNumberFormatterGroupingSeparatorKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, (const UChar *)ubuffer, cnt, &status);
    } else if (kCFNumberFormatterUseGroupingSeparatorKey == key) {
	__CFGenericValidateType(value, CFBooleanGetTypeID());
	__cficu_unum_setAttribute(formatter->_nf, UNUM_GROUPING_USED, (kCFBooleanTrue == value));
    } else if (kCFNumberFormatterPercentSymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterZeroSymbolKey == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
        CFStringRef old = formatter->_zeroSym;
        formatter->_zeroSym = value ? (CFStringRef)CFRetain(value) : NULL;
        if (old) CFRelease(old);
    } else if (kCFNumberFormatterNaNSymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterInfinitySymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterMinusSignKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterPlusSignKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterCurrencySymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, (const UChar *)ubuffer, cnt, &status);
    } else if (kCFNumberFormatterExponentSymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterMinIntegerDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS, n);
    } else if (kCFNumberFormatterMaxIntegerDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS, n);
    } else if (kCFNumberFormatterMinFractionDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS, n);
    } else if (kCFNumberFormatterMaxFractionDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS, n);
    } else if (kCFNumberFormatterGroupingSizeKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_GROUPING_SIZE, n);
    } else if (kCFNumberFormatterSecondaryGroupingSizeKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE, n);
    } else if (kCFNumberFormatterRoundingModeKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_ROUNDING_MODE, n);
    } else if (kCFNumberFormatterRoundingIncrementKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberDoubleType, &d);
	__cficu_unum_setDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT, d);
    } else if (kCFNumberFormatterFormatWidthKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_FORMAT_WIDTH, n);
    } else if (kCFNumberFormatterPaddingPositionKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_PADDING_POSITION, n);
    } else if (kCFNumberFormatterPaddingCharacterKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterDefaultFormatKey == key) {
	// read-only attribute
    } else if (kCFNumberFormatterMultiplierKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
        CFNumberRef old = formatter->_multiplier;
        formatter->_multiplier = value ? (CFNumberRef)CFRetain(value) : NULL;
	formatter->_userSetMultiplier = value ? true : false;
        if (old) CFRelease(old);
    } else if (kCFNumberFormatterPositivePrefixKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterPositiveSuffixKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
    } else if (kCFNumberFormatterNegativePrefixKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterNegativeSuffixKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	cnt = CFStringGetLength((CFStringRef)value);
	if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
	CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
	__cficu_unum_setTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, (const UChar *)ubuffer, cnt, &status);
    } else if (kCFNumberFormatterPerMillSymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
        __cficu_unum_setSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterInternationalCurrencySymbolKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
        __cficu_unum_setSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterCurrencyGroupingSeparatorKey == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
        cnt = CFStringGetLength((CFStringRef)value);
        if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
        CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, cnt), (UniChar *)ubuffer);
        __cficu_unum_setSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, cnt, &status);
    } else if (kCFNumberFormatterIsLenientKey == key) {
	__CFGenericValidateType(value, CFBooleanGetTypeID());
	formatter->_isLenient = (kCFBooleanTrue == value);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_LENIENT_PARSE, (kCFBooleanTrue == value));
    } else if (kCFNumberFormatterUseSignificantDigitsKey == key) {
	__CFGenericValidateType(value, CFBooleanGetTypeID());
	__cficu_unum_setAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED, (kCFBooleanTrue == value));
    } else if (kCFNumberFormatterMinSignificantDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS, n);
    } else if (kCFNumberFormatterMaxSignificantDigitsKey == key) {
	__CFGenericValidateType(value, CFNumberGetTypeID());
	CFNumberGetValue((CFNumberRef)value, kCFNumberSInt32Type, &n);
	__cficu_unum_setAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS, n);
    } else if (kCFNumberFormatterUsesCharacterDirectionKey == key) {
        __CFGenericValidateType(value, CFBooleanGetTypeID());
        formatter->_usesCharacterDirection = value == kCFBooleanTrue;
    } else {
	CFAssert(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
    }
    if (_CFExecutableLinkedOnOrAfter(CFSystemVersionSnowLeopard)) {
        // do a dummy call to CFNumberFormatterGetFormat() after changing an attribute because
        // ICU sometimes changes the pattern due to a property change, and we need to poke
        // __cficu_unum_toPattern() and also update our own variables
        CFNumberFormatterGetFormat(formatter);
    }
}

CFTypeRef CFNumberFormatterCopyProperty(CFNumberFormatterRef formatter, CFStringRef key) {
    int32_t n;
    double d;
    UErrorCode status = U_ZERO_ERROR;
    UChar ubuffer[BUFFER_SIZE];
    CFIndex cnt;
    __CFGenericValidateType(formatter, CFNumberFormatterGetTypeID());
    __CFGenericValidateType(key, CFStringGetTypeID());
    // rule-based formatters don't do attributes and symbols, except for one
    if (CFEqual(kCFNumberFormatterFormattingContextKey, key)) {
#if U_ICU_VERSION_MAJOR_NUM >= 55
        n = __cficu_unum_getContext(formatter->_nf, UDISPCTX_TYPE_CAPITALIZATION, &status);
        if (1) {
            return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
        }
#endif
    }
    if (kCFNumberFormatterSpellOutStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
    if (kCFNumberFormatterOrdinalStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
    if (kCFNumberFormatterDurationStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
    if (kCFNumberFormatterCurrencyPluralStyle == formatter->_style && kCFNumberFormatterIsLenientKey != key) return NULL;
    if (kCFNumberFormatterCurrencyCodeKey == key) {
	cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt == 0) {
	    CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
	    char buffer[BUFFER_SIZE];
	    const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
	    if (NULL == cstr) {
		if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
	    }
	    if (NULL == cstr) {
	        return NULL;
	    }
	    UErrorCode status = U_ZERO_ERROR;
	    UNumberFormat *nf = __cficu_unum_open(UNUM_CURRENCY, NULL, 0, cstr, NULL, &status);
	    if (NULL != nf) {
		cnt = __cficu_unum_getTextAttribute(nf, UNUM_CURRENCY_CODE, ubuffer, BUFFER_SIZE, &status);
		__cficu_unum_close(nf);
	    }
	}
	if (U_SUCCESS(status) && 0 < cnt && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterDecimalSeparatorKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_DECIMAL_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterCurrencyDecimalSeparatorKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MONETARY_SEPARATOR_SYMBOL, (UChar *)ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterAlwaysShowDecimalSeparatorKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_DECIMAL_ALWAYS_SHOWN);
	if (1) {
	    return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
	}
    } else if (kCFNumberFormatterGroupingSeparatorKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterUseGroupingSeparatorKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_GROUPING_USED);
	if (1) {
	    return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
	}
   } else if (kCFNumberFormatterPercentSymbolKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PERCENT_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterZeroSymbolKey == key) {
        return formatter->_zeroSym ? CFRetain(formatter->_zeroSym) : NULL;
    } else if (kCFNumberFormatterNaNSymbolKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_NAN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterInfinitySymbolKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_INFINITY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterMinusSignKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MINUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterPlusSignKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PLUS_SIGN_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterCurrencySymbolKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterExponentSymbolKey == key) {
	cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_EXPONENTIAL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterMinIntegerDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_INTEGER_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterMaxIntegerDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_INTEGER_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterMinFractionDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_FRACTION_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterMaxFractionDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_FRACTION_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterGroupingSizeKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_GROUPING_SIZE);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterSecondaryGroupingSizeKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_SECONDARY_GROUPING_SIZE);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterRoundingModeKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_ROUNDING_MODE);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterRoundingIncrementKey == key) {
	d = __cficu_unum_getDoubleAttribute(formatter->_nf, UNUM_ROUNDING_INCREMENT);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberDoubleType, &d);
	}
    } else if (kCFNumberFormatterFormatWidthKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_FORMAT_WIDTH);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterPaddingPositionKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_PADDING_POSITION);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterPaddingCharacterKey == key) {
	cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_PADDING_CHARACTER, ubuffer, BUFFER_SIZE, &status);
	if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
	    return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
	}
    } else if (kCFNumberFormatterDefaultFormatKey == key) {
	return formatter->_defformat ? CFRetain(formatter->_defformat) : NULL;
    } else if (kCFNumberFormatterMultiplierKey == key) {
        return formatter->_multiplier ? CFRetain(formatter->_multiplier) : NULL;
    } else if (kCFNumberFormatterPositivePrefixKey == key) {
        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterPositiveSuffixKey == key) {
        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_POSITIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterNegativePrefixKey == key) {
        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_PREFIX, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterNegativeSuffixKey == key) {
        cnt = __cficu_unum_getTextAttribute(formatter->_nf, UNUM_NEGATIVE_SUFFIX, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterPerMillSymbolKey == key) {
        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_PERMILL_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterInternationalCurrencySymbolKey == key) {
        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_INTL_CURRENCY_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterCurrencyGroupingSeparatorKey == key) {
        cnt = __cficu_unum_getSymbol(formatter->_nf, UNUM_MONETARY_GROUPING_SEPARATOR_SYMBOL, ubuffer, BUFFER_SIZE, &status);
        if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
            return CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, cnt);
        }
    } else if (kCFNumberFormatterIsLenientKey == key) {
	// __cficu_unum_getAttribute(, UNUM_LENIENT_PARSE) is undefined.
	return CFRetain(formatter->_isLenient ? kCFBooleanTrue : kCFBooleanFalse);
    } else if (kCFNumberFormatterUseSignificantDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_SIGNIFICANT_DIGITS_USED);
	if (1) {
	    return CFRetain(n ? kCFBooleanTrue : kCFBooleanFalse);
	}
    } else if (kCFNumberFormatterMinSignificantDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MIN_SIGNIFICANT_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else if (kCFNumberFormatterMaxSignificantDigitsKey == key) {
	n = __cficu_unum_getAttribute(formatter->_nf, UNUM_MAX_SIGNIFICANT_DIGITS);
	if (1) {
	    return CFNumberCreate(CFGetAllocator(formatter), kCFNumberSInt32Type, &n);
	}
    } else {
	CFAssert(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
    }
    return NULL;
}


Boolean CFNumberFormatterGetDecimalInfoForCurrencyCode(CFStringRef currencyCode, int32_t *defaultFractionDigits, double *roundingIncrement) {
    UChar ubuffer[4];
    __CFGenericValidateType(currencyCode, CFStringGetTypeID());
    CFAssert(3 == CFStringGetLength(currencyCode), __kCFLogAssertion, "%s(): currencyCode is not 3 characters", __PRETTY_FUNCTION__);
    CFStringGetCharacters(currencyCode, CFRangeMake(0, 3), (UniChar *)ubuffer);
    ubuffer[3] = 0;
    UErrorCode icuStatus = U_ZERO_ERROR;
    if (defaultFractionDigits) *defaultFractionDigits = __cficu_ucurr_getDefaultFractionDigits(ubuffer, &icuStatus);
    if (roundingIncrement) *roundingIncrement = __cficu_ucurr_getRoundingIncrement(ubuffer, &icuStatus);
    if (U_FAILURE(icuStatus))
        return false;
    return (!defaultFractionDigits || 0 <= *defaultFractionDigits) && (!roundingIncrement || 0.0 <= *roundingIncrement);
}

// This is for NSNumberFormatter use only!
void *_CFNumberFormatterGetFormatter(CFNumberFormatterRef formatter) {
    return (void *)formatter->_nf;
}

#undef BUFFER_SIZE

