10596faeddefbf198de137d5e893708495ab1584cFredrik Roubert// © 2016 and later: Unicode, Inc. and others. 264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 5c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert* Copyright (C) 1997-2015, International Business Machines Corporation 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* and others. All Rights Reserved. 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 10fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/utypes.h" 1154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "utypeinfo.h" // for 'typeid' to work 1227f654740f2a26ad62a5c155af9199af9e69b889claireho 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/rbnf.h" 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_HAVE_RBNF 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/normlzr.h" 18f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unicode/plurfmt.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/tblcoll.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucol.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uloc.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unum.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ures.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utf16.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 28fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/udisplaycontext.h" 29fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/brkiter.h" 300596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "unicode/ucasemap.h" 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 34b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h" 3585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uresimp.h" 360596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "nfrs.h" 370596faeddefbf198de137d5e893708495ab1584cFredrik Roubert#include "digitlst.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// debugging 40f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// #define RBNF_DEBUG 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 42f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#ifdef RBNF_DEBUG 43c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert#include <stdio.h> 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_ICUDATA_RBNF U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf" 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gPercentPercent[] = 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x25, 0x25, 0 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* "%%" */ 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// All urbnf objects are created through openRules, so we init all of the 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Unicode string constants required by rbnf, nfrs, or nfr here. 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gLenientParse[] = 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x25, 0x25, 0x6C, 0x65, 0x6E, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x70, 0x61, 0x72, 0x73, 0x65, 0x3A, 0 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* "%%lenient-parse:" */ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gSemiColon = 0x003B; 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gSemiPercent[] = 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x3B, 0x25, 0 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* ";%" */ 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kSomeNumberOfBitsDiv2 22 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kHalfMaxDouble (double)(1 << kSomeNumberOfBitsDiv2) 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kMaxDouble (kHalfMaxDouble * kHalfMaxDouble) 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedNumberFormat) 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThis is a utility class. It does not use ICU's RTTI. 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIf ICU's RTTI is needed again, you can uncomment the RTTI code and derive from UObject. 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruPlease make sure that intltest passes on Windows in Release mode, 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querusince the string pooling per compilation unit will mess up how RTTI works. 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThe RTTI code was also removed due to lack of code coverage. 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocalizationInfo : public UMemory { 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprotected: 82103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius virtual ~LocalizationInfo(); 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t refcount; 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo() : refcount(0) {} 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* ref(void) { 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++refcount; 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return this; 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* unref(void) { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (refcount && --refcount == 0) { 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete this; 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual UBool operator==(const LocalizationInfo* rhs) const; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline UBool operator!=(const LocalizationInfo* rhs) const { return !operator==(rhs); } 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfRuleSets(void) const = 0; 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getRuleSetName(int32_t index) const = 0; 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfDisplayLocales(void) const = 0; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getLocaleName(int32_t index) const = 0; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getDisplayName(int32_t localeIndex, int32_t ruleIndex) const = 0; 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t indexForLocale(const UChar* locale) const; 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t indexForRuleSet(const UChar* ruleset) const; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// virtual UClassID getDynamicClassID() const = 0; 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// static UClassID getStaticClassID(void); 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 116103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusLocalizationInfo::~LocalizationInfo() {} 117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(LocalizationInfo) 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if both strings are NULL, this returns TRUE 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustreq(const UChar* lhs, const UChar* rhs) { 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rhs == lhs) { 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lhs && rhs) { 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_strcmp(lhs, rhs) == 0; 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::operator==(const LocalizationInfo* rhs) const { 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rhs) { 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == rhs) { 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t rsc = getNumberOfRuleSets(); 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rsc == rhs->getNumberOfRuleSets()) { 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < rsc; ++i) { 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(getRuleSetName(i), rhs->getRuleSetName(i))) { 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t dlc = getNumberOfDisplayLocales(); 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dlc == rhs->getNumberOfDisplayLocales()) { 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < dlc; ++i) { 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* locale = getLocaleName(i); 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = rhs->indexForLocale(locale); 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if no locale, ix is -1, getLocaleName returns null, so streq returns false 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(locale, rhs->getLocaleName(ix))) { 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int j = 0; j < rsc; ++j) { 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(getDisplayName(i, j), rhs->getDisplayName(ix, j))) { 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::indexForLocale(const UChar* locale) const { 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < getNumberOfDisplayLocales(); ++i) { 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (streq(locale, getLocaleName(i))) { 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::indexForRuleSet(const UChar* ruleset) const { 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleset) { 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < getNumberOfRuleSets(); ++i) { 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (streq(ruleset, getRuleSetName(i))) { 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef void (*Fn_Deleter)(void*); 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass VArray { 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** buf; 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cap; 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t size; 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Fn_Deleter deleter; 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray() : buf(NULL), cap(0), size(0), deleter(NULL) {} 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray(Fn_Deleter del) : buf(NULL), cap(0), size(0), deleter(del) {} 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~VArray() { 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deleter) { 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < size; ++i) { 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*deleter)(buf[i]); 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(buf); 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length() { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return size; 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void add(void* elem, UErrorCode& status) { 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (size == cap) { 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cap == 0) { 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap = 1; 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (cap < 256) { 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap *= 2; 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap += 256; 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (buf == NULL) { 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = (void**)uprv_malloc(cap * sizeof(void*)); 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = (void**)uprv_realloc(buf, cap * sizeof(void*)); 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (buf == NULL) { 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if we couldn't realloc, we leak the memory we've already allocated, but we're in deep trouble anyway 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void* start = &buf[size]; 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size_t count = (cap - size) * sizeof(void*); 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(start, 0, count); // fill with nulls, just because 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[size++] = elem; 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** release(void) { 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** result = buf; 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = NULL; 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap = 0; 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size = 0; 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocDataParser; 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass StringLocalizationInfo : public LocalizationInfo { 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* info; 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar*** data; 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numRuleSets; 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numLocales; 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend class LocDataParser; 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo(UChar* i, UChar*** d, int32_t numRS, int32_t numLocs) 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : info(i), data(d), numRuleSets(numRS), numLocales(numLocs) 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static StringLocalizationInfo* create(const UnicodeString& info, UParseError& perror, UErrorCode& status); 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~StringLocalizationInfo(); 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfRuleSets(void) const { return numRuleSets; } 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getRuleSetName(int32_t index) const; 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfDisplayLocales(void) const { return numLocales; } 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getLocaleName(int32_t index) const; 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getDisplayName(int32_t localeIndex, int32_t ruleIndex) const; 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// virtual UClassID getDynamicClassID() const; 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// static UClassID getStaticClassID(void); 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void init(UErrorCode& status) const; 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OPEN_ANGLE = 0x003c, /* '<' */ 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CLOSE_ANGLE = 0x003e, /* '>' */ 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru COMMA = 0x002c, 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TICK = 0x0027, 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru QUOTE = 0x0022, 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SPACE = 0x0020 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Utility for parsing a localization string and returning a StringLocalizationInfo*. 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocDataParser { 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* data; 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* e; 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* p; 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar ch; 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& pe; 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& ec; 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocDataParser(UParseError& parseError, UErrorCode& status) 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : data(NULL), e(NULL), p(NULL), ch(0xffff), pe(parseError), ec(status) {} 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~LocDataParser() {} 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * On a successful parse, return a StringLocalizationInfo*, otherwise delete locData, set perror and status, 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and return NULL. The StringLocalizationInfo will adopt locData if it is created. 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo* parse(UChar* data, int32_t len); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 319ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inline void inc(void) { 320ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert ++p; 321ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert ch = 0xffff; 322ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 323ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inline UBool checkInc(UChar c) { 324ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert if (p < e && (ch == c || *p == c)) { 325ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inc(); 326ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return TRUE; 327ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 328ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return FALSE; 329ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 330ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inline UBool check(UChar c) { 331ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return p < e && (ch == c || *p == c); 332ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 333ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inline void skipWhitespace(void) { 334ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert while (p < e && PatternProps::isWhiteSpace(ch != 0xffff ? ch : *p)) { 335ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inc(); 336ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 337ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 338ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert inline UBool inList(UChar c, const UChar* list) const { 339ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert if (*list == SPACE && PatternProps::isWhiteSpace(c)) { 340ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return TRUE; 341ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 342ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert while (*list && *list != c) { 343ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert ++list; 344ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 345ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return *list == c; 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void parseError(const char* msg); 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo* doParse(void); 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar** nextArray(int32_t& requiredLength); 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* nextString(void); 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 355f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#ifdef RBNF_DEBUG 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ERROR(msg) parseError(msg); return NULL; 357fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#define EXPLANATION_ARG explanationArg 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ERROR(msg) parseError(NULL); return NULL; 360fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#define EXPLANATION_ARG 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar DQUOTE_STOPLIST[] = { 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru QUOTE, 0 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar SQUOTE_STOPLIST[] = { 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TICK, 0 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar NOQUOTE_STOPLIST[] = { 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SPACE, COMMA, CLOSE_ANGLE, OPEN_ANGLE, TICK, QUOTE, 0 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDeleteFn(void* p) { 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(p); 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::parse(UChar* _data, int32_t len) { 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(ec)) { 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_data) uprv_free(_data); 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.line = 0; 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.offset = -1; 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.postContext[0] = 0; 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.preContext[0] = 0; 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_data == NULL) { 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len <= 0) { 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(_data); 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = _data; 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e = data + len; 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p = _data; 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ch = 0xffff; 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return doParse(); 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::doParse(void) { 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(OPEN_ANGLE)) { 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing open angle"); 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray array(DeleteFn); 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mightHaveNext = TRUE; 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t requiredLength = -1; 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (mightHaveNext) { 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = FALSE; 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar** elem = nextArray(requiredLength); 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveComma = check(COMMA); 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (elem) { 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(elem, ec); 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveComma) { 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = TRUE; 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (haveComma) { 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected character"); 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(CLOSE_ANGLE)) { 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (check(OPEN_ANGLE)) { 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing comma in outer array"); 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing close angle bracket in outer array"); 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p != e) { 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Extra text after close of localization data"); 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(NULL, ec); 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numLocs = array.length() - 2; // subtract first, NULL 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar*** result = (UChar***)array.release(); 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new StringLocalizationInfo(data, result, requiredLength-2, numLocs); // subtract first, NULL 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unknown error"); 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUChar** 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::nextArray(int32_t& requiredLength) { 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(ec)) { 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(OPEN_ANGLE)) { 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing open angle"); 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray array; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mightHaveNext = TRUE; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (mightHaveNext) { 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = FALSE; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* elem = nextString(); 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveComma = check(COMMA); 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (elem) { 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(elem, ec); 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveComma) { 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = TRUE; 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (haveComma) { 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected comma"); 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(CLOSE_ANGLE)) { 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (check(OPEN_ANGLE)) { 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing close angle bracket in inner array"); 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing comma in inner array"); 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(NULL, ec); 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (requiredLength == -1) { 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru requiredLength = array.length() + 1; 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (array.length() != requiredLength) { 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Array not of required length"); 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UChar**)array.release(); 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unknown Error"); 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUChar* 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::nextString() { 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* result = NULL; 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p < e) { 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* terminators; 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar c = *p; 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveQuote = c == QUOTE || c == TICK; 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveQuote) { 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminators = c == QUOTE ? DQUOTE_STOPLIST : SQUOTE_STOPLIST; 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminators = NOQUOTE_STOPLIST; 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* start = p; 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p < e && !inList(*p, terminators)) ++p; 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == e) { 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected end of data"); 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar x = *p; 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p > start) { 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ch = x; 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p = 0x0; // terminate by writing to data 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = start; // just point into data 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveQuote) { 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (x != c) { 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing matching quote"); 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (p == start) { 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Empty string"); 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (x == OPEN_ANGLE || x == TICK || x == QUOTE) { 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected character in string"); 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ok for there to be no next string 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid LocDataParser::parseError(const char* EXPLANATION_ARG) 559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{ 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!data) { 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* start = p - U_PARSE_CONTEXT_LEN - 1; 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (start < data) { 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = data; 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (UChar* x = p; --x >= start;) { 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!*x) { 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = x+1; 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* limit = p + U_PARSE_CONTEXT_LEN - 1; 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (limit > e) { 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = e; 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_strncpy(pe.preContext, start, (int32_t)(p-start)); 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.preContext[p-start] = 0; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_strncpy(pe.postContext, p, (int32_t)(limit-p)); 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.postContext[limit-p] = 0; 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.offset = (int32_t)(p - data); 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 584f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#ifdef RBNF_DEBUG 585fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fprintf(stderr, "%s at or near character %ld: ", EXPLANATION_ARG, p-data); 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString msg; 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append(start, p - start); 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append((UChar)0x002f); /* SOLIDUS/SLASH */ 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append(p, limit-p); 591fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius msg.append(UNICODE_STRING_SIMPLE("'")); 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char buf[128]; 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = msg.extract(0, msg.length(), buf, 128); 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len >= 128) { 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[127] = 0; 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[len] = 0; 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s\n", buf); 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fflush(stderr); 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = NULL; 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p = NULL; 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e = NULL; 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_PARSE_ERROR; 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//UOBJECT_DEFINE_RTTI_IMPLEMENTATION(StringLocalizationInfo) 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::create(const UnicodeString& info, UParseError& perror, UErrorCode& status) { 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = info.length(); 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len == 0) { 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; // no error; 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* p = (UChar*)uprv_malloc(len * sizeof(UChar)); 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!p) { 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info.extract(p, len, status); 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!U_FAILURE(status)) { 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ZERO_ERROR; // clear warning about non-termination 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocDataParser parser(perror, status); 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return parser.parse(p, len); 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::~StringLocalizationInfo() { 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (UChar*** p = (UChar***)data; *p; ++p) { 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // remaining data is simply pointer into our unicode string data. 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*p) uprv_free(*p); 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (data) uprv_free(data); 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info) uprv_free(info); 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getRuleSetName(int32_t index) const { 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (index >= 0 && index < getNumberOfRuleSets()) { 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[0][index]; 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getLocaleName(int32_t index) const { 661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (index >= 0 && index < getNumberOfDisplayLocales()) { 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[index+1][0]; 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getDisplayName(int32_t localeIndex, int32_t ruleIndex) const { 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localeIndex >= 0 && localeIndex < getNumberOfDisplayLocales() && 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleIndex >= 0 && ruleIndex < getNumberOfRuleSets()) { 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[localeIndex+1][ruleIndex+1]; 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ---------- 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& locs, 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& alocale, UParseError& perror, UErrorCode& status) 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 682103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 683103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 688c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 689c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 690ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 694fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 695fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 696fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 697fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status); 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, locinfo, perror, status); 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& locs, 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, UErrorCode& status) 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 707103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 708103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(Locale::getDefault()) 711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 713c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 714c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 715ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 719fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 720fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 721fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 722fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status); 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, locinfo, perror, status); 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* info, 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& alocale, UParseError& perror, UErrorCode& status) 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 732103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 733103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 738c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 739c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 740ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 744fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 745fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 746fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 747fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, info, perror, status); 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 756103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(Locale::getDefault()) 760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 762c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 763c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 764ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 765ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 766ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 767ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 768fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 769fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 770fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 771fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, NULL, perror, status); 774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 776ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 777ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& aLocale, 778ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, 779ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 780ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 781103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(aLocale) 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 786ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 787c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 788c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 789ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 790ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 793fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 794fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 795fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 796fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, NULL, perror, status); 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale& alocale, UErrorCode& status) 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 809c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 810c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 811ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 815fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 816fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 817fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 818fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 82485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const char* rules_tag = "RBNFRules"; 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char* fmt_tag = ""; 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (tag) { 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_SPELLOUT: fmt_tag = "SpelloutRules"; break; 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_ORDINAL: fmt_tag = "OrdinalRules"; break; 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_DURATION: fmt_tag = "DurationRules"; break; 83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case URBNF_NUMBERING_SYSTEM: fmt_tag = "NumberingSystemRules"; break; 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: status = U_ILLEGAL_ARGUMENT_ERROR; return; 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO: read localization info from resource 835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = NULL; 836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle* nfrb = ures_open(U_ICUDATA_RBNF, locale.getName(), &status); 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocaleIDs(ures_getLocaleByType(nfrb, ULOC_VALID_LOCALE, &status), 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getLocaleByType(nfrb, ULOC_ACTUAL_LOCALE, &status)); 84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UResourceBundle* rbnfRules = ures_getByKeyWithFallback(nfrb, rules_tag, NULL, &status); 84385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 84485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(nfrb); 84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UResourceBundle* ruleSets = ures_getByKeyWithFallback(rbnfRules, fmt_tag, NULL, &status); 84785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 84885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(rbnfRules); 84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(nfrb); 85085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 85185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 852103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 85385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UnicodeString desc; 85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (ures_hasNext(ruleSets)) { 855103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius desc.append(ures_getNextUnicodeString(ruleSets,NULL,&status)); 85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError perror; 85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 859c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert init(desc, locinfo, perror, status); 86085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 86185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(ruleSets); 86285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(rbnfRules); 863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(nfrb); 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs) 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : NumberFormat(rhs) 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , ruleSets(NULL) 870103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , ruleSetDescriptions(NULL) 871103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius , numRuleSets(0) 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(rhs.locale) 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 876c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultInfinityRule(NULL) 877c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert , defaultNaNRule(NULL) 878ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert , roundingMode(DecimalFormat::ERoundingMode::kRoundUnnecessary) 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 882fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationInfoSet(FALSE) 883fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForUIListMenu(FALSE) 884fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationForStandAlone(FALSE) 885fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius , capitalizationBrkIter(NULL) 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->operator=(rhs); 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------- 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat& 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs) 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 895fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (this == &rhs) { 896fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return *this; 897fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 898fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius NumberFormat::operator=(rhs); 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dispose(); 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru locale = rhs.locale; 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient = rhs.lenient; 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError perror; 905fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius setDecimalFormatSymbols(*rhs.getDecimalFormatSymbols()); 906c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert init(rhs.originalDescription, rhs.localizations ? rhs.localizations->ref() : NULL, perror, status); 907fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius setDefaultRuleSet(rhs.getDefaultRuleSetName(), status); 908ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert setRoundingMode(rhs.getRoundingMode()); 909fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 910fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationInfoSet = rhs.capitalizationInfoSet; 911fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationForUIListMenu = rhs.capitalizationForUIListMenu; 912fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationForStandAlone = rhs.capitalizationForStandAlone; 913fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 914fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationBrkIter = (rhs.capitalizationBrkIter!=NULL)? rhs.capitalizationBrkIter->clone(): NULL; 915fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::~RuleBasedNumberFormat() 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dispose(); 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat* 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::clone(void) const 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 928fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return new RuleBasedNumberFormat(*this); 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::operator==(const Format& other) const 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == &other) { 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 93827f654740f2a26ad62a5c155af9199af9e69b889claireho if (typeid(*this) == typeid(other)) { 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other; 940fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // test for capitalization info equality is adequately handled 941fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // by the NumberFormat test for fCapitalizationContext equality; 942fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // the info here is just derived from that. 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (locale == rhs.locale && 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient == rhs.lenient && 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (localizations == NULL 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ? rhs.localizations == NULL 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : (rhs.localizations == NULL 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ? FALSE 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : *localizations == rhs.localizations))) { 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet** p = ruleSets; 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet** q = rhs.ruleSets; 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == NULL) { 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return q == NULL; 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (q == NULL) { 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*p && *q && (**p == **q)) { 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++p; 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++q; 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *q == NULL && *p == NULL; 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRules() const 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets != NULL) { 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*p)->appendRules(result); 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetName(int32_t index) const 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 985c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert UnicodeString string(TRUE, localizations->getRuleSetName(index), (int32_t)-1); 986c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return string; 987c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 988c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (ruleSets) { 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = *p; 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs->isPublic()) { 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (--index == -1) { 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs->getName(result); 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString empty; 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return empty; 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getNumberOfRuleSetNames() const 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t result = 0; 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1009c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result = localizations->getNumberOfRuleSets(); 1010c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1011c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else if (ruleSets) { 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((**p).isPublic()) { 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++result; 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getNumberOfRuleSetDisplayNameLocales(void) const { 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return localizations->getNumberOfDisplayLocales(); 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocale 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayNameLocale(int32_t index, UErrorCode& status) const { 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return Locale(""); 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations && index >= 0 && index < localizations->getNumberOfDisplayLocales()) { 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getLocaleName(index), -1); 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char buffer[64]; 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cap = name.length() + 1; 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char* bp = buffer; 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cap > 64) { 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bp = (char *)uprv_malloc(cap); 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bp == NULL) { 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return Locale(""); 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name.extract(0, name.length(), bp, cap, UnicodeString::kInvariant); 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Locale retLocale(bp); 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bp != buffer) { 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(bp); 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return retLocale; 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Locale retLocale; 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return retLocale; 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayName(int32_t index, const Locale& localeParam) { 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations && index >= 0 && index < localizations->getNumberOfRuleSets()) { 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString localeName(localeParam.getBaseName(), -1, UnicodeString::kInvariant); 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = localeName.length(); 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* localeStr = localeName.getBuffer(len + 1); 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (len >= 0) { 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localeStr[len] = 0; 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = localizations->indexForLocale(localeStr); 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ix >= 0) { 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getDisplayName(ix, index), -1); 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 1070ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1071ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1072ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // trim trailing portion, skipping over ommitted sections 1073ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { --len;} while (len > 0 && localeStr[len] != 0x005f); // underscore 1074ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (len > 0 && localeStr[len-1] == 0x005F) --len; 1075ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1076ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getRuleSetName(index), -1); 1077ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 1078ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString bogus; 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bogus.setToBogus(); 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return bogus; 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayName(const UnicodeString& ruleSetName, const Locale& localeParam) { 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rsn(ruleSetName); 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = localizations->indexForRuleSet(rsn.getTerminatedBuffer()); 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getRuleSetDisplayName(ix, localeParam); 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString bogus; 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bogus.setToBogus(); 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return bogus; 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruNFRuleSet* 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::findRuleSet(const UnicodeString& name, UErrorCode& status) const 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status) && ruleSets) { 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = *p; 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs->isNamed(name)) { 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rs; 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 11120596faeddefbf198de137d5e893708495ab1584cFredrik RoubertRuleBasedNumberFormat::format(const DigitList &number, 11130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UnicodeString &appendTo, 11140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert FieldPositionIterator *posIter, 11150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UErrorCode &status) const { 11160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (U_FAILURE(status)) { 11170596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return appendTo; 11180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11190596faeddefbf198de137d5e893708495ab1584cFredrik Roubert DigitList copy(number); 11200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (copy.fitsIntoInt64(false)) { 11210596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(((DigitList &)number).getInt64(), appendTo, posIter, status); 11220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11230596faeddefbf198de137d5e893708495ab1584cFredrik Roubert else { 11240596faeddefbf198de137d5e893708495ab1584cFredrik Roubert copy.roundAtExponent(0); 11250596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (copy.fitsIntoInt64(false)) { 11260596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(number.getDouble(), appendTo, posIter, status); 11270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11280596faeddefbf198de137d5e893708495ab1584cFredrik Roubert else { 11290596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // We're outside of our normal range that this framework can handle. 11300596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // The DecimalFormat will provide more accurate results. 11310596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11320596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J. 11330596faeddefbf198de137d5e893708495ab1584cFredrik Roubert NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status); 11340596faeddefbf198de137d5e893708495ab1584cFredrik Roubert Formattable f; 11350596faeddefbf198de137d5e893708495ab1584cFredrik Roubert f.adoptDigitList(new DigitList(number)); 11360596faeddefbf198de137d5e893708495ab1584cFredrik Roubert decimalFormat->format(f, appendTo, posIter, status); 11370596faeddefbf198de137d5e893708495ab1584cFredrik Roubert delete decimalFormat; 11380596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11390596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11400596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return appendTo; 11410596faeddefbf198de137d5e893708495ab1584cFredrik Roubert} 11420596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11430596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11440596faeddefbf198de137d5e893708495ab1584cFredrik RoubertUnicodeString& 11450596faeddefbf198de137d5e893708495ab1584cFredrik RoubertRuleBasedNumberFormat::format(const DigitList &number, 11460596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UnicodeString& appendTo, 11470596faeddefbf198de137d5e893708495ab1584cFredrik Roubert FieldPosition& pos, 11480596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UErrorCode &status) const { 11490596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (U_FAILURE(status)) { 11500596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return appendTo; 11510596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11520596faeddefbf198de137d5e893708495ab1584cFredrik Roubert DigitList copy(number); 11530596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (copy.fitsIntoInt64(false)) { 11540596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(((DigitList &)number).getInt64(), appendTo, pos, status); 11550596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11560596faeddefbf198de137d5e893708495ab1584cFredrik Roubert else { 11570596faeddefbf198de137d5e893708495ab1584cFredrik Roubert copy.roundAtExponent(0); 11580596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (copy.fitsIntoInt64(false)) { 11590596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(number.getDouble(), appendTo, pos, status); 11600596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11610596faeddefbf198de137d5e893708495ab1584cFredrik Roubert else { 11620596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // We're outside of our normal range that this framework can handle. 11630596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // The DecimalFormat will provide more accurate results. 11640596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11650596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J. 11660596faeddefbf198de137d5e893708495ab1584cFredrik Roubert NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status); 11670596faeddefbf198de137d5e893708495ab1584cFredrik Roubert Formattable f; 11680596faeddefbf198de137d5e893708495ab1584cFredrik Roubert f.adoptDigitList(new DigitList(number)); 11690596faeddefbf198de137d5e893708495ab1584cFredrik Roubert decimalFormat->format(f, appendTo, pos, status); 11700596faeddefbf198de137d5e893708495ab1584cFredrik Roubert delete decimalFormat; 11710596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11720596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 11730596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return appendTo; 11740596faeddefbf198de137d5e893708495ab1584cFredrik Roubert} 11750596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 11760596faeddefbf198de137d5e893708495ab1584cFredrik RoubertUnicodeString& 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int32_t number, 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 11790596faeddefbf198de137d5e893708495ab1584cFredrik Roubert FieldPosition& pos) const 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 11810596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return format((int64_t)number, toAppendTo, pos); 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int64_t number, 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */) const 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1190fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (defaultRuleSet) { 1191f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 11920596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(number, defaultRuleSet, toAppendTo, status); 1193fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(double number, 1200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */) const 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 12030596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UErrorCode status = U_ZERO_ERROR; 1204c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (defaultRuleSet) { 1205ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert format(number, *defaultRuleSet, toAppendTo, status); 1206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1207ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return toAppendTo; 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int32_t number, 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 12150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert FieldPosition& pos, 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 12180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return format((int64_t)number, ruleSetName, toAppendTo, pos, status); 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int64_t number, 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */, 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1230103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) { 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new IllegalArgumentException("Can't use internal rule set"); 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rs = findRuleSet(ruleSetName, status); 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs) { 12360596faeddefbf198de137d5e893708495ab1584cFredrik Roubert format(number, rs, toAppendTo, status); 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(double number, 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */, 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ruleSetName.indexOf(gPercentPercent, 2, 0) == 0) { 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new IllegalArgumentException("Can't use internal rule set"); 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rs = findRuleSet(ruleSetName, status); 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs) { 1258ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert format(number, *rs, toAppendTo, status); 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1265ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertvoid 1266ffdc27edd5503111189fc11165c5a11289a71f79Fredrik RoubertRuleBasedNumberFormat::format(double number, 1267ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert NFRuleSet& rs, 1268ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UnicodeString& toAppendTo, 1269ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert UErrorCode& status) const 1270ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert{ 1271ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert int32_t startPos = toAppendTo.length(); 1272ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert if (getRoundingMode() != DecimalFormat::ERoundingMode::kRoundUnnecessary && !uprv_isNaN(number) && !uprv_isInfinite(number)) { 1273ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert DigitList digitList; 1274ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert digitList.set(number); 1275ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert digitList.setRoundingMode(getRoundingMode()); 1276ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert digitList.roundFixedPoint(getMaximumFractionDigits()); 1277ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert number = digitList.getDouble(); 1278ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert } 1279ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert rs.format(number, toAppendTo, toAppendTo.length(), 0, status); 1280ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert adjustForCapitalizationContext(startPos, toAppendTo, status); 1281ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert} 1282ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 12830596faeddefbf198de137d5e893708495ab1584cFredrik Roubert/** 12840596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * Bottleneck through which all the public format() methods 12850596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * that take a long pass. By the time we get here, we know 12860596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * which rule set we're using to do the formatting. 12870596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * @param number The number to format 12880596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * @param ruleSet The rule set to use to format the number 12890596faeddefbf198de137d5e893708495ab1584cFredrik Roubert * @return The text that resulted from formatting the number 12900596faeddefbf198de137d5e893708495ab1584cFredrik Roubert */ 12910596faeddefbf198de137d5e893708495ab1584cFredrik RoubertUnicodeString& 12920596faeddefbf198de137d5e893708495ab1584cFredrik RoubertRuleBasedNumberFormat::format(int64_t number, NFRuleSet *ruleSet, UnicodeString& toAppendTo, UErrorCode& status) const 12930596faeddefbf198de137d5e893708495ab1584cFredrik Roubert{ 12940596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // all API format() routines that take a double vector through 12950596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // here. We have these two identical functions-- one taking a 12960596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // double and one taking a long-- the couple digits of precision 12970596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // that long has but double doesn't (both types are 8 bytes long, 12980596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // but double has to borrow some of the mantissa bits to hold 12990596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // the exponent). 13000596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // Create an empty string buffer where the result will 13010596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // be built, and pass it to the rule set (along with an insertion 13020596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // position of 0 and the number being formatted) to the rule set 13030596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // for formatting 13040596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 13050596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (U_SUCCESS(status)) { 13060596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (number == U_INT64_MIN) { 13070596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // We can't handle this value right now. Provide an accurate default value. 13080596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 13090596faeddefbf198de137d5e893708495ab1584cFredrik Roubert // TODO this section should probably be optimized. The DecimalFormat is shared in ICU4J. 13100596faeddefbf198de137d5e893708495ab1584cFredrik Roubert NumberFormat *decimalFormat = NumberFormat::createInstance(locale, UNUM_DECIMAL, status); 13110596faeddefbf198de137d5e893708495ab1584cFredrik Roubert Formattable f; 13120596faeddefbf198de137d5e893708495ab1584cFredrik Roubert FieldPosition pos(FieldPosition::DONT_CARE); 13130596faeddefbf198de137d5e893708495ab1584cFredrik Roubert DigitList *digitList = new DigitList(); 13140596faeddefbf198de137d5e893708495ab1584cFredrik Roubert digitList->set(number); 13150596faeddefbf198de137d5e893708495ab1584cFredrik Roubert f.adoptDigitList(digitList); 13160596faeddefbf198de137d5e893708495ab1584cFredrik Roubert decimalFormat->format(f, toAppendTo, pos, status); 13170596faeddefbf198de137d5e893708495ab1584cFredrik Roubert delete decimalFormat; 13180596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 13190596faeddefbf198de137d5e893708495ab1584cFredrik Roubert else { 13200596faeddefbf198de137d5e893708495ab1584cFredrik Roubert int32_t startPos = toAppendTo.length(); 13210596faeddefbf198de137d5e893708495ab1584cFredrik Roubert ruleSet->format(number, toAppendTo, toAppendTo.length(), 0, status); 13220596faeddefbf198de137d5e893708495ab1584cFredrik Roubert adjustForCapitalizationContext(startPos, toAppendTo, status); 13230596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 13240596faeddefbf198de137d5e893708495ab1584cFredrik Roubert } 13250596faeddefbf198de137d5e893708495ab1584cFredrik Roubert return toAppendTo; 13260596faeddefbf198de137d5e893708495ab1584cFredrik Roubert} 13270596faeddefbf198de137d5e893708495ab1584cFredrik Roubert 1328fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusUnicodeString& 1329fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRuleBasedNumberFormat::adjustForCapitalizationContext(int32_t startPos, 13300596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UnicodeString& currentResult, 13310596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UErrorCode& status) const 1332fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{ 1333fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 13340596faeddefbf198de137d5e893708495ab1584cFredrik Roubert UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status); 13350596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (capitalizationContext != UDISPCTX_CAPITALIZATION_NONE && startPos == 0 && currentResult.length() > 0) { 1336fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // capitalize currentResult according to context 1337fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UChar32 ch = currentResult.char32At(0); 13380596faeddefbf198de137d5e893708495ab1584cFredrik Roubert if (u_islower(ch) && U_SUCCESS(status) && capitalizationBrkIter != NULL && 13390596faeddefbf198de137d5e893708495ab1584cFredrik Roubert ( capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || 13400596faeddefbf198de137d5e893708495ab1584cFredrik Roubert (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitalizationForUIListMenu) || 13410596faeddefbf198de137d5e893708495ab1584cFredrik Roubert (capitalizationContext == UDISPCTX_CAPITALIZATION_FOR_STANDALONE && capitalizationForStandAlone)) ) { 1342fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // titlecase first word of currentResult, here use sentence iterator unlike current implementations 1343fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // in LocaleDisplayNamesImpl::adjustForUsageAndContext and RelativeDateFormat::format 1344fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius currentResult.toTitle(capitalizationBrkIter, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); 1345fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1346fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1347fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1348fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return currentResult; 1349fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1350fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1351fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::parse(const UnicodeString& text, 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable& result, 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition& parsePosition) const 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru parsePosition.setErrorIndex(0); 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString workingText(text, parsePosition.getIndex()); 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition workingPos(0); 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition high_pp(0); 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable high_result; 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rp = *p; 137085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (rp->isPublic() && rp->isParseable()) { 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition working_pp(0); 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable working_result; 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rp->parse(workingText, working_pp, kMaxDouble, working_result); 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (working_pp.getIndex() > high_pp.getIndex()) { 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru high_pp = working_pp; 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru high_result = working_result; 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (high_pp.getIndex() == workingText.length()) { 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 138685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t startIndex = parsePosition.getIndex(); 138785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parsePosition.setIndex(startIndex + high_pp.getIndex()); 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (high_pp.getIndex() > 0) { 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru parsePosition.setErrorIndex(-1); 139085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 139185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t errorIndex = (high_pp.getErrorIndex()>0)? high_pp.getErrorIndex(): 0; 139285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parsePosition.setErrorIndex(startIndex + errorIndex); 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = high_result; 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result.getType() == Formattable::kDouble) { 13968de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert double d = result.getDouble(); 13978de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert if (!uprv_isNaN(d) && d == uprv_trunc(d) && INT32_MIN <= d && d <= INT32_MAX) { 13988de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert // Note: casting a double to an int when the double is too large or small 13998de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert // to fit the destination is undefined behavior. The explicit range checks, 14008de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert // above, are required. Just casting and checking the result value is undefined. 14018de051c3d18a56cc126f0f44e368495a52f9148cFredrik Roubert result.setLong(static_cast<int32_t>(d)); 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::setLenient(UBool enabled) 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient = enabled; 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!enabled && collator) { 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete collator; 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru collator = NULL; 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::setDefaultRuleSet(const UnicodeString& ruleSetName, UErrorCode& status) { 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetName.isEmpty()) { 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getRuleSetName(0), -1); 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = findRuleSet(name, status); 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initDefaultRuleSet(); 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (ruleSetName.startsWith(UNICODE_STRING_SIMPLE("%%"))) { 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* result = findRuleSet(ruleSetName, status); 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result != NULL) { 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = result; 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getDefaultRuleSetName() const { 1443c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert UnicodeString result; 1444c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (defaultRuleSet && defaultRuleSet->isPublic()) { 1445c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultRuleSet->getName(result); 1446c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } else { 1447c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert result.setToBogus(); 1448c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1449c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return result; 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::initDefaultRuleSet() 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = NULL; 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1457c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1460c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const UnicodeString spellout(UNICODE_STRING_SIMPLE("%spellout-numbering")); 1461c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const UnicodeString ordinal(UNICODE_STRING_SIMPLE("%digits-ordinal")); 1462c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert const UnicodeString duration(UNICODE_STRING_SIMPLE("%duration")); 146385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet**p = &ruleSets[0]; 1465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*p) { 146685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if ((*p)->isNamed(spellout) || (*p)->isNamed(ordinal) || (*p)->isNamed(duration)) { 146785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho defaultRuleSet = *p; 146885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 146985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 147085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ++p; 147185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = *--p; 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!defaultRuleSet->isPublic()) { 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p != ruleSets) { 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((*--p)->isPublic()) { 1478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = *p; 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* localizationInfos, 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& pErr, UErrorCode& status) 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO: implement UParseError 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(&pErr, 0, sizeof(UParseError)); 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Note: this can leave ruleSets == NULL, so remaining code should check 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1497c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert initializeDecimalFormatSymbols(status); 1498c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert initializeDefaultInfinityRule(status); 1499c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert initializeDefaultNaNRule(status); 1500c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_FAILURE(status)) { 1501c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return; 1502c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1503c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->localizations = localizationInfos == NULL ? NULL : localizationInfos->ref(); 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString description(rules); 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!description.length()) { 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // start by stripping the trailing whitespace from all the rules 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (this is all the whitespace follwing each semicolon in the 1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // description). This allows us to look for rule-set boundaries 1515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // by searching for ";%" without having to worry about whitespace 1516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // between the ; and the % 1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stripWhitespace(description); 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // check to see if there's a set of lenient-parse rules. If there 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is, pull them out into our temporary holding place for them, 1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and delete them from the description before the real desciption- 1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // parsing code sees them 1523103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t lp = description.indexOf(gLenientParse, -1, 0); 1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lp != -1) { 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we've got to make sure we're not in the middle of a rule 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (where "%%lenient-parse" would actually get treated as 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule text) 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lp == 0 || description.charAt(lp - 1) == gSemiColon) { 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // locate the beginning and end of the actual collation 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rules (there may be whitespace between the name and 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the first token in the description) 1532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int lpEnd = description.indexOf(gSemiPercent, 2, lp); 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lpEnd == -1) { 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lpEnd = description.length() - 1; 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int lpStart = lp + u_strlen(gLenientParse); 1538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (PatternProps::isWhiteSpace(description.charAt(lpStart))) { 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++lpStart; 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // copy out the lenient-parse rules and delete them 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // from the description 1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules = new UnicodeString(); 1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* test for NULL */ 1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lenientParseRules == 0) { 1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules->setTo(description, lpStart, lpEnd - lpStart); 1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru description.remove(lp, lpEnd + 1 - lp); 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // pre-flight parsing the description and count the number of 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule sets (";%" marks the end of one rule set and the beginning 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // of the next) 1559103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numRuleSets = 0; 1560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t p = description.indexOf(gSemiPercent, 2, 0); p != -1; p = description.indexOf(gSemiPercent, 2, p)) { 1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++numRuleSets; 1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++p; 1563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++numRuleSets; 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // our rule list is an array of the appropriate size 1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets = (NFRuleSet **)uprv_malloc((numRuleSets + 1) * sizeof(NFRuleSet *)); 1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* test for NULL */ 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets == 0) { 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i <= numRuleSets; ++i) { 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets[i] = NULL; 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // divide up the descriptions into individual rule-set descriptions 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and store them in a temporary array. At each step, we also 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // new up a rule set, but all this does is initialize its name 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and remove it from its description. We can't actually parse 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the rest of the descriptions and finish initializing everything 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // because we have to know the names and locations of all the rule 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // sets before we can actually set everything up 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!numRuleSets) { 158685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho status = U_ILLEGAL_ARGUMENT_ERROR; 158785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1589103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1590103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ruleSetDescriptions = new UnicodeString[numRuleSets]; 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetDescriptions == 0) { 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int curRuleSet = 0; 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t start = 0; 1599103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t p = description.indexOf(gSemiPercent, 2, 0); p != -1; p = description.indexOf(gSemiPercent, 2, start)) { 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSetDescriptions[curRuleSet].setTo(description, start, p + 1 - start); 1601c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ruleSets[curRuleSet] = new NFRuleSet(this, ruleSetDescriptions, curRuleSet, status); 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets[curRuleSet] == 0) { 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1604103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++curRuleSet; 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = p + 1; 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSetDescriptions[curRuleSet].setTo(description, start, description.length() - start); 1610c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ruleSets[curRuleSet] = new NFRuleSet(this, ruleSetDescriptions, curRuleSet, status); 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets[curRuleSet] == 0) { 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // now we can take note of the formatter's default rule set, which 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is the last public rule set in the description (it's the last 1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rather than the first so that a user can create a new formatter 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // from an existing formatter and change its default behavior just 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // by appending more rule sets to the end) 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // {dlf} Initialization of a fraction rule set requires the default rule 1624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // set to be known. For purposes of initialization, this is always the 1625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // last public rule set, no matter what the localization data says. 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initDefaultRuleSet(); 1627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // finally, we can go back through the temporary descriptions 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // list and finish seting up the substructure (and we throw 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // away the temporary descriptions as we go) 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < numRuleSets; i++) { 1633c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ruleSets[i]->parseRules(ruleSetDescriptions[i], status); 1634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Now that the rules are initialized, the 'real' default rule 1638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // set can be adjusted by the localization data. 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // The C code keeps the localization array as is, rather than building 1641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // a separate array of the public rule set names, so we have less work 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // to do here-- but we still need to check the names. 1643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizationInfos) { 1645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // confirm the names, if any aren't in the rules, that's an error 1646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // it is ok if the rules contain public rule sets that are not in this list 1647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = 0; i < localizationInfos->getNumberOfRuleSets(); ++i) { 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizationInfos->getRuleSetName(i), -1); 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = findRuleSet(name, status); 1650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs == NULL) { 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // error 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (i == 0) { 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = rs; 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = getDefaultRuleSet(); 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1660fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius originalDescription = rules; 1661fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1662fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1663fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// override the NumberFormat implementation in order to 1664fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// lazily initialize relevant items 1665fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid 1666fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRuleBasedNumberFormat::setContext(UDisplayContext value, UErrorCode& status) 1667fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{ 1668fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius NumberFormat::setContext(value, status); 1669fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_SUCCESS(status)) { 1670fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (!capitalizationInfoSet && 1671fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE)) { 1672fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius initCapitalizationContextInfo(locale); 1673fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationInfoSet = TRUE; 1674fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1675fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 1676fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if ( capitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE || 1677fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU && capitalizationForUIListMenu) || 1678fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius (value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE && capitalizationForStandAlone)) ) { 1679fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode status = U_ZERO_ERROR; 1680fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationBrkIter = BreakIterator::createSentenceInstance(locale, status); 1681fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 1682fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete capitalizationBrkIter; 1683fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationBrkIter = NULL; 1684fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1685fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1686fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1687fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1688fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1689fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1690fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid 1691fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusRuleBasedNumberFormat::initCapitalizationContextInfo(const Locale& thelocale) 1692fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius{ 1693fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 1694fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const char * localeID = (thelocale != NULL)? thelocale.getBaseName(): NULL; 1695fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode status = U_ZERO_ERROR; 1696fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UResourceBundle *rb = ures_open(NULL, localeID, &status); 1697fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius rb = ures_getByKeyWithFallback(rb, "contextTransforms", rb, &status); 1698fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius rb = ures_getByKeyWithFallback(rb, "number-spellout", rb, &status); 1699fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_SUCCESS(status) && rb != NULL) { 1700fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t len = 0; 1701fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius const int32_t * intVector = ures_getIntVector(rb, &len, &status); 1702fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_SUCCESS(status) && intVector != NULL && len >= 2) { 1703fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationForUIListMenu = intVector[0]; 1704fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius capitalizationForStandAlone = intVector[1]; 1705fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1706fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1707fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ures_close(rb); 1708fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::stripWhitespace(UnicodeString& description) 1713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // iterate through the characters... 1715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 1716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int start = 0; 1718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (start != -1 && start < description.length()) { 1719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // seek to the first non-whitespace character... 1720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (start < description.length() 1721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && PatternProps::isWhiteSpace(description.charAt(start))) { 1722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++start; 1723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // locate the next semicolon in the text and copy the text from 1726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // our current position up to that semicolon into the result 1727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t p = description.indexOf(gSemiColon, start); 1728ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == -1) { 1729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // or if we don't find a semicolon, just copy the rest of 1730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the string into the result 1731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(description, start, description.length() - start); 1732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = -1; 1733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (p < description.length()) { 1735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(description, start, p + 1 - start); 1736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = p + 1; 1737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // when we get here, we've seeked off the end of the sring, and 1740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we terminate the loop (we continue until *start* is -1 rather 1741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // than until *p* is -1, because otherwise we'd miss the last 1742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule in the description) 1743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = -1; 1745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1747ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru description.setTo(result); 1749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1753ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::dispose() 1754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets) { 1756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete *p; 1758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(ruleSets); 1760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets = NULL; 1761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ruleSetDescriptions) { 1764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete [] ruleSetDescriptions; 1765c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ruleSetDescriptions = NULL; 1766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1768ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1769ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete collator; 1770ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1771ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru collator = NULL; 1772ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1773ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete decimalFormatSymbols; 1774ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru decimalFormatSymbols = NULL; 1775ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1776c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete defaultInfinityRule; 1777c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultInfinityRule = NULL; 1778c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1779c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete defaultNaNRule; 1780c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultNaNRule = NULL; 1781c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete lenientParseRules; 1783ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules = NULL; 1784ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1785fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_BREAK_ITERATION 1786c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete capitalizationBrkIter; 1787c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert capitalizationBrkIter = NULL; 1788fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 1789fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1790c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (localizations) { 1791c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert localizations = localizations->unref(); 1792c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------- 1797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// package-internal API 1798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------- 1799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1801ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Returns the collator to use for lenient parsing. The collator is lazily created: 1802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this function creates it the first time it's called. 1803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The collator to use for lenient parsing, or null if lenient parsing 1804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is turned off. 1805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1806fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusconst RuleBasedCollator* 1807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getCollator() const 1808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1814fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius // lazy-evaluate the collator 1815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (collator == NULL && lenient) { 1816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // create a default collator based on the formatter's locale, 1817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // then pull out that collator's rules, append any additional 1818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rules specified in the description, and create a _new_ 1819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // collator based on the combinaiton of those rules 1820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 1822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Collator* temp = Collator::createInstance(locale, status); 182427f654740f2a26ad62a5c155af9199af9e69b889claireho RuleBasedCollator* newCollator; 182527f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_SUCCESS(status) && (newCollator = dynamic_cast<RuleBasedCollator*>(temp)) != NULL) { 1826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lenientParseRules) { 1827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rules(newCollator->getRules()); 1828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rules.append(*lenientParseRules); 1829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCollator = new RuleBasedCollator(rules, status); 183185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // Exit if newCollator could not be created. 183285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (newCollator == NULL) { 1833fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return NULL; 183485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1835ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1836ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru temp = NULL; 1837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCollator->setAttribute(UCOL_DECOMPOSITION_MODE, UCOL_ON, status); 1840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // cast away const 1841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((RuleBasedNumberFormat*)this)->collator = newCollator; 1842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete newCollator; 1844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete temp; 1847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if lenient-parse mode is off, this will be null 1851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (see setLenientParseMode()) 1852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return collator; 1853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDecimalFormatSymbols* 1857c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::initializeDecimalFormatSymbols(UErrorCode &status) 1858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // lazy-evaluate the DecimalFormatSymbols object. This object 1860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is shared by all DecimalFormat instances belonging to this 1861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // formatter 1862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (decimalFormatSymbols == NULL) { 1863ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DecimalFormatSymbols* temp = new DecimalFormatSymbols(locale, status); 1864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1865c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert decimalFormatSymbols = temp; 1866c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1867c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else { 1868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete temp; 1869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return decimalFormatSymbols; 1872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1874c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert/** 1875c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * Returns the DecimalFormatSymbols object that should be used by all DecimalFormat 1876c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert * instances owned by this formatter. 1877c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert*/ 1878c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst DecimalFormatSymbols* 1879c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::getDecimalFormatSymbols() const 1880c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert{ 1881c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return decimalFormatSymbols; 1882c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 1883c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1884c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertNFRule* 1885c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::initializeDefaultInfinityRule(UErrorCode &status) 1886c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert{ 1887c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_FAILURE(status)) { 1888c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return NULL; 1889c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1890c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (defaultInfinityRule == NULL) { 1891c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert UnicodeString rule(UNICODE_STRING_SIMPLE("Inf: ")); 1892c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rule.append(getDecimalFormatSymbols()->getSymbol(DecimalFormatSymbols::kInfinitySymbol)); 1893c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert NFRule* temp = new NFRule(this, rule, status); 1894c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_SUCCESS(status)) { 1895c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultInfinityRule = temp; 1896c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1897c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else { 1898c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete temp; 1899c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1900c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1901c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return defaultInfinityRule; 1902c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 1903c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1904c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst NFRule* 1905c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::getDefaultInfinityRule() const 1906c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert{ 1907c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return defaultInfinityRule; 1908c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 1909c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1910c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertNFRule* 1911c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::initializeDefaultNaNRule(UErrorCode &status) 1912c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert{ 1913c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_FAILURE(status)) { 1914c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return NULL; 1915c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1916c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (defaultNaNRule == NULL) { 1917c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert UnicodeString rule(UNICODE_STRING_SIMPLE("NaN: ")); 1918c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert rule.append(getDecimalFormatSymbols()->getSymbol(DecimalFormatSymbols::kNaNSymbol)); 1919c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert NFRule* temp = new NFRule(this, rule, status); 1920c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (U_SUCCESS(status)) { 1921c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultNaNRule = temp; 1922c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1923c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert else { 1924c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete temp; 1925c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1926c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1927c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return defaultNaNRule; 1928c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 1929c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1930c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubertconst NFRule* 1931c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik RoubertRuleBasedNumberFormat::getDefaultNaNRule() const 1932c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert{ 1933c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert return defaultNaNRule; 1934c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert} 1935c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1936103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// De-owning the current localized symbols and adopt the new symbols. 1937103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 1938103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusRuleBasedNumberFormat::adoptDecimalFormatSymbols(DecimalFormatSymbols* symbolsToAdopt) 1939103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{ 1940103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (symbolsToAdopt == NULL) { 1941103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; // do not allow caller to set decimalFormatSymbols to NULL 1942103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1943103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1944103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (decimalFormatSymbols != NULL) { 1945103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete decimalFormatSymbols; 1946103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1947103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1948103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius decimalFormatSymbols = symbolsToAdopt; 1949103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1950103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 1951103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Apply the new decimalFormatSymbols by reparsing the rulesets 1952103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 1953103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1954c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete defaultInfinityRule; 1955c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultInfinityRule = NULL; 1956c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert initializeDefaultInfinityRule(status); // Reset with the new DecimalFormatSymbols 1957c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1958c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert delete defaultNaNRule; 1959c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert defaultNaNRule = NULL; 1960c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert initializeDefaultNaNRule(status); // Reset with the new DecimalFormatSymbols 1961c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert 1962c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert if (ruleSets) { 1963c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert for (int32_t i = 0; i < numRuleSets; i++) { 1964c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert ruleSets[i]->setDecimalFormatSymbols(*symbolsToAdopt, status); 1965c14898b482f76ecab9026615e2e4c6fe78358bdcFredrik Roubert } 1966103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1967103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1968103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1969103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1970103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Setting the symbols is equlivalent to adopting a newly created localized symbols. 1971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 1972103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusRuleBasedNumberFormat::setDecimalFormatSymbols(const DecimalFormatSymbols& symbols) 1973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius{ 1974103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius adoptDecimalFormatSymbols(new DecimalFormatSymbols(symbols)); 1975103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1976103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1977f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusPluralFormat * 1978f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusRuleBasedNumberFormat::createPluralFormat(UPluralType pluralType, 1979f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UnicodeString &pattern, 1980f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode& status) const 1981f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius{ 1982f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return new PluralFormat(locale, pluralType, pattern, status); 1983f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1984f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1985ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/** 1986ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Get the rounding mode. 1987ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * @return A rounding mode 1988ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 1989ffdc27edd5503111189fc11165c5a11289a71f79Fredrik RoubertDecimalFormat::ERoundingMode RuleBasedNumberFormat::getRoundingMode() const { 1990ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert return roundingMode; 1991ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert} 1992ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 1993ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert/** 1994ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * Set the rounding mode. This has no effect unless the rounding 1995ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * increment is greater than zero. 1996ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert * @param roundingMode A rounding mode 1997ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert */ 1998ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubertvoid RuleBasedNumberFormat::setRoundingMode(DecimalFormat::ERoundingMode roundingMode) { 1999ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert this->roundingMode = roundingMode; 2000ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert} 2001ffdc27edd5503111189fc11165c5a11289a71f79Fredrik Roubert 2002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 2003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* U_HAVE_RBNF */ 2005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 2006