1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 1997-2011, International Business Machines Corporation 4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* and others. All Rights Reserved. 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************* 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 827f654740f2a26ad62a5c155af9199af9e69b889claireho#include <typeinfo> // for 'typeid' to work 927f654740f2a26ad62a5c155af9199af9e69b889claireho 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/rbnf.h" 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if U_HAVE_RBNF 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/normlzr.h" 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/tblcoll.h" 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uchar.h" 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ucol.h" 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uloc.h" 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/unum.h" 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ures.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/ustring.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utf16.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "nfrs.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cstring.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h" 2985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uresimp.h" 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// debugging 32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// #define DEBUG 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef DEBUG 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "stdio.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define U_ICUDATA_RBNF U_ICUDATA_NAME U_TREE_SEPARATOR_STRING "rbnf" 39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gPercentPercent[] = 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x25, 0x25, 0 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* "%%" */ 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// All urbnf objects are created through openRules, so we init all of the 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Unicode string constants required by rbnf, nfrs, or nfr here. 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gLenientParse[] = 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x25, 0x25, 0x6C, 0x65, 0x6E, 0x69, 0x65, 0x6E, 0x74, 0x2D, 0x70, 0x61, 0x72, 0x73, 0x65, 0x3A, 0 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* "%%lenient-parse:" */ 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gSemiColon = 0x003B; 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar gSemiPercent[] = 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x3B, 0x25, 0 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; /* ";%" */ 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kSomeNumberOfBitsDiv2 22 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kHalfMaxDouble (double)(1 << kSomeNumberOfBitsDiv2) 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define kMaxDouble (kHalfMaxDouble * kHalfMaxDouble) 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 6185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Temporary workaround - when noParse is true, do noting in parse. 6285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// TODO: We need a real fix - see #6895/#6896 6385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hostatic const char *NO_SPELLOUT_PARSE_LANGUAGES[] = { "ga", NULL }; 6485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(RuleBasedNumberFormat) 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThis is a utility class. It does not use ICU's RTTI. 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruIf ICU's RTTI is needed again, you can uncomment the RTTI code and derive from UObject. 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruPlease make sure that intltest passes on Windows in Release mode, 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querusince the string pooling per compilation unit will mess up how RTTI works. 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruThe RTTI code was also removed due to lack of code coverage. 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocalizationInfo : public UMemory { 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprotected: 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho virtual ~LocalizationInfo() {} 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uint32_t refcount; 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo() : refcount(0) {} 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* ref(void) { 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++refcount; 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return this; 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* unref(void) { 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (refcount && --refcount == 0) { 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete this; 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual UBool operator==(const LocalizationInfo* rhs) const; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inline UBool operator!=(const LocalizationInfo* rhs) const { return !operator==(rhs); } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfRuleSets(void) const = 0; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getRuleSetName(int32_t index) const = 0; 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfDisplayLocales(void) const = 0; 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getLocaleName(int32_t index) const = 0; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getDisplayName(int32_t localeIndex, int32_t ruleIndex) const = 0; 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t indexForLocale(const UChar* locale) const; 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t indexForRuleSet(const UChar* ruleset) const; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// virtual UClassID getDynamicClassID() const = 0; 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// static UClassID getStaticClassID(void); 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(LocalizationInfo) 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// if both strings are NULL, this returns TRUE 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UBool 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustreq(const UChar* lhs, const UChar* rhs) { 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rhs == lhs) { 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lhs && rhs) { 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return u_strcmp(lhs, rhs) == 0; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::operator==(const LocalizationInfo* rhs) const { 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rhs) { 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == rhs) { 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t rsc = getNumberOfRuleSets(); 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rsc == rhs->getNumberOfRuleSets()) { 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < rsc; ++i) { 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(getRuleSetName(i), rhs->getRuleSetName(i))) { 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t dlc = getNumberOfDisplayLocales(); 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (dlc == rhs->getNumberOfDisplayLocales()) { 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < dlc; ++i) { 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* locale = getLocaleName(i); 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = rhs->indexForLocale(locale); 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if no locale, ix is -1, getLocaleName returns null, so streq returns false 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(locale, rhs->getLocaleName(ix))) { 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int j = 0; j < rsc; ++j) { 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!streq(getDisplayName(i, j), rhs->getDisplayName(ix, j))) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::indexForLocale(const UChar* locale) const { 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < getNumberOfDisplayLocales(); ++i) { 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (streq(locale, getLocaleName(i))) { 166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocalizationInfo::indexForRuleSet(const UChar* ruleset) const { 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleset) { 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < getNumberOfRuleSets(); ++i) { 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (streq(ruleset, getRuleSetName(i))) { 177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querutypedef void (*Fn_Deleter)(void*); 186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass VArray { 188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** buf; 189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cap; 190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t size; 191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Fn_Deleter deleter; 192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray() : buf(NULL), cap(0), size(0), deleter(NULL) {} 194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray(Fn_Deleter del) : buf(NULL), cap(0), size(0), deleter(del) {} 196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~VArray() { 198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (deleter) { 199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < size; ++i) { 200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*deleter)(buf[i]); 201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(buf); 204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t length() { 207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return size; 208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void add(void* elem, UErrorCode& status) { 211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (size == cap) { 213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cap == 0) { 214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap = 1; 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (cap < 256) { 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap *= 2; 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap += 256; 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (buf == NULL) { 221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = (void**)uprv_malloc(cap * sizeof(void*)); 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = (void**)uprv_realloc(buf, cap * sizeof(void*)); 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (buf == NULL) { 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if we couldn't realloc, we leak the memory we've already allocated, but we're in deep trouble anyway 227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void* start = &buf[size]; 231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size_t count = (cap - size) * sizeof(void*); 232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(start, 0, count); // fill with nulls, just because 233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[size++] = elem; 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** release(void) { 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void** result = buf; 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf = NULL; 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cap = 0; 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru size = 0; 243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocDataParser; 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass StringLocalizationInfo : public LocalizationInfo { 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* info; 251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar*** data; 252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numRuleSets; 253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numLocales; 254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querufriend class LocDataParser; 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo(UChar* i, UChar*** d, int32_t numRS, int32_t numLocs) 258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : info(i), data(d), numRuleSets(numRS), numLocales(numLocs) 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru static StringLocalizationInfo* create(const UnicodeString& info, UParseError& perror, UErrorCode& status); 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual ~StringLocalizationInfo(); 266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfRuleSets(void) const { return numRuleSets; } 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getRuleSetName(int32_t index) const; 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual int32_t getNumberOfDisplayLocales(void) const { return numLocales; } 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getLocaleName(int32_t index) const; 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru virtual const UChar* getDisplayName(int32_t localeIndex, int32_t ruleIndex) const; 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// virtual UClassID getDynamicClassID() const; 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// static UClassID getStaticClassID(void); 274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void init(UErrorCode& status) const; 277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum { 281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru OPEN_ANGLE = 0x003c, /* '<' */ 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru CLOSE_ANGLE = 0x003e, /* '>' */ 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru COMMA = 0x002c, 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TICK = 0x0027, 285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru QUOTE = 0x0022, 286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SPACE = 0x0020 287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Utility for parsing a localization string and returning a StringLocalizationInfo*. 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruclass LocDataParser { 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* data; 294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* e; 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* p; 296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar ch; 297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& pe; 298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& ec; 299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querupublic: 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocDataParser(UParseError& parseError, UErrorCode& status) 302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : data(NULL), e(NULL), p(NULL), ch(0xffff), pe(parseError), ec(status) {} 303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ~LocDataParser() {} 304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * On a successful parse, return a StringLocalizationInfo*, otherwise delete locData, set perror and status, 307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and return NULL. The StringLocalizationInfo will adopt locData if it is created. 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo* parse(UChar* data, int32_t len); 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruprivate: 312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void inc(void) { ++p; ch = 0xffff; } 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool checkInc(UChar c) { if (p < e && (ch == c || *p == c)) { inc(); return TRUE; } return FALSE; } 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool check(UChar c) { return p < e && (ch == c || *p == c); } 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void skipWhitespace(void) { while (p < e && PatternProps::isWhiteSpace(ch != 0xffff ? ch : *p)) inc();} 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool inList(UChar c, const UChar* list) const { 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (*list == SPACE && PatternProps::isWhiteSpace(c)) return TRUE; 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*list && *list != c) ++list; return *list == c; 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru void parseError(const char* msg); 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru StringLocalizationInfo* doParse(void); 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar** nextArray(int32_t& requiredLength); 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* nextString(void); 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef DEBUG 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ERROR(msg) parseError(msg); return NULL; 331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define ERROR(msg) parseError(NULL); return NULL; 333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar DQUOTE_STOPLIST[] = { 337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru QUOTE, 0 338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar SQUOTE_STOPLIST[] = { 341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TICK, 0 342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar NOQUOTE_STOPLIST[] = { 345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru SPACE, COMMA, CLOSE_ANGLE, OPEN_ANGLE, TICK, QUOTE, 0 346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic void 349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDeleteFn(void* p) { 350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(p); 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::parse(UChar* _data, int32_t len) { 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(ec)) { 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_data) uprv_free(_data); 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.line = 0; 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.offset = -1; 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.postContext[0] = 0; 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.preContext[0] = 0; 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (_data == NULL) { 366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len <= 0) { 371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(_data); 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = _data; 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e = data + len; 378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p = _data; 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ch = 0xffff; 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return doParse(); 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::doParse(void) { 387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(OPEN_ANGLE)) { 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing open angle"); 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray array(DeleteFn); 392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mightHaveNext = TRUE; 393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t requiredLength = -1; 394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (mightHaveNext) { 395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = FALSE; 396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar** elem = nextArray(requiredLength); 397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveComma = check(COMMA); 399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (elem) { 400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(elem, ec); 401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveComma) { 402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = TRUE; 404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (haveComma) { 406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected character"); 407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(CLOSE_ANGLE)) { 412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (check(OPEN_ANGLE)) { 413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing comma in outer array"); 414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing close angle bracket in outer array"); 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p != e) { 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Extra text after close of localization data"); 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(NULL, ec); 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t numLocs = array.length() - 2; // subtract first, NULL 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar*** result = (UChar***)array.release(); 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new StringLocalizationInfo(data, result, requiredLength-2, numLocs); // subtract first, NULL 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unknown error"); 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUChar** 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::nextArray(int32_t& requiredLength) { 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(ec)) { 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(OPEN_ANGLE)) { 444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing open angle"); 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru VArray array; 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mightHaveNext = TRUE; 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (mightHaveNext) { 450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = FALSE; 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* elem = nextString(); 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveComma = check(COMMA); 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (elem) { 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(elem, ec); 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveComma) { 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru mightHaveNext = TRUE; 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (haveComma) { 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected comma"); 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!checkInc(CLOSE_ANGLE)) { 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (check(OPEN_ANGLE)) { 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing close angle bracket in inner array"); 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing comma in inner array"); 470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru array.add(NULL, ec); 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (requiredLength == -1) { 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru requiredLength = array.length() + 1; 477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (array.length() != requiredLength) { 478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Array not of required length"); 480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (UChar**)array.release(); 483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unknown Error"); 485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUChar* 488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::nextString() { 489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* result = NULL; 490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru skipWhitespace(); 492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p < e) { 493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* terminators; 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar c = *p; 495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool haveQuote = c == QUOTE || c == TICK; 496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveQuote) { 497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminators = c == QUOTE ? DQUOTE_STOPLIST : SQUOTE_STOPLIST; 499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru terminators = NOQUOTE_STOPLIST; 501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* start = p; 503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p < e && !inList(*p, terminators)) ++p; 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == e) { 505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected end of data"); 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar x = *p; 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p > start) { 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ch = x; 511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *p = 0x0; // terminate by writing to data 512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = start; // just point into data 513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (haveQuote) { 515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (x != c) { 516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Missing matching quote"); 517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (p == start) { 518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Empty string"); 519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru inc(); 521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (x == OPEN_ANGLE || x == TICK || x == QUOTE) { 522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ERROR("Unexpected character in string"); 523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // ok for there to be no next string 527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocDataParser::parseError(const char* /*str*/) { 532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!data) { 533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* start = p - U_PARSE_CONTEXT_LEN - 1; 537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (start < data) { 538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = data; 539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (UChar* x = p; --x >= start;) { 541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!*x) { 542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = x+1; 543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar* limit = p + U_PARSE_CONTEXT_LEN - 1; 547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (limit > e) { 548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru limit = e; 549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_strncpy(pe.preContext, start, (int32_t)(p-start)); 551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.preContext[p-start] = 0; 552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru u_strncpy(pe.postContext, p, (int32_t)(limit-p)); 553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.postContext[limit-p] = 0; 554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pe.offset = (int32_t)(p - data); 555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#ifdef DEBUG 557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s at or near character %d: ", str, p-data); 558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString msg; 560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append(start, p - start); 561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append((UChar)0x002f); /* SOLIDUS/SLASH */ 562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append(p, limit-p); 563ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru msg.append("'"); 564ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char buf[128]; 566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = msg.extract(0, msg.length(), buf, 128); 567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len >= 128) { 568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[127] = 0; 569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru buf[len] = 0; 571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fprintf(stderr, "%s\n", buf); 573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fflush(stderr); 574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(data); 577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru data = NULL; 578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru p = NULL; 579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru e = NULL; 580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(ec)) { 582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_PARSE_ERROR; 583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//UOBJECT_DEFINE_RTTI_IMPLEMENTATION(StringLocalizationInfo) 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo* 589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::create(const UnicodeString& info, UParseError& perror, UErrorCode& status) { 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = info.length(); 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (len == 0) { 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; // no error; 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* p = (UChar*)uprv_malloc(len * sizeof(UChar)); 600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!p) { 601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru info.extract(p, len, status); 605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!U_FAILURE(status)) { 606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ZERO_ERROR; // clear warning about non-termination 607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocDataParser parser(perror, status); 610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return parser.parse(p, len); 611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::~StringLocalizationInfo() { 614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (UChar*** p = (UChar***)data; *p; ++p) { 615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // remaining data is simply pointer into our unicode string data. 616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (*p) uprv_free(*p); 617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (data) uprv_free(data); 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (info) uprv_free(info); 620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getRuleSetName(int32_t index) const { 625ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (index >= 0 && index < getNumberOfRuleSets()) { 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[0][index]; 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 632ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getLocaleName(int32_t index) const { 633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (index >= 0 && index < getNumberOfDisplayLocales()) { 634ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[index+1][0]; 635ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 636ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 637ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* 640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruStringLocalizationInfo::getDisplayName(int32_t localeIndex, int32_t ruleIndex) const { 641ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localeIndex >= 0 && localeIndex < getNumberOfDisplayLocales() && 642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleIndex >= 0 && ruleIndex < getNumberOfRuleSets()) { 643ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return data[localeIndex+1][ruleIndex+1]; 644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 645ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 646ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 647ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ---------- 649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 650ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& locs, 652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& alocale, UParseError& perror, UErrorCode& status) 653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 658ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho , noParse(FALSE) //TODO: to be removed after #6895 662ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status); 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, locinfo, perror, status); 665ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 666ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& locs, 669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, UErrorCode& status) 670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(Locale::getDefault()) 673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 67885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho , noParse(FALSE) //TODO: to be removed after #6895 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = StringLocalizationInfo::create(locs, perror, status); 681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, locinfo, perror, status); 682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* info, 686ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& alocale, UParseError& perror, UErrorCode& status) 687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 69585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho , noParse(FALSE) //TODO: to be removed after #6895 696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, info, perror, status); 698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, 702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(Locale::getDefault()) 706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 71185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho , noParse(FALSE) //TODO: to be removed after #6895 712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, NULL, perror, status); 714ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 715ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 716ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const UnicodeString& description, 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& aLocale, 718ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& perror, 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 721ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 722ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(aLocale) 723ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 724ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 725ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 726ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 727ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 72885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho , noParse(FALSE) //TODO: to be removed after #6895 729ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 730ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(description, NULL, perror, status); 731ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 732ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 733ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(URBNFRuleSetTag tag, const Locale& alocale, UErrorCode& status) 734ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : ruleSets(NULL) 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(alocale) 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 738ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 739ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 740ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 741ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 742ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 743ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 744ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 745ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 746ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 74785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const char* rules_tag = "RBNFRules"; 748ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const char* fmt_tag = ""; 749ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru switch (tag) { 750ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_SPELLOUT: fmt_tag = "SpelloutRules"; break; 751ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_ORDINAL: fmt_tag = "OrdinalRules"; break; 752ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case URBNF_DURATION: fmt_tag = "DurationRules"; break; 75385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho case URBNF_NUMBERING_SYSTEM: fmt_tag = "NumberingSystemRules"; break; 754ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: status = U_ILLEGAL_ARGUMENT_ERROR; return; 755ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 756ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 757ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO: read localization info from resource 758ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru LocalizationInfo* locinfo = NULL; 759ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 760ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = 0; 761ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UResourceBundle* nfrb = ures_open(U_ICUDATA_RBNF, locale.getName(), &status); 762ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 763ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocaleIDs(ures_getLocaleByType(nfrb, ULOC_VALID_LOCALE, &status), 764ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_getLocaleByType(nfrb, ULOC_ACTUAL_LOCALE, &status)); 76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 76685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UResourceBundle* rbnfRules = ures_getByKeyWithFallback(nfrb, rules_tag, NULL, &status); 76785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 76885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(nfrb); 76985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 77085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UResourceBundle* ruleSets = ures_getByKeyWithFallback(rbnfRules, fmt_tag, NULL, &status); 77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(rbnfRules); 77385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(nfrb); 77485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 77585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 77685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UnicodeString desc; 77885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho while (ures_hasNext(ruleSets)) { 77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UChar* currentString = ures_getNextString(ruleSets,&len,NULL,&status); 78085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho desc.append(currentString); 78185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 782ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError perror; 78385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 78485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 785ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init (desc, locinfo, perror, status); 78685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho //TODO: we need a real fix - see #6895 / #6896 78885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho noParse = FALSE; 78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (tag == URBNF_SPELLOUT) { 79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const char *lang = alocale.getLanguage(); 79185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho for (int32_t i = 0; NO_SPELLOUT_PARSE_LANGUAGES[i] != NULL; i++) { 79285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (uprv_strcmp(lang, NO_SPELLOUT_PARSE_LANGUAGES[i]) == 0) { 79385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho noParse = TRUE; 79485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 79585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 79685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 79785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 79885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho //TODO: end 79985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 80085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(ruleSets); 80185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ures_close(rbnfRules); 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ures_close(nfrb); 804ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::RuleBasedNumberFormat(const RuleBasedNumberFormat& rhs) 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : NumberFormat(rhs) 808ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , ruleSets(NULL) 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , defaultRuleSet(NULL) 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , locale(rhs.locale) 811ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , collator(NULL) 812ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , decimalFormatSymbols(NULL) 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenient(FALSE) 814ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , lenientParseRules(NULL) 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru , localizations(NULL) 816ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->operator=(rhs); 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 820ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// -------- 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 822ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat& 823ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::operator=(const RuleBasedNumberFormat& rhs) 824ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 826ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dispose(); 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru locale = rhs.locale; 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient = rhs.lenient; 829ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rules = rhs.getRules(); 831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError perror; 832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru init(rules, rhs.localizations ? rhs.localizations->ref() : NULL, perror, status); 833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 83485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho //TODO: remove below when we fix the parse bug - See #6895 / #6896 83585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho noParse = rhs.noParse; 83685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 837ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 838ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 839ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 840ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::~RuleBasedNumberFormat() 841ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 842ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dispose(); 843ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 844ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 845ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat* 846ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::clone(void) const 847ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 848ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RuleBasedNumberFormat * result = NULL; 849ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rules = getRules(); 850ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 851ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError perror; 852ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = new RuleBasedNumberFormat(rules, localizations, locale, perror, status); 853ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* test for NULL */ 854ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result == 0) { 855ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 856ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 857ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 858ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 859ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete result; 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = 0; 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result->lenient = lenient; 86385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 86485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho //TODO: remove below when we fix the parse bug - See #6895 / #6896 86585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho result->noParse = noParse; 866ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 867ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 868ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 871ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::operator==(const Format& other) const 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 873ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == &other) { 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 876ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 87727f654740f2a26ad62a5c155af9199af9e69b889claireho if (typeid(*this) == typeid(other)) { 878ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const RuleBasedNumberFormat& rhs = (const RuleBasedNumberFormat&)other; 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (locale == rhs.locale && 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient == rhs.lenient && 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (localizations == NULL 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ? rhs.localizations == NULL 883ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : (rhs.localizations == NULL 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ? FALSE 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru : *localizations == rhs.localizations))) { 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 887ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet** p = ruleSets; 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet** q = rhs.ruleSets; 889ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == NULL) { 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return q == NULL; 891ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (q == NULL) { 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 894ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*p && *q && (**p == **q)) { 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++p; 896ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++q; 897ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 898ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *q == NULL && *p == NULL; 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 901ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRules() const 907ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 909ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets != NULL) { 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 911ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru (*p)->appendRules(result); 912ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 913ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 914ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 915ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 916ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 917ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 918ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetName(int32_t index) const 919ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 920ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 921ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString string(TRUE, localizations->getRuleSetName(index), (int32_t)-1); 922ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return string; 923ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (ruleSets) { 924ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 925ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 926ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = *p; 927ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs->isPublic()) { 928ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (--index == -1) { 929ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs->getName(result); 930ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 931ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 932ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 935ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString empty; 936ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return empty; 937ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 938ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 939ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 940ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getNumberOfRuleSetNames() const 941ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t result = 0; 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 944ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = localizations->getNumberOfRuleSets(); 945ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (ruleSets) { 946ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 947ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((**p).isPublic()) { 948ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++result; 949ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 950ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 951ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 952ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 953ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 954ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 955ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruint32_t 956ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getNumberOfRuleSetDisplayNameLocales(void) const { 957ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 958ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return localizations->getNumberOfDisplayLocales(); 959ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 960ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; 961ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 962ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 963ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruLocale 964ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayNameLocale(int32_t index, UErrorCode& status) const { 965ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 966ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return Locale(""); 967ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 968ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations && index >= 0 && index < localizations->getNumberOfDisplayLocales()) { 969ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getLocaleName(index), -1); 970ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char buffer[64]; 971ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cap = name.length() + 1; 972ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru char* bp = buffer; 973ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (cap > 64) { 974ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bp = (char *)uprv_malloc(cap); 975ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bp == NULL) { 976ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 977ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return Locale(""); 978ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 979ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 980ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru name.extract(0, name.length(), bp, cap, UnicodeString::kInvariant); 981ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Locale retLocale(bp); 982ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (bp != buffer) { 983ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(bp); 984ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 985ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return retLocale; 986ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 987ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 988ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Locale retLocale; 989ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return retLocale; 990ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 991ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 992ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 993ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayName(int32_t index, const Locale& localeParam) { 994ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations && index >= 0 && index < localizations->getNumberOfRuleSets()) { 995ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString localeName(localeParam.getBaseName(), -1, UnicodeString::kInvariant); 996ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t len = localeName.length(); 997ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar* localeStr = localeName.getBuffer(len + 1); 998ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (len >= 0) { 999ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru localeStr[len] = 0; 1000ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = localizations->indexForLocale(localeStr); 1001ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ix >= 0) { 1002ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getDisplayName(ix, index), -1); 1003ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 1004ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1005ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1006ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // trim trailing portion, skipping over ommitted sections 1007ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru do { --len;} while (len > 0 && localeStr[len] != 0x005f); // underscore 1008ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (len > 0 && localeStr[len-1] == 0x005F) --len; 1009ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1010ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getRuleSetName(index), -1); 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return name; 1012ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1013ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString bogus; 1014ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bogus.setToBogus(); 1015ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return bogus; 1016ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1017ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1018ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 1019ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getRuleSetDisplayName(const UnicodeString& ruleSetName, const Locale& localeParam) { 1020ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1021ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rsn(ruleSetName); 1022ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t ix = localizations->indexForRuleSet(rsn.getTerminatedBuffer()); 1023ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return getRuleSetDisplayName(ix, localeParam); 1024ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1025ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString bogus; 1026ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru bogus.setToBogus(); 1027ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return bogus; 1028ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1029ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1030ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruNFRuleSet* 1031ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::findRuleSet(const UnicodeString& name, UErrorCode& status) const 1032ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1033ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status) && ruleSets) { 1034ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1035ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = *p; 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs->isNamed(name)) { 1037ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return rs; 1038ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1040ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1041ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1042ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1043ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1044ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1045ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1046ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int32_t number, 1047ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1048ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */) const 1049ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1050ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (defaultRuleSet) defaultRuleSet->format((int64_t)number, toAppendTo, toAppendTo.length()); 1051ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1052ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1053ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1054ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1055ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1056ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int64_t number, 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1058ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */) const 1059ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1060ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (defaultRuleSet) defaultRuleSet->format(number, toAppendTo, toAppendTo.length()); 1061ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1062ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1063ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1064ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1065ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1066ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(double number, 1067ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1068ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */) const 1069ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1070b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Special case for NaN; adapted from what DecimalFormat::_format( double number,...) does. 1071b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (uprv_isNaN(number)) { 1072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho DecimalFormatSymbols* decFmtSyms = getDecimalFormatSymbols(); // RuleBasedNumberFormat internal 1073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (decFmtSyms) { 1074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho toAppendTo += decFmtSyms->getConstSymbol(DecimalFormatSymbols::kNaNSymbol); 1075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (defaultRuleSet) { 1077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho defaultRuleSet->format(number, toAppendTo, toAppendTo.length()); 1078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1079ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1080ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1081ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1082ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1083ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1084ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int32_t number, 1085ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1086ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */, 1088ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1089ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1090ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // return format((int64_t)number, ruleSetName, toAppendTo, pos, status); 1091ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1092ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetName.indexOf(gPercentPercent) == 0) { 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new IllegalArgumentException("Can't use internal rule set"); 1094ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1095ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1096ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rs = findRuleSet(ruleSetName, status); 1097ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs) { 1098ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs->format((int64_t)number, toAppendTo, toAppendTo.length()); 1099ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(int64_t number, 1108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */, 1111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetName.indexOf(gPercentPercent) == 0) { 1115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new IllegalArgumentException("Can't use internal rule set"); 1116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rs = findRuleSet(ruleSetName, status); 1119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs) { 1120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs->format(number, toAppendTo, toAppendTo.length()); 1121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// make linker happy 1129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(const Formattable& obj, 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& pos, 1133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NumberFormat::format(obj, toAppendTo, pos, status); 1136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 1139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::format(double number, 1140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UnicodeString& ruleSetName, 1141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString& toAppendTo, 1142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru FieldPosition& /* pos */, 1143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) const 1144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetName.indexOf(gPercentPercent) == 0) { 1147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // throw new IllegalArgumentException("Can't use internal rule set"); 1148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rs = findRuleSet(ruleSetName, status); 1151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs) { 1152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rs->format(number, toAppendTo, toAppendTo.length()); 1153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return toAppendTo; 1157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::parse(const UnicodeString& text, 1161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable& result, 1162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition& parsePosition) const 1163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 116485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho //TODO: We need a real fix. See #6895 / #6896 116585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (noParse) { 116685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // skip parsing 116785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parsePosition.setErrorIndex(0); 116885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 116985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 117085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru parsePosition.setErrorIndex(0); 1173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString workingText(text, parsePosition.getIndex()); 1177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition workingPos(0); 1178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition high_pp(0); 1180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable high_result; 1181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet *rp = *p; 118485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (rp->isPublic() && rp->isParseable()) { 1185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition working_pp(0); 1186ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable working_result; 1187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rp->parse(workingText, working_pp, kMaxDouble, working_result); 1189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (working_pp.getIndex() > high_pp.getIndex()) { 1190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru high_pp = working_pp; 1191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru high_result = working_result; 1192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (high_pp.getIndex() == workingText.length()) { 1194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 120085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t startIndex = parsePosition.getIndex(); 120185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parsePosition.setIndex(startIndex + high_pp.getIndex()); 1202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (high_pp.getIndex() > 0) { 1203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru parsePosition.setErrorIndex(-1); 120485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 120585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t errorIndex = (high_pp.getErrorIndex()>0)? high_pp.getErrorIndex(): 0; 120685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho parsePosition.setErrorIndex(startIndex + errorIndex); 1207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result = high_result; 1209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result.getType() == Formattable::kDouble) { 1210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t r = (int32_t)result.getDouble(); 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((double)r == result.getDouble()) { 1212ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.setLong(r); 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1214ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::setLenient(UBool enabled) 1221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenient = enabled; 1223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!enabled && collator) { 1224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete collator; 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru collator = NULL; 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::setDefaultRuleSet(const UnicodeString& ruleSetName, UErrorCode& status) { 1233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetName.isEmpty()) { 1235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) { 1236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizations->getRuleSetName(0), -1); 1237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = findRuleSet(name, status); 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initDefaultRuleSet(); 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (ruleSetName.startsWith(UNICODE_STRING_SIMPLE("%%"))) { 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_ILLEGAL_ARGUMENT_ERROR; 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* result = findRuleSet(ruleSetName, status); 1245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (result != NULL) { 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = result; 1247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString 1253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getDefaultRuleSetName() const { 1254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 1255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (defaultRuleSet && defaultRuleSet->isPublic()) { 1256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet->getName(result); 1257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.setToBogus(); 1259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 1261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::initDefaultRuleSet() 1265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = NULL; 1267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 127185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UnicodeString spellout = UNICODE_STRING_SIMPLE("%spellout-numbering"); 127285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UnicodeString ordinal = UNICODE_STRING_SIMPLE("%digits-ordinal"); 127385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UnicodeString duration = UNICODE_STRING_SIMPLE("%duration"); 127485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet**p = &ruleSets[0]; 1276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (*p) { 127785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if ((*p)->isNamed(spellout) || (*p)->isNamed(ordinal) || (*p)->isNamed(duration)) { 127885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho defaultRuleSet = *p; 127985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 128085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 128185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ++p; 128285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = *--p; 1286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!defaultRuleSet->isPublic()) { 1287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (p != ruleSets) { 1288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if ((*--p)->isPublic()) { 1289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = *p; 1290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::init(const UnicodeString& rules, LocalizationInfo* localizationInfos, 1299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& pErr, UErrorCode& status) 1300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // TODO: implement UParseError 1302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(&pErr, 0, sizeof(UParseError)); 1303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Note: this can leave ruleSets == NULL, so remaining code should check 1304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(status)) { 1305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru this->localizations = localizationInfos == NULL ? NULL : localizationInfos->ref(); 1309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString description(rules); 1311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!description.length()) { 1312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // start by stripping the trailing whitespace from all the rules 1317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (this is all the whitespace follwing each semicolon in the 1318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // description). This allows us to look for rule-set boundaries 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // by searching for ";%" without having to worry about whitespace 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // between the ; and the % 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru stripWhitespace(description); 1322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // check to see if there's a set of lenient-parse rules. If there 1324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is, pull them out into our temporary holding place for them, 1325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and delete them from the description before the real desciption- 1326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // parsing code sees them 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t lp = description.indexOf(gLenientParse); 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lp != -1) { 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we've got to make sure we're not in the middle of a rule 1330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (where "%%lenient-parse" would actually get treated as 1331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule text) 1332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lp == 0 || description.charAt(lp - 1) == gSemiColon) { 1333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // locate the beginning and end of the actual collation 1334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rules (there may be whitespace between the name and 1335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the first token in the description) 1336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int lpEnd = description.indexOf(gSemiPercent, lp); 1337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lpEnd == -1) { 1339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lpEnd = description.length() - 1; 1340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int lpStart = lp + u_strlen(gLenientParse); 1342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho while (PatternProps::isWhiteSpace(description.charAt(lpStart))) { 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++lpStart; 1344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // copy out the lenient-parse rules and delete them 1347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // from the description 1348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules = new UnicodeString(); 1349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* test for NULL */ 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lenientParseRules == 0) { 1351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules->setTo(description, lpStart, lpEnd - lpStart); 1355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru description.remove(lp, lpEnd + 1 - lp); 1357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // pre-flight parsing the description and count the number of 1361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule sets (";%" marks the end of one rule set and the beginning 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // of the next) 1363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int numRuleSets = 0; 1364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t p = description.indexOf(gSemiPercent); p != -1; p = description.indexOf(gSemiPercent, p)) { 1365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++numRuleSets; 1366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++p; 1367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++numRuleSets; 1369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // our rule list is an array of the appropriate size 1371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets = (NFRuleSet **)uprv_malloc((numRuleSets + 1) * sizeof(NFRuleSet *)); 1372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* test for NULL */ 1373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets == 0) { 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i <= numRuleSets; ++i) { 1379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets[i] = NULL; 1380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // divide up the descriptions into individual rule-set descriptions 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and store them in a temporary array. At each step, we also 1384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // new up a rule set, but all this does is initialize its name 1385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // and remove it from its description. We can't actually parse 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the rest of the descriptions and finish initializing everything 1387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // because we have to know the names and locations of all the rule 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // sets before we can actually set everything up 1389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(!numRuleSets) { 139085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho status = U_ILLEGAL_ARGUMENT_ERROR; 139185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString* ruleSetDescriptions = new UnicodeString[numRuleSets]; 1394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSetDescriptions == 0) { 1395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 1396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int curRuleSet = 0; 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t start = 0; 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t p = description.indexOf(gSemiPercent); p != -1; p = description.indexOf(gSemiPercent, start)) { 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSetDescriptions[curRuleSet].setTo(description, start, p + 1 - start); 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet, status); 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets[curRuleSet] == 0) { 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 140785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho goto cleanup; 1408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++curRuleSet; 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = p + 1; 1411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSetDescriptions[curRuleSet].setTo(description, start, description.length() - start); 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets[curRuleSet] = new NFRuleSet(ruleSetDescriptions, curRuleSet, status); 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets[curRuleSet] == 0) { 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 141685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho goto cleanup; 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // now we can take note of the formatter's default rule set, which 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is the last public rule set in the description (it's the last 1422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rather than the first so that a user can create a new formatter 1423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // from an existing formatter and change its default behavior just 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // by appending more rule sets to the end) 1425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // {dlf} Initialization of a fraction rule set requires the default rule 1427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // set to be known. For purposes of initialization, this is always the 1428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // last public rule set, no matter what the localization data says. 1429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru initDefaultRuleSet(); 1430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // finally, we can go back through the temporary descriptions 1432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // list and finish seting up the substructure (and we throw 1433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // away the temporary descriptions as we go) 1434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru { 1435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int i = 0; i < numRuleSets; i++) { 1436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets[i]->parseRules(ruleSetDescriptions[i], this, status); 1437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Now that the rules are initialized, the 'real' default rule 1441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // set can be adjusted by the localization data. 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // The C code keeps the localization array as is, rather than building 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // a separate array of the public rule set names, so we have less work 1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // to do here-- but we still need to check the names. 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizationInfos) { 1448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // confirm the names, if any aren't in the rules, that's an error 1449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // it is ok if the rules contain public rule sets that are not in this list 1450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = 0; i < localizationInfos->getNumberOfRuleSets(); ++i) { 1451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString name(TRUE, localizationInfos->getRuleSetName(i), -1); 1452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NFRuleSet* rs = findRuleSet(name, status); 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (rs == NULL) { 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; // error 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (i == 0) { 1457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = rs; 1458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultRuleSet = getDefaultRuleSet(); 1462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 146385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 146485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hocleanup: 146585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho delete[] ruleSetDescriptions; 1466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::stripWhitespace(UnicodeString& description) 1470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // iterate through the characters... 1472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString result; 1473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int start = 0; 1475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (start != -1 && start < description.length()) { 1476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // seek to the first non-whitespace character... 1477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru while (start < description.length() 1478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho && PatternProps::isWhiteSpace(description.charAt(start))) { 1479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ++start; 1480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // locate the next semicolon in the text and copy the text from 1483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // our current position up to that semicolon into the result 1484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t p = description.indexOf(gSemiColon, start); 1485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (p == -1) { 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // or if we don't find a semicolon, just copy the rest of 1487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // the string into the result 1488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(description, start, description.length() - start); 1489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = -1; 1490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else if (p < description.length()) { 1492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.append(description, start, p + 1 - start); 1493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = p + 1; 1494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // when we get here, we've seeked off the end of the sring, and 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // we terminate the loop (we continue until *start* is -1 rather 1498ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // than until *p* is -1, because otherwise we'd miss the last 1499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rule in the description) 1500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 1501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru start = -1; 1502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru description.setTo(result); 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::dispose() 1511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (ruleSets) { 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (NFRuleSet** p = ruleSets; *p; ++p) { 1514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete *p; 1515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(ruleSets); 1517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ruleSets = NULL; 1518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete collator; 1522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru collator = NULL; 1524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete decimalFormatSymbols; 1526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru decimalFormatSymbols = NULL; 1527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete lenientParseRules; 1529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru lenientParseRules = NULL; 1530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (localizations) localizations = localizations->unref(); 1532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------- 1536ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// package-internal API 1537ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//----------------------------------------------------------------------- 1538ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1539ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1540ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Returns the collator to use for lenient parsing. The collator is lazily created: 1541ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * this function creates it the first time it's called. 1542ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The collator to use for lenient parsing, or null if lenient parsing 1543ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * is turned off. 1544ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1545ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruCollator* 1546ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getCollator() const 1547ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1548ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1549ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!ruleSets) { 1550ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1551ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1552ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // lazy-evaulate the collator 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (collator == NULL && lenient) { 1555ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // create a default collator based on the formatter's locale, 1556ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // then pull out that collator's rules, append any additional 1557ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // rules specified in the description, and create a _new_ 1558ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // collator based on the combinaiton of those rules 1559ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1560ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 1561ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1562ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Collator* temp = Collator::createInstance(locale, status); 156327f654740f2a26ad62a5c155af9199af9e69b889claireho RuleBasedCollator* newCollator; 156427f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_SUCCESS(status) && (newCollator = dynamic_cast<RuleBasedCollator*>(temp)) != NULL) { 1565ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (lenientParseRules) { 1566ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UnicodeString rules(newCollator->getRules()); 1567ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru rules.append(*lenientParseRules); 1568ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCollator = new RuleBasedCollator(rules, status); 157085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho // Exit if newCollator could not be created. 157185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (newCollator == NULL) { 157285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 157385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru temp = NULL; 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru newCollator->setAttribute(UCOL_DECOMPOSITION_MODE, UCOL_ON, status); 1579ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // cast away const 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((RuleBasedNumberFormat*)this)->collator = newCollator; 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete newCollator; 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1584ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1585ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete temp; 1586ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if lenient-parse mode is off, this will be null 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // (see setLenientParseMode()) 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return collator; 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Returns the DecimalFormatSymbols object that should be used by all DecimalFormat 1597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * instances owned by this formatter. This object is lazily created: this function 1598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * creates it the first time it's called. 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return The DecimalFormatSymbols object that should be used by all DecimalFormat 1600ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * instances owned by this formatter. 1601ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/ 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruDecimalFormatSymbols* 1603ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruRuleBasedNumberFormat::getDecimalFormatSymbols() const 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // lazy-evaluate the DecimalFormatSymbols object. This object 1606ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // is shared by all DecimalFormat instances belonging to this 1607ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // formatter 1608ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (decimalFormatSymbols == NULL) { 1609ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 1610ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru DecimalFormatSymbols* temp = new DecimalFormatSymbols(locale, status); 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_SUCCESS(status)) { 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ((RuleBasedNumberFormat*)this)->decimalFormatSymbols = temp; 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1614ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete temp; 1615ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1616ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return decimalFormatSymbols; 1618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1620ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* U_HAVE_RBNF */ 1623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 1624