150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/******************************************************************** 227f654740f2a26ad62a5c155af9199af9e69b889claireho * COPYRIGHT: 354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Copyright (c) 1997-2012, International Business Machines Corporation and 450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * others. All Rights Reserved. 550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ******************************************************************** 650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * File MSGFMT.CPP 850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Modification History: 1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Date Name Description 1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 02/19/97 aliu Converted from java. 1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 03/20/97 helena Finished first cut of implementation. 1450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 04/10/97 aliu Made to work on AIX. Added stoi to replace wtoi. 1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 06/11/97 helena Fixed addPattern to take the pattern correctly. 1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 06/17/97 helena Fixed the getPattern to return the correct pattern. 1750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 07/09/97 helena Made ParsePosition into a class. 1850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 02/22/99 stephen Removed character literals for EBCDIC safety 1927f654740f2a26ad62a5c155af9199af9e69b889claireho * 11/01/09 kirtig Added SelectFormat 2050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ********************************************************************/ 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/appendable.h" 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/choicfmt.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/datefmt.h" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/decimfmt.h" 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/localpointer.h" 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/msgfmt.h" 3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/plurfmt.h" 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/rbnf.h" 3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/selfmt.h" 35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/smpdtfmt.h" 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/umsg.h" 37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/ustring.h" 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h" 40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "messageimpl.h" 4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "msgfmt_impl.h" 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uassert.h" 43103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uelement.h" 44103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uhash.h" 4585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "ustrfmt.h" 46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "util.h" 4785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "uvector.h" 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************** 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// class MessageFormat 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ***************************************************************************** 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define SINGLE_QUOTE ((UChar)0x0027) 54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#define COMMA ((UChar)0x002C) 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define LEFT_CURLY_BRACE ((UChar)0x007B) 56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#define RIGHT_CURLY_BRACE ((UChar)0x007D) 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//--------------------------------------- 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// static data 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_NUMBER[] = { 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0 /* "number" */ 63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_DATE[] = { 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x64, 0x61, 0x74, 0x65, 0 /* "date" */ 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_TIME[] = { 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x74, 0x69, 0x6D, 0x65, 0 /* "time" */ 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_SPELLOUT[] = { 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x73, 0x70, 0x65, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0 /* "spellout" */ 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_ORDINAL[] = { 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0 /* "ordinal" */ 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_DURATION[] = { 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0 /* "duration" */ 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// MessageFormat Type List Number, Date, Time or Choice 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar * const TYPE_IDS[] = { 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_NUMBER, 8327f654740f2a26ad62a5c155af9199af9e69b889claireho ID_DATE, 84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_TIME, 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_SPELLOUT, 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_ORDINAL, 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_DURATION, 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 9027f654740f2a26ad62a5c155af9199af9e69b889claireho 91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar ID_EMPTY[] = { 92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 0 /* empty string, used for default so that null can mark end of list */ 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_CURRENCY[] = { 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x63, 0x79, 0 /* "currency" */ 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_PERCENT[] = { 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x70, 0x65, 0x72, 0x63, 0x65, 0x6E, 0x74, 0 /* "percent" */ 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_INTEGER[] = { 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x69, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0 /* "integer" */ 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// NumberFormat modifier list, default, currency, percent or integer 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar * const NUMBER_STYLE_IDS[] = { 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_EMPTY, 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_CURRENCY, 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_PERCENT, 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_INTEGER, 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_SHORT[] = { 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x73, 0x68, 0x6F, 0x72, 0x74, 0 /* "short" */ 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_MEDIUM[] = { 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x6D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0 /* "medium" */ 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_LONG[] = { 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x6C, 0x6F, 0x6E, 0x67, 0 /* "long" */ 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar ID_FULL[] = { 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 0x66, 0x75, 0x6C, 0x6C, 0 /* "full" */ 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// DateFormat modifier list, default, short, medium, long or full 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const UChar * const DATE_STYLE_IDS[] = { 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_EMPTY, 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_SHORT, 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_MEDIUM, 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_LONG, 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ID_FULL, 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NULL, 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 13527f654740f2a26ad62a5c155af9199af9e69b889claireho 136103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const icu::DateFormat::EStyle DATE_STYLES[] = { 137103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::DateFormat::kDefault, 138103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::DateFormat::kShort, 139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::DateFormat::kMedium, 140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::DateFormat::kLong, 141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius icu::DateFormat::kFull, 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}; 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const int32_t DEFAULT_INITIAL_CAPACITY = 10; 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar NULL_STRING[] = { 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 0x6E, 0x75, 0x6C, 0x6C, 0 // "null" 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar OTHER_STRING[] = { 151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 0x6F, 0x74, 0x68, 0x65, 0x72, 0 // "other" 152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}; 153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_BEGIN 155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic UBool U_CALLCONV equalFormatsForHash(const UHashTok key1, 156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashTok key2) { 157103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return icu::MessageFormat::equalFormats(key1.pointer, key2.pointer); 158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_CDECL_END 161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_BEGIN 163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(MessageFormat) 16685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(FormatNameEnumeration) 167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-------------------------------------------------------------------- 169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Convert an integer value to a string and append the result to 172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * the given UnicodeString. 173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UnicodeString& itos(int32_t i, UnicodeString& appendTo) { 175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UChar temp[16]; 176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_itou(temp,16,i,10,0); // 10 == radix 177103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius appendTo.append(temp, -1); 178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// AppendableWrapper: encapsulates the result of formatting, keeping track 183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// of the string and its length. 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoclass AppendableWrapper : public UMemory { 18585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hopublic: 186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho AppendableWrapper(Appendable& appendable) : app(appendable), len(0) { 18785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void append(const UnicodeString& s) { 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho app.appendString(s.getBuffer(), s.length()); 190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho len += s.length(); 19185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void append(const UChar* s, const int32_t sLength) { 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho app.appendString(s, sLength); 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho len += sLength; 195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void append(const UnicodeString& s, int32_t start, int32_t length) { 197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho append(s.tempSubString(start, length)); 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void formatAndAppend(const Format* formatter, const Formattable& arg, UErrorCode& ec) { 200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString s; 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatter->format(arg, s, ec); 202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(ec)) { 203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho append(s); 204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length() { 207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return len; 20885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Appendable& app; 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len; 21285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}; 21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 215ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 216ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Creates a MessageFormat instance based on the pattern. 217ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::MessageFormat(const UnicodeString& pattern, 219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) 220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: fLocale(Locale::getDefault()), // Uses the default locale 221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(success), 222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliases(NULL), 223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliasesCapacity(0), 224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypes(NULL), 225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCount(0), 226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCapacity(0), 227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts(FALSE), 228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultNumberFormat(NULL), 229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho defaultDateFormat(NULL), 230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters(NULL), 231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts(NULL), 23254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius pluralProvider(&fLocale, UPLURAL_TYPE_CARDINAL), 23354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ordinalProvider(&fLocale, UPLURAL_TYPE_ORDINAL) 234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocaleIDs(fLocale.getName(), fLocale.getName()); 236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho applyPattern(pattern, success); 237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 23827f654740f2a26ad62a5c155af9199af9e69b889claireho 239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::MessageFormat(const UnicodeString& pattern, 240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& newLocale, 241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) 242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: fLocale(newLocale), 243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(success), 244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliases(NULL), 245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliasesCapacity(0), 246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypes(NULL), 247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCount(0), 248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCapacity(0), 249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts(FALSE), 250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultNumberFormat(NULL), 251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho defaultDateFormat(NULL), 252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters(NULL), 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts(NULL), 25454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius pluralProvider(&fLocale, UPLURAL_TYPE_CARDINAL), 25554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ordinalProvider(&fLocale, UPLURAL_TYPE_ORDINAL) 256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocaleIDs(fLocale.getName(), fLocale.getName()); 258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho applyPattern(pattern, success); 259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::MessageFormat(const UnicodeString& pattern, 262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Locale& newLocale, 263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& parseError, 264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) 265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru: fLocale(newLocale), 266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(success), 267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliases(NULL), 268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliasesCapacity(0), 269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypes(NULL), 270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCount(0), 271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCapacity(0), 272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts(FALSE), 273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultNumberFormat(NULL), 274b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho defaultDateFormat(NULL), 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters(NULL), 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts(NULL), 27754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius pluralProvider(&fLocale, UPLURAL_TYPE_CARDINAL), 27854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ordinalProvider(&fLocale, UPLURAL_TYPE_ORDINAL) 279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocaleIDs(fLocale.getName(), fLocale.getName()); 281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho applyPattern(pattern, parseError, success); 282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::MessageFormat(const MessageFormat& that) 285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho: 286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format(that), 287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocale(that.fLocale), 288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(that.msgPattern), 289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliases(NULL), 290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru formatAliasesCapacity(0), 291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypes(NULL), 292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCount(0), 293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru argTypeCapacity(0), 294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts(that.hasArgTypeConflicts), 295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultNumberFormat(NULL), 296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho defaultDateFormat(NULL), 297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters(NULL), 298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts(NULL), 29954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius pluralProvider(&fLocale, UPLURAL_TYPE_CARDINAL), 30054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ordinalProvider(&fLocale, UPLURAL_TYPE_ORDINAL) 301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This will take care of creating the hash tables (since they are NULL). 303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode ec = U_ZERO_ERROR; 304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho copyObjects(that, ec); 305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho resetPattern(); 307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::~MessageFormat() 311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(cachedFormatters); 313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(customFormatArgStarts); 314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(argTypes); 316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(formatAliases); 317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete defaultNumberFormat; 318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete defaultDateFormat; 319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//-------------------------------------------------------------------- 322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Variable-size array management 323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Allocate argTypes[] to at least the given capacity and return 326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TRUE if successful. If not, leave argTypes[] unchanged. 327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * If argTypes is NULL, allocate it. If it is not NULL, enlarge it 329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * if necessary to be at least as large as specified. 330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool MessageFormat::allocateArgTypes(int32_t capacity, UErrorCode& status) { 332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argTypeCapacity >= capacity) { 336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (capacity < DEFAULT_INITIAL_CAPACITY) { 339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho capacity = DEFAULT_INITIAL_CAPACITY; 340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (capacity < 2*argTypeCapacity) { 341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho capacity = 2*argTypeCapacity; 342b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 343b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable::Type* a = (Formattable::Type*) 344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_realloc(argTypes, sizeof(*argTypes) * capacity); 345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (a == NULL) { 346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypes = a; 350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypeCapacity = capacity; 351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// assignment operator 356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst MessageFormat& 358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::operator=(const MessageFormat& that) 359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (this != &that) { 361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Calls the super class for assignment first. 362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Format::operator=(that); 363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru setLocale(that.fLocale); 365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern = that.msgPattern; 366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts = that.hasArgTypeConflicts; 36727f654740f2a26ad62a5c155af9199af9e69b889claireho 368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode ec = U_ZERO_ERROR; 369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho copyObjects(that, ec); 370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho resetPattern(); 372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return *this; 375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool 37827f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::operator==(const Format& rhs) const 379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (this == &rhs) return TRUE; 38127f654740f2a26ad62a5c155af9199af9e69b889claireho 382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MessageFormat& that = (MessageFormat&)rhs; 383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Check class ID before checking MessageFormat members 385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!Format::operator==(rhs) || 386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern != that.msgPattern || 387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocale != that.fLocale) { 388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 391b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Compare hashtables. 392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((customFormatArgStarts == NULL) != (that.customFormatArgStarts == NULL)) { 393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts == NULL) { 396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return TRUE; 397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode ec = U_ZERO_ERROR; 400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t count = uhash_count(customFormatArgStarts); 401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t rhs_count = uhash_count(that.customFormatArgStarts); 402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (count != rhs_count) { 403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t idx = 0, rhs_idx = 0, pos = -1, rhs_pos = -1; 406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (; idx < count && rhs_idx < rhs_count && U_SUCCESS(ec); ++idx, ++rhs_idx) { 407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashElement* cur = uhash_nextElement(customFormatArgStarts, &pos); 408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashElement* rhs_cur = uhash_nextElement(that.customFormatArgStarts, &rhs_pos); 409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cur->key.integer != rhs_cur->key.integer) { 410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return FALSE; 411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Format* format = (const Format*)uhash_iget(cachedFormatters, cur->key.integer); 413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Format* rhs_format = (const Format*)uhash_iget(that.cachedFormatters, rhs_cur->key.integer); 414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (*format != *rhs_format) { 415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return FALSE; 416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return TRUE; 419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Creates a copy of this MessageFormat, the caller owns the copy. 42327f654740f2a26ad62a5c155af9199af9e69b889claireho 424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormat* 425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::clone() const 426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return new MessageFormat(*this); 428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 42927f654740f2a26ad62a5c155af9199af9e69b889claireho 430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Sets the locale of this MessageFormat object to theLocale. 43227f654740f2a26ad62a5c155af9199af9e69b889claireho 433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::setLocale(const Locale& theLocale) 435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (fLocale != theLocale) { 437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete defaultNumberFormat; 438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultNumberFormat = NULL; 439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete defaultDateFormat; 440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru defaultDateFormat = NULL; 441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fLocale = theLocale; 442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setLocaleIDs(fLocale.getName(), fLocale.getName()); 443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pluralProvider.reset(&fLocale); 44454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius ordinalProvider.reset(&fLocale); 445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 44727f654740f2a26ad62a5c155af9199af9e69b889claireho 448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Gets the locale of this MessageFormat object. 45027f654740f2a26ad62a5c155af9199af9e69b889claireho 451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst Locale& 452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::getLocale() const 453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fLocale; 455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 45827f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::applyPattern(const UnicodeString& newPattern, 459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& status) 460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError parseError; 462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru applyPattern(newPattern,parseError,status); 463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Applies the new pattern and returns an error if the pattern 468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// is not correct. 469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 47027f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::applyPattern(const UnicodeString& pattern, 471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UParseError& parseError, 472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& ec) 47327f654740f2a26ad62a5c155af9199af9e69b889claireho{ 474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(U_FAILURE(ec)) { 475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.parse(pattern, &parseError, ec); 478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cacheExplicitFormats(ec); 479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho resetPattern(); 482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 485b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::resetPattern() { 486b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.clear(); 487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(cachedFormatters); 488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters = NULL; 489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_close(customFormatArgStarts); 490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts = NULL; 491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypeCount = 0; 492b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts = FALSE; 493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid 496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMessageFormat::applyPattern(const UnicodeString& pattern, 497b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternApostropheMode aposMode, 498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UParseError* parseError, 499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) { 500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (aposMode != msgPattern.getApostropheMode()) { 501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.clearPatternAndSetApostropheMode(aposMode); 502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho applyPattern(pattern, *parseError, status); 504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 50727f654740f2a26ad62a5c155af9199af9e69b889claireho// Converts this MessageFormat instance to a pattern. 508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::toPattern(UnicodeString& appendTo) const { 511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((customFormatArgStarts != NULL && 0 != uhash_count(customFormatArgStarts)) || 512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 0 == msgPattern.countParts() 513b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.setToBogus(); 515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo.append(msgPattern.getPatternString()); 518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t MessageFormat::nextTopLevelArgStart(int32_t partIndex) const { 521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (partIndex != 0) { 522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex = msgPattern.getLimitPartIndex(partIndex); 523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (;;) { 525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternPartType type = msgPattern.getPartType(++partIndex); 526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_ARG_START) { 527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return partIndex; 52885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return -1; 53127f654740f2a26ad62a5c155af9199af9e69b889claireho } 532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 53427f654740f2a26ad62a5c155af9199af9e69b889claireho 535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::setArgStartFormat(int32_t argStart, 536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* formatter, 537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) { 538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete formatter; 540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters == NULL) { 542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters=uhash_open(uhash_hashLong, uhash_compareLong, 543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho equalFormatsForHash, &status); 544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete formatter; 546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 54727f654740f2a26ad62a5c155af9199af9e69b889claireho } 548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uhash_setValueDeleter(cachedFormatters, uprv_deleteUObject); 549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (formatter == NULL) { 551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatter = new DummyFormat(); 552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 553b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_iput(cachedFormatters, argStart, formatter, &status); 554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 55527f654740f2a26ad62a5c155af9199af9e69b889claireho 556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool MessageFormat::argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber) { 558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part = msgPattern.getPart(partIndex); 559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return part.getType() == UMSGPAT_PART_TYPE_ARG_NAME ? 560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.partSubstringMatches(part, argName) : 561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho part.getValue() == argNumber; // ARG_NUMBER 562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Sets a custom formatter for a MessagePattern ARG_START part index. 565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// "Custom" formatters are provided by the user via setFormat() or similar APIs. 566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::setCustomArgStartFormat(int32_t argStart, 567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* formatter, 568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) { 569b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setArgStartFormat(argStart, formatter, status); 570b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts == NULL) { 571b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts=uhash_open(uhash_hashLong, uhash_compareLong, 572b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho NULL, &status); 573b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 574b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_iputi(customFormatArgStarts, argStart, 1, &status); 575b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 576b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 577b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoFormat* MessageFormat::getCachedFormatter(int32_t argumentNumber) const { 578b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters == NULL) { 579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 581b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho void* ptr = uhash_iget(cachedFormatters, argumentNumber); 582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (ptr != NULL && dynamic_cast<DummyFormat*>((Format*)ptr) == NULL) { 583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return (Format*) ptr; 584b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 585b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Not cached, or a DummyFormat representing setFormat(NULL). 586b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 587ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 588ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 58927f654740f2a26ad62a5c155af9199af9e69b889claireho 590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Adopts the new formats array and updates the array count. 592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This MessageFormat instance owns the new formats. 593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 594ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::adoptFormats(Format** newFormats, 595ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t count) { 596ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (newFormats == NULL || count < 0) { 597ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 598ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 599b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Throw away any cached formatters. 600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters != NULL) { 601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(cachedFormatters); 602b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts != NULL) { 604b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(customFormatArgStarts); 605b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 60627f654740f2a26ad62a5c155af9199af9e69b889claireho 607b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t formatNumber = 0; 608b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; 610b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatNumber < count && U_SUCCESS(status) && 611b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, newFormats[formatNumber], status); 613b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++formatNumber; 614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Delete those that didn't get used (if any). 616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (; formatNumber < count; ++formatNumber) { 617b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete newFormats[formatNumber]; 618ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 619ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 62027f654740f2a26ad62a5c155af9199af9e69b889claireho} 621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 622ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 623ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Sets the new formats array and updates the array count. 624ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// This MessageFormat instance maks a copy of the new formats. 62527f654740f2a26ad62a5c155af9199af9e69b889claireho 626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 627ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::setFormats(const Format** newFormats, 628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t count) { 629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (newFormats == NULL || count < 0) { 630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Throw away any cached formatters. 633b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters != NULL) { 634b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(cachedFormatters); 635b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts != NULL) { 637b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(customFormatArgStarts); 638ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 640b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t formatNumber = 0; 642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; 643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatNumber < count && U_SUCCESS(status) && (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 644b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* newFormat = NULL; 645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newFormats[formatNumber] != NULL) { 646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho newFormat = newFormats[formatNumber]->clone(); 647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newFormat == NULL) { 648b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 649b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 651b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, newFormat, status); 652b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++formatNumber; 653b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 654b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 655b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho resetPattern(); 656b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 65727f654740f2a26ad62a5c155af9199af9e69b889claireho} 65827f654740f2a26ad62a5c155af9199af9e69b889claireho 659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 66085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Adopt a single format by format number. 66185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Do nothing if the format number is not less than the array count. 66227f654740f2a26ad62a5c155af9199af9e69b889claireho 663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::adoptFormat(int32_t n, Format *newFormat) { 665b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<Format> p(newFormat); 666b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (n >= 0) { 667b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t formatNumber = 0; 668b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 669b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (n == formatNumber) { 670b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 671b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, p.orphan(), status); 672b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 673b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 674b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++formatNumber; 675b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 68085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Adopt a single format by format name. 68185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Do nothing if there is no match of formatName. 68285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid 68327f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::adoptFormat(const UnicodeString& formatName, 68485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho Format* formatToAdopt, 68585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode& status) { 686b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalPointer<Format> p(formatToAdopt); 687b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 688b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 689b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 690b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = MessagePattern::validateArgumentName(formatName); 691b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 692b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ILLEGAL_ARGUMENT_ERROR; 69385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 69485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 695b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; 696b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (partIndex = nextTopLevelArgStart(partIndex)) >= 0 && U_SUCCESS(status); 697b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 698b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNameMatches(partIndex + 1, formatName, argNumber)) { 699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* f; 700b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (p.isValid()) { 701b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho f = p.orphan(); 702b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (formatToAdopt == NULL) { 703b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho f = NULL; 70485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 705b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho f = formatToAdopt->clone(); 706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (f == NULL) { 707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 708b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 709b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 71085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 711b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, f, status); 71285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 71385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 71485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 71585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 71685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// ------------------------------------- 717ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Set a single format. 71885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Do nothing if the variable is not less than the array count. 719ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 720ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::setFormat(int32_t n, const Format& newFormat) { 721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (n >= 0) { 723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t formatNumber = 0; 724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; 725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (n == formatNumber) { 727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* new_format = newFormat.clone(); 728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (new_format) { 729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode status = U_ZERO_ERROR; 730b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, new_format, status); 731b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 732b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++formatNumber; 735ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 736ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 737ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 73885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 73985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// ------------------------------------- 74085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Get a single format by format name. 74185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Do nothing if the variable is not less than the array count. 74285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormat * 74385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::getFormat(const UnicodeString& formatName, UErrorCode& status) { 744b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status) || cachedFormatters == NULL) return NULL; 74585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = MessagePattern::validateArgumentName(formatName); 747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ILLEGAL_ARGUMENT_ERROR; 749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 75085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNameMatches(partIndex + 1, formatName, argNumber)) { 753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return getCachedFormatter(partIndex); 75485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 75585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 75685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 75785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 75885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 75985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// ------------------------------------- 76085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Set a single format by format name 76185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho// Do nothing if the variable is not less than the array count. 76285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid 76385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::setFormat(const UnicodeString& formatName, 76485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const Format& newFormat, 76585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode& status) { 766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) return; 767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = MessagePattern::validateArgumentName(formatName); 769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ILLEGAL_ARGUMENT_ERROR; 77185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return; 77285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 773b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; 774b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (partIndex = nextTopLevelArgStart(partIndex)) >= 0 && U_SUCCESS(status); 775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNameMatches(partIndex + 1, formatName, argNumber)) { 77785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (&newFormat == NULL) { 778b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, NULL, status); 77985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else { 780b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* new_format = newFormat.clone(); 781b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (new_format == NULL) { 782b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 783b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 784b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 785b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setCustomArgStartFormat(partIndex, new_format, status); 78685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 78785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 78885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 78985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 79085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 791ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 792ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Gets the format array. 793ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst Format** 794ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::getFormats(int32_t& cnt) const 795ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 796ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // This old API returns an array (which we hold) of Format* 797ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // pointers. The array is valid up to the next call to any 798ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // method on this object. We construct and resize an array 799ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // on demand that contains aliases to the subformats[i].format 800ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // pointers. 801b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MessageFormat* t = const_cast<MessageFormat*> (this); 802ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru cnt = 0; 803ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (formatAliases == NULL) { 804b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho t->formatAliasesCapacity = (argTypeCount<10) ? 10 : argTypeCount; 805ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Format** a = (Format**) 806ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_malloc(sizeof(Format*) * formatAliasesCapacity); 807ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (a == NULL) { 808b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho t->formatAliasesCapacity = 0; 809ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 810ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 81127f654740f2a26ad62a5c155af9199af9e69b889claireho t->formatAliases = a; 812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (argTypeCount > formatAliasesCapacity) { 813ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Format** a = (Format**) 814b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_realloc(formatAliases, sizeof(Format*) * argTypeCount); 815ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (a == NULL) { 816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho t->formatAliasesCapacity = 0; 817ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 818ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 819ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t->formatAliases = a; 820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho t->formatAliasesCapacity = argTypeCount; 821ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho t->formatAliases[cnt++] = getCachedFormatter(partIndex); 825ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 827ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (const Format**)formatAliases; 828ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 82927f654740f2a26ad62a5c155af9199af9e69b889claireho 83085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 831b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString MessageFormat::getArgName(int32_t partIndex) { 832b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part = msgPattern.getPart(partIndex); 833b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (part.getType() == UMSGPAT_PART_TYPE_ARG_NAME) { 834b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgPattern.getSubstring(part); 835b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 836b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString temp; 837b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return itos(part.getValue(), temp); 838b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 839b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 840b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 84185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoStringEnumeration* 84285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::getFormatNames(UErrorCode& status) { 84385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) return NULL; 84427f654740f2a26ad62a5c155af9199af9e69b889claireho 84585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UVector *fFormatNames = new UVector(status); 84685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_FAILURE(status)) { 84785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho status = U_MEMORY_ALLOCATION_ERROR; 84885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 84985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 850103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fFormatNames->setDeleter(uprv_deleteUObject); 851b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 852b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 85354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius fFormatNames->addElement(new UnicodeString(getArgName(partIndex + 1)), status); 85485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 85585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 85685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho StringEnumeration* nameEnumerator = new FormatNameEnumeration(fFormatNames, status); 85785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return nameEnumerator; 85885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 85985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 860ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 861ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Formats the source Formattable array and copy into the result buffer. 862ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Ignore the FieldPosition result for error checking. 86327f654740f2a26ad62a5c155af9199af9e69b889claireho 864ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 865ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::format(const Formattable* source, 86627f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t cnt, 86727f654740f2a26ad62a5c155af9199af9e69b889claireho UnicodeString& appendTo, 86827f654740f2a26ad62a5c155af9199af9e69b889claireho FieldPosition& ignore, 869ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) const 870ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 871b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return format(source, NULL, cnt, appendTo, &ignore, success); 872ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 87327f654740f2a26ad62a5c155af9199af9e69b889claireho 874ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 875ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Internally creates a MessageFormat instance based on the 87627f654740f2a26ad62a5c155af9199af9e69b889claireho// pattern and formats the arguments Formattable array and 877ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// copy into the appendTo buffer. 87827f654740f2a26ad62a5c155af9199af9e69b889claireho 879ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 880ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::format( const UnicodeString& pattern, 881ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Formattable* arguments, 882ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt, 88327f654740f2a26ad62a5c155af9199af9e69b889claireho UnicodeString& appendTo, 884ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) 885ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 886ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MessageFormat temp(pattern, success); 887b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return temp.format(arguments, NULL, cnt, appendTo, NULL, success); 888ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 88927f654740f2a26ad62a5c155af9199af9e69b889claireho 890ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 89127f654740f2a26ad62a5c155af9199af9e69b889claireho// Formats the source Formattable object and copy into the 892ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// appendTo buffer. The Formattable object must be an array 893ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// of Formattable instances, returns error otherwise. 89427f654740f2a26ad62a5c155af9199af9e69b889claireho 895ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 89627f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::format(const Formattable& source, 89727f654740f2a26ad62a5c155af9199af9e69b889claireho UnicodeString& appendTo, 89827f654740f2a26ad62a5c155af9199af9e69b889claireho FieldPosition& ignore, 899ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) const 900ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 90127f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(success)) 902ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 903ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (source.getType() != Formattable::kArray) { 904ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = U_ILLEGAL_ARGUMENT_ERROR; 905ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 906ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 907b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cnt; 908ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const Formattable* tmpPtr = source.getArray(cnt); 909b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return format(tmpPtr, NULL, cnt, appendTo, &ignore, success); 910ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 91185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 91285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString& 91385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::format(const UnicodeString* argumentNames, 91485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const Formattable* arguments, 91585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho int32_t count, 91685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UnicodeString& appendTo, 91785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode& success) const { 918b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return format(arguments, argumentNames, count, appendTo, NULL, success); 91985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 92085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 921b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Does linear search to find the match for an ArgName. 922b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoconst Formattable* MessageFormat::getArgFromListByName(const Formattable* arguments, 923b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *argumentNames, 924b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cnt, UnicodeString& name) const { 925b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < cnt; ++i) { 926b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (0 == argumentNames[i].compare(name)) { 927b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return arguments + i; 928b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 930b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 93185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 93285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 933ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 934ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUnicodeString& 93585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::format(const Formattable* arguments, 93685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho const UnicodeString *argumentNames, 93727f654740f2a26ad62a5c155af9199af9e69b889claireho int32_t cnt, 93827f654740f2a26ad62a5c155af9199af9e69b889claireho UnicodeString& appendTo, 939b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition* pos, 940b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) const { 941b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 942ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return appendTo; 943ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 94427f654740f2a26ad62a5c155af9199af9e69b889claireho 945b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeStringAppendable usapp(appendTo); 946b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho AppendableWrapper app(usapp); 947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho format(0, 0.0, arguments, argumentNames, cnt, app, pos, status); 948b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 949b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 950b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 951b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// if argumentNames is NULL, this means arguments is a numeric array. 952b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// arguments can not be NULL. 953b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::format(int32_t msgStart, double pluralNumber, 954b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Formattable* arguments, 955b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *argumentNames, 956b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cnt, 957b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho AppendableWrapper& appendTo, 958b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition* ignore, 959b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& success) const { 960b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(success)) { 961b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 96285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 96327f654740f2a26ad62a5c155af9199af9e69b889claireho 964b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& msgString = msgPattern.getPatternString(); 965b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevIndex = msgPattern.getPart(msgStart).getLimit(); 966b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = msgStart + 1; U_SUCCESS(success) ; ++i) { 967b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part* part = &msgPattern.getPart(i); 968b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UMessagePatternPartType type = part->getType(); 969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index = part->getIndex(); 970b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(msgString, prevIndex, index - prevIndex); 971b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 972b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 97385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = part->getLimit(); 975b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) { 976b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const NumberFormat* nf = getDefaultNumberFormat(success); 977b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.formatAndAppend(nf, Formattable(pluralNumber), success); 978b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 979b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 980b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type != UMSGPAT_PART_TYPE_ARG_START) { 981b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 982b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 983b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argLimit = msgPattern.getLimitPartIndex(i); 984b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternArgType argType = part->getArgType(); 985b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho part = &msgPattern.getPart(++i); 986b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Formattable* arg; 987b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString noArg; 988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argumentNames == NULL) { 989b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = part->getValue(); // ARG_NUMBER 990b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (0 <= argNumber && argNumber < cnt) { 991b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho arg = arguments + argNumber; 992b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 993b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho arg = NULL; 994b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho noArg.append(LEFT_CURLY_BRACE); 995b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho itos(argNumber, noArg); 996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho noArg.append(RIGHT_CURLY_BRACE); 99785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 998b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 999b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString key; 1000b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (part->getType() == UMSGPAT_PART_TYPE_ARG_NAME) { 1001b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho key = msgPattern.getSubstring(*part); 1002b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else /* UMSGPAT_PART_TYPE_ARG_NUMBER */ { 1003b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho itos(part->getValue(), key); 1004b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1005b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho arg = getArgFromListByName(arguments, argumentNames, cnt, key); 1006b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (arg == NULL) { 1007b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho noArg.append(LEFT_CURLY_BRACE); 1008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho noArg.append(key); 1009b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho noArg.append(RIGHT_CURLY_BRACE); 101085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1011ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1012b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++i; 1013b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevDestLength = appendTo.length(); 1014b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Format* formatter = NULL; 1015b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!noArg.isEmpty()) { 1016b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(noArg); 1017b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (arg == NULL) { 1018b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(NULL_STRING, 4); 1019b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if ((formatter = getCachedFormatter(i -2))) { 1020b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Handles all ArgType.SIMPLE, and formatters from setFormat() and its siblings. 1021b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (dynamic_cast<const ChoiceFormat*>(formatter) || 1022b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho dynamic_cast<const PluralFormat*>(formatter) || 1023b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho dynamic_cast<const SelectFormat*>(formatter)) { 1024b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We only handle nested formats here if they were provided via 1025b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // setFormat() or its siblings. Otherwise they are not cached and instead 1026b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // handled below according to argType. 1027b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString subMsgString; 1028b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatter->format(*arg, subMsgString, success); 1029b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (subMsgString.indexOf(LEFT_CURLY_BRACE) >= 0 || 1030b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho (subMsgString.indexOf(SINGLE_QUOTE) >= 0 && !MessageImpl::jdkAposMode(msgPattern)) 1031b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ) { 1032b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MessageFormat subMsgFormat(subMsgString, fLocale, success); 1033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho subMsgFormat.format(0, 0, arguments, argumentNames, cnt, appendTo, ignore, success); 1034b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1035b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(subMsgString); 1036ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1037b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1038b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.formatAndAppend(formatter, *arg, success); 1039ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1040b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (argType == UMSGPAT_ARG_TYPE_NONE || (cachedFormatters && uhash_iget(cachedFormatters, i - 2))) { 1041b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We arrive here if getCachedFormatter returned NULL, but there was actually an element in the hash table. 1042b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This can only happen if the hash table contained a DummyFormat, so the if statement above is a check 1043b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // for the hash table containind DummyFormat. 1044b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (arg->isNumeric()) { 1045b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const NumberFormat* nf = getDefaultNumberFormat(success); 1046b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.formatAndAppend(nf, *arg, success); 1047b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (arg->getType() == Formattable::kDate) { 1048b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const DateFormat* df = getDefaultDateFormat(success); 1049b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.formatAndAppend(df, *arg, success); 1050b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1051b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(arg->getString(success)); 1052b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1053b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (argType == UMSGPAT_ARG_TYPE_CHOICE) { 1054b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!arg->isNumeric()) { 1055b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho success = U_ILLEGAL_ARGUMENT_ERROR; 1056b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1057ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1058b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We must use the Formattable::getDouble() variant with the UErrorCode parameter 1059b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // because only this one converts non-double numeric types to double. 1060b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const double number = arg->getDouble(success); 1061b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t subMsgStart = ChoiceFormat::findSubMessage(msgPattern, i, number); 1062b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatComplexSubMessage(subMsgStart, 0, arguments, argumentNames, 1063b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt, appendTo, success); 106454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else if (UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType)) { 1065b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!arg->isNumeric()) { 1066b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho success = U_ILLEGAL_ARGUMENT_ERROR; 1067b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1068b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 106954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const PluralFormat::PluralSelector &selector = 107054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius argType == UMSGPAT_ARG_TYPE_PLURAL ? pluralProvider : ordinalProvider; 1071b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We must use the Formattable::getDouble() variant with the UErrorCode parameter 1072b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // because only this one converts non-double numeric types to double. 1073b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double number = arg->getDouble(success); 107454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t subMsgStart = PluralFormat::findSubMessage(msgPattern, i, selector, number, 1075b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho success); 1076b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double offset = msgPattern.getPluralOffset(i); 1077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatComplexSubMessage(subMsgStart, number-offset, arguments, argumentNames, 1078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt, appendTo, success); 1079b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (argType == UMSGPAT_ARG_TYPE_SELECT) { 1080b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t subMsgStart = SelectFormat::findSubMessage(msgPattern, i, arg->getString(success), success); 1081b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatComplexSubMessage(subMsgStart, 0, arguments, argumentNames, 1082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cnt, appendTo, success); 1083b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1084b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This should never happen. 1085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho success = U_INTERNAL_PROGRAM_ERROR; 1086b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1087ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1088b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ignore = updateMetaData(appendTo, prevDestLength, ignore, arg); 1089b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = msgPattern.getPart(argLimit).getLimit(); 1090b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho i = argLimit; 1091b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1092b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1093ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1094b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1095b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::formatComplexSubMessage(int32_t msgStart, 1096b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double pluralNumber, 1097b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Formattable* arguments, 1098b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString *argumentNames, 1099b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t cnt, 1100b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho AppendableWrapper& appendTo, 1101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& success) const { 1102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(success)) { 1103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!MessageImpl::jdkAposMode(msgPattern)) { 1107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho format(msgStart, pluralNumber, arguments, argumentNames, cnt, appendTo, NULL, success); 1108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // JDK compatibility mode: (see JDK MessageFormat.format() API docs) 1112b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // - remove SKIP_SYNTAX; that is, remove half of the apostrophes 1113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // - if the result string contains an open curly brace '{' then 1114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // instantiate a temporary MessageFormat object and format again; 1115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // otherwise just append the result string 1116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& msgString = msgPattern.getPatternString(); 1117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString sb; 1118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevIndex = msgPattern.getPart(msgStart).getLimit(); 1119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = msgStart;;) { 1120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part = msgPattern.getPart(++i); 1121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UMessagePatternPartType type = part.getType(); 1122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index = part.getIndex(); 1123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 1124b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sb.append(msgString, prevIndex, index - prevIndex); 1125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER || type == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { 1127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sb.append(msgString, prevIndex, index - prevIndex); 1128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) { 1129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const NumberFormat* nf = getDefaultNumberFormat(success); 1130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sb.append(nf->format(pluralNumber, sb, success)); 1131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = part.getLimit(); 1133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if (type == UMSGPAT_PART_TYPE_ARG_START) { 1134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sb.append(msgString, prevIndex, index - prevIndex); 1135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = index; 1136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho i = msgPattern.getLimitPartIndex(i); 1137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho index = msgPattern.getPart(i).getLimit(); 1138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MessageImpl::appendReducedApostrophes(msgString, prevIndex, index, sb); 1139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex = index; 1140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (sb.indexOf(LEFT_CURLY_BRACE) >= 0) { 1143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString emptyPattern; // gcc 3.3.3 fails with "UnicodeString()" as the first parameter. 1144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MessageFormat subMsgFormat(emptyPattern, fLocale, success); 1145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho subMsgFormat.applyPattern(sb, UMSGPAT_APOS_DOUBLE_REQUIRED, NULL, success); 1146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho subMsgFormat.format(0, 0, arguments, argumentNames, cnt, appendTo, NULL, success); 1147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(sb); 1149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1151b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1153b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString MessageFormat::getLiteralStringUntilNextArgument(int32_t from) const { 1154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& msgString=msgPattern.getPatternString(); 1155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevIndex=msgPattern.getPart(from).getLimit(); 1156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString b; 1157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = from + 1; ; ++i) { 1158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part = msgPattern.getPart(i); 1159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UMessagePatternPartType type=part.getType(); 1160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index=part.getIndex(); 1161b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho b.append(msgString, prevIndex, index - prevIndex); 1162b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(type==UMSGPAT_PART_TYPE_ARG_START || type==UMSGPAT_PART_TYPE_MSG_LIMIT) { 1163b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return b; 1164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Unexpected Part "part" in parsed message. 1166b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(type==UMSGPAT_PART_TYPE_SKIP_SYNTAX || type==UMSGPAT_PART_TYPE_INSERT_CHAR); 1167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex=part.getLimit(); 1168b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1169b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1171b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoFieldPosition* MessageFormat::updateMetaData(AppendableWrapper& /*dest*/, int32_t /*prevLength*/, 1173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition* /*fp*/, const Formattable* /*argId*/) const { 1174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Unlike in Java, there are no field attributes defined for MessageFormat. Do nothing. 1175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho /* 1177b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (fp != NULL && Field.ARGUMENT.equals(fp.getFieldAttribute())) { 1178b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fp->setBeginIndex(prevLength); 1179b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fp->setEndIndex(dest.get_length()); 1180b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1181b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fp; 1183b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho */ 1184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1185b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::copyObjects(const MessageFormat& that, UErrorCode& ec) { 1187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Deep copy pointer fields. 1188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We need not copy the formatAliases because they are re-filled 1189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // in each getFormats() call. 1190b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // The defaultNumberFormat, defaultDateFormat and pluralProvider.rules 1191b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // also get created on demand. 1192b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypeCount = that.argTypeCount; 1193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argTypeCount > 0) { 1194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!allocateArgTypes(argTypeCount, ec)) { 1195b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1196b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1197b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uprv_memcpy(argTypes, that.argTypes, argTypeCount * sizeof(argTypes[0])); 1198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters != NULL) { 1200b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(cachedFormatters); 1201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1202b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts != NULL) { 1203b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(customFormatArgStarts); 1204b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (that.cachedFormatters) { 1206b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters == NULL) { 1207b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho cachedFormatters=uhash_open(uhash_hashLong, uhash_compareLong, 1208b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho equalFormatsForHash, &ec); 1209b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 1210b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uhash_setValueDeleter(cachedFormatters, uprv_deleteUObject); 1213ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t count = uhash_count(that.cachedFormatters); 1216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t pos, idx; 1217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (idx = 0, pos = -1; idx < count && U_SUCCESS(ec); ++idx) { 1218b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashElement* cur = uhash_nextElement(that.cachedFormatters, &pos); 1219b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* newFormat = ((Format*)(cur->value.pointer))->clone(); 1220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (newFormat) { 1221b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_iput(cachedFormatters, cur->key.integer, newFormat, &ec); 1222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ec = U_MEMORY_ALLOCATION_ERROR; 1224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (that.customFormatArgStarts) { 1229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts == NULL) { 1230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho customFormatArgStarts=uhash_open(uhash_hashLong, uhash_compareLong, 1231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho NULL, &ec); 1232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int32_t count = uhash_count(that.customFormatArgStarts); 1234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t pos, idx; 1235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (idx = 0, pos = -1; idx < count && U_SUCCESS(ec); ++idx) { 1236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UHashElement* cur = uhash_nextElement(that.customFormatArgStarts, &pos); 1237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_iputi(customFormatArgStarts, cur->key.integer, cur->value.integer, &ec); 1238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormattable* 1244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMessageFormat::parse(int32_t msgStart, 1245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& source, 1246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition& pos, 1247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t& count, 1248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& ec) const { 1249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count = 0; 1250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 1251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(pos.getIndex()); 1252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // parse() does not work with named arguments. 1255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (msgPattern.hasNamedArguments()) { 1256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ec = U_ARGUMENT_TYPE_MISMATCH; 1257b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(pos.getIndex()); 1258b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1259b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1260b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho LocalArray<Formattable> resultArray(new Formattable[argTypeCount ? argTypeCount : 1]); 1261b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& msgString=msgPattern.getPatternString(); 1262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t prevIndex=msgPattern.getPart(msgStart).getLimit(); 1263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t sourceOffset = pos.getIndex(); 1264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ParsePosition tempStatus(0); 1265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1266b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for(int32_t i=msgStart+1; ; ++i) { 1267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UBool haveArgResult = FALSE; 1268b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part* part=&msgPattern.getPart(i); 1269b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UMessagePatternPartType type=part->getType(); 1270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index=part->getIndex(); 1271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Make sure the literal string matches. 1272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = index - prevIndex; 1273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (len == 0 || (0 == msgString.compare(prevIndex, len, source, sourceOffset, len))) { 1274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceOffset += len; 1275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex += len; 1276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(sourceOffset); 1278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; // leave index as is to signal error 127927f654740f2a26ad62a5c155af9199af9e69b889claireho } 1280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(type==UMSGPAT_PART_TYPE_MSG_LIMIT) { 1281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Things went well! Done. 1282b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setIndex(sourceOffset); 1283b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return resultArray.orphan(); 1284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(type==UMSGPAT_PART_TYPE_SKIP_SYNTAX || type==UMSGPAT_PART_TYPE_INSERT_CHAR) { 1286b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex=part->getLimit(); 1287b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 1288b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We do not support parsing Plural formats. (No REPLACE_NUMBER here.) 1290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Unexpected Part "part" in parsed message. 1291b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho U_ASSERT(type==UMSGPAT_PART_TYPE_ARG_START); 1292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argLimit=msgPattern.getLimitPartIndex(i); 1293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternArgType argType=part->getArgType(); 1295b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho part=&msgPattern.getPart(++i); 1296b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = part->getValue(); // ARG_NUMBER 1297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString key; 1298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++i; 1299b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const Format* formatter = NULL; 1300b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable& argResult = resultArray[argNumber]; 1301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1302b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(cachedFormatters!=NULL && (formatter = getCachedFormatter(i - 2))!=NULL) { 1303b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Just parse using the formatter. 1304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tempStatus.setIndex(sourceOffset); 1305b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formatter->parseObject(source, argResult, tempStatus); 1306b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tempStatus.getIndex() == sourceOffset) { 1307b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(sourceOffset); 1308b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; // leave index as is to signal error 1309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sourceOffset = tempStatus.getIndex(); 1311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho haveArgResult = TRUE; 1312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if( 1313b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argType==UMSGPAT_ARG_TYPE_NONE || (cachedFormatters && uhash_iget(cachedFormatters, i -2))) { 1314b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We arrive here if getCachedFormatter returned NULL, but there was actually an element in the hash table. 1315b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This can only happen if the hash table contained a DummyFormat, so the if statement above is a check 1316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // for the hash table containind DummyFormat. 1317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Match as a string. 1319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // if at end, use longest possible match 1320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // otherwise uses first match to intervening string 1321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // does NOT recursively try all possibilities 1322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString stringAfterArgument = getLiteralStringUntilNextArgument(argLimit); 1323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t next; 1324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!stringAfterArgument.isEmpty()) { 1325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho next = source.indexOf(stringAfterArgument, sourceOffset); 1326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1327ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru next = source.length(); 1328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (next < 0) { 1330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(sourceOffset); 1331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; // leave index as is to signal error 1332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString strValue(source.tempSubString(sourceOffset, next - sourceOffset)); 1334b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString compValue; 1335b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho compValue.append(LEFT_CURLY_BRACE); 1336b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho itos(argNumber, compValue); 1337b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho compValue.append(RIGHT_CURLY_BRACE); 1338b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (0 != strValue.compare(compValue)) { 1339b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argResult.setString(strValue); 1340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho haveArgResult = TRUE; 1341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru sourceOffset = next; 1343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(argType==UMSGPAT_ARG_TYPE_CHOICE) { 1345b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho tempStatus.setIndex(sourceOffset); 1346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho double choiceResult = ChoiceFormat::parseArgument(msgPattern, i, source, tempStatus); 1347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (tempStatus.getIndex() == sourceOffset) { 1348b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho pos.setErrorIndex(sourceOffset); 1349b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; // leave index as is to signal error 1350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argResult.setDouble(choiceResult); 1352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho haveArgResult = TRUE; 1353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sourceOffset = tempStatus.getIndex(); 135454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else if(UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) || argType==UMSGPAT_ARG_TYPE_SELECT) { 1355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Parsing not supported. 1356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ec = U_UNSUPPORTED_ERROR; 1357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This should never happen. 1360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ec = U_INTERNAL_PROGRAM_ERROR; 1361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (haveArgResult && count <= argNumber) { 1364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho count = argNumber + 1; 1365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho prevIndex=msgPattern.getPart(argLimit).getLimit(); 1367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho i=argLimit; 1368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// ------------------------------------- 1371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// Parses the source pattern and returns the Formattable objects array, 1372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// the array count and the ending parse position. The caller of this method 1373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho// owns the array. 1374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoFormattable* 1376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMessageFormat::parse(const UnicodeString& source, 1377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ParsePosition& pos, 1378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t& count) const { 1379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode ec = U_ZERO_ERROR; 1380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return parse(0, source, pos, count, ec); 1381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 138227f654740f2a26ad62a5c155af9199af9e69b889claireho 1383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 138427f654740f2a26ad62a5c155af9199af9e69b889claireho// Parses the source string and returns the array of 138527f654740f2a26ad62a5c155af9199af9e69b889claireho// Formattable objects and the array count. The caller 1386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// owns the returned array. 138727f654740f2a26ad62a5c155af9199af9e69b889claireho 1388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruFormattable* 138927f654740f2a26ad62a5c155af9199af9e69b889clairehoMessageFormat::parse(const UnicodeString& source, 1390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t& cnt, 1391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UErrorCode& success) const 1392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (msgPattern.hasNamedArguments()) { 139485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho success = U_ARGUMENT_TYPE_MISMATCH; 139527f654740f2a26ad62a5c155af9199af9e69b889claireho return NULL; 139685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition status(0); 1398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Calls the actual implementation method and starts 1399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // from zero offset of the source text. 1400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable* result = parse(source, status, cnt); 1401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (status.getIndex() == 0) { 1402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru success = U_MESSAGE_PARSE_ERROR; 1403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete[] result; 1404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 1405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return result; 1407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 140827f654740f2a26ad62a5c155af9199af9e69b889claireho 1409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 1410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// Parses the source text and copy into the result buffer. 141127f654740f2a26ad62a5c155af9199af9e69b889claireho 1412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid 1413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::parseObject( const UnicodeString& source, 1414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable& result, 1415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ParsePosition& status) const 1416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru int32_t cnt = 0; 1418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru Formattable* tmpResult = parse(source, status, cnt); 141927f654740f2a26ad62a5c155af9199af9e69b889claireho if (tmpResult != NULL) 1420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru result.adoptArray(tmpResult, cnt); 1421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 142227f654740f2a26ad62a5c155af9199af9e69b889claireho 142327f654740f2a26ad62a5c155af9199af9e69b889clairehoUnicodeString 1424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::autoQuoteApostrophe(const UnicodeString& pattern, UErrorCode& status) { 1425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString result; 1426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t plen = pattern.length(); 1428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar* pat = pattern.getBuffer(); 1429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t blen = plen * 2 + 1; // space for null termination, convenience 1430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UChar* buf = result.getBuffer(blen); 1431b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (buf == NULL) { 1432b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_MEMORY_ALLOCATION_ERROR; 1433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 1434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t len = umsg_autoQuoteApostrophe(pat, plen, buf, blen, &status); 1435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.releaseBuffer(U_SUCCESS(status) ? len : 0); 1436b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1437b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho result.setToBogus(); 1440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return result; 1442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// ------------------------------------- 1445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const UnicodeString& defaultRuleSet, UErrorCode& ec) { 1447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru RuleBasedNumberFormat* fmt = new RuleBasedNumberFormat(tag, locale, ec); 144885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (fmt == NULL) { 144985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho ec = U_MEMORY_ALLOCATION_ERROR; 145085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } else if (U_SUCCESS(ec) && defaultRuleSet.length() > 0) { 145185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho UErrorCode localStatus = U_ZERO_ERROR; // ignore unrecognized default rule set 145285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fmt->setDefaultRuleSet(defaultRuleSet, localStatus); 1453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return fmt; 1455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 145627f654740f2a26ad62a5c155af9199af9e69b889claireho 1457b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::cacheExplicitFormats(UErrorCode& status) { 1458b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 1459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return; 1460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1462b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (cachedFormatters != NULL) { 1463b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(cachedFormatters); 146485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1465b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (customFormatArgStarts != NULL) { 1466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uhash_removeAll(customFormatArgStarts); 1467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1468b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1469b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // The last two "parts" can at most be ARG_LIMIT and MSG_LIMIT 1470b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // which we need not examine. 1471b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t limit = msgPattern.countParts() - 2; 1472b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypeCount = 0; 1473b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We also need not look at the first two "parts" 1474b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // (at most MSG_START and ARG_START) in this loop. 1475b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We determine the argTypeCount first so that we can allocateArgTypes 1476b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // so that the next loop can set argTypes[argNumber]. 1477b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // (This is for the C API which needs the argTypes to read its va_arg list.) 1478b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 2; i < limit && U_SUCCESS(status); ++i) { 1479b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part = msgPattern.getPart(i); 1480b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (part.getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) { 1481b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const int argNumber = part.getValue(); 1482b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNumber >= argTypeCount) { 1483b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypeCount = argNumber + 1; 1484b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 148585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1487b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!allocateArgTypes(argTypeCount, status)) { 1488b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return; 1489b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1490b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Set all argTypes to kObject, as a "none" value, for lack of any better value. 1491b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We never use kObject for real arguments. 149254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // We use it as "no argument yet" for the check for hasArgTypeConflicts. 1493b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 0; i < argTypeCount; ++i) { 1494b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypes[i] = Formattable::kObject; 1495b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1496b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts = FALSE; 1497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // This loop starts at part index 1 because we do need to examine 1499b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // ARG_START parts. (But we can ignore the MSG_START.) 1500b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho for (int32_t i = 1; i < limit && U_SUCCESS(status); ++i) { 1501b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part* part = &msgPattern.getPart(i); 1502b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (part->getType() != UMSGPAT_PART_TYPE_ARG_START) { 1503b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho continue; 1504b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1505b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UMessagePatternArgType argType = part->getArgType(); 1506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1507b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t argNumber = -1; 1508b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho part = &msgPattern.getPart(i + 1); 1509b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (part->getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) { 1510b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argNumber = part->getValue(); 1511b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1512b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable::Type formattableType; 1513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1514b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (argType) { 1515b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UMSGPAT_ARG_TYPE_NONE: 1516b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kString; 1517b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1518b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UMSGPAT_ARG_TYPE_SIMPLE: { 1519b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t index = i; 1520b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho i += 2; 1521b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString explicitType = msgPattern.getSubstring(msgPattern.getPart(i++)); 1522b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString style; 1523b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if ((part = &msgPattern.getPart(i))->getType() == UMSGPAT_PART_TYPE_ARG_STYLE) { 1524b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho style = msgPattern.getSubstring(*part); 1525b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ++i; 1526b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1527b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UParseError parseError; 1528b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* formatter = createAppropriateFormat(explicitType, style, formattableType, parseError, status); 1529b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho setArgStartFormat(index, formatter, status); 1530b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1531b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1532b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UMSGPAT_ARG_TYPE_CHOICE: 1533b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UMSGPAT_ARG_TYPE_PLURAL: 153454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius case UMSGPAT_ARG_TYPE_SELECTORDINAL: 1535b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDouble; 1536b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1537b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case UMSGPAT_ARG_TYPE_SELECT: 1538b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kString; 1539b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1540b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho default: 1541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_INTERNAL_PROGRAM_ERROR; // Should be unreachable. 1542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kString; 1543b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1544b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1545b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argNumber != -1) { 1546b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (argTypes[argNumber] != Formattable::kObject && argTypes[argNumber] != formattableType) { 1547b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho hasArgTypeConflicts = TRUE; 1548b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho argTypes[argNumber] = formattableType; 1550b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1551b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1552b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1553ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1554ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1555b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoFormat* MessageFormat::createAppropriateFormat(UnicodeString& type, UnicodeString& style, 1556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable::Type& formattableType, UParseError& parseError, 1557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& ec) { 1558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 1559b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return NULL; 1560b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1561b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Format* fmt = NULL; 1562b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t typeID, styleID; 1563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho DateFormat::EStyle date_style; 1564b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (typeID = findKeyword(type, TYPE_IDS)) { 1566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 0: // number 1567b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDouble; 1568b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho switch (findKeyword(style, NUMBER_STYLE_IDS)) { 1569ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 0: // default 1570ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fmt = NumberFormat::createInstance(fLocale, ec); 1571ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1572ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 1: // currency 1573ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fmt = NumberFormat::createCurrencyInstance(fLocale, ec); 1574ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1575ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 2: // percent 1576ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fmt = NumberFormat::createPercentInstance(fLocale, ec); 1577ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1578ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru case 3: // integer 1579b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kLong; 1580ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fmt = createIntegerFormat(fLocale, ec); 1581ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1582ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: // pattern 1583ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru fmt = NumberFormat::createInstance(fLocale, ec); 158427f654740f2a26ad62a5c155af9199af9e69b889claireho if (fmt) { 158527f654740f2a26ad62a5c155af9199af9e69b889claireho DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fmt); 158627f654740f2a26ad62a5c155af9199af9e69b889claireho if (decfmt != NULL) { 1587b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho decfmt->applyPattern(style,parseError,ec); 158827f654740f2a26ad62a5c155af9199af9e69b889claireho } 1589ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1590ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1591ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1592ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1593ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 1: // date 1595b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 2: // time 1596b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDate; 1597b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho styleID = findKeyword(style, DATE_STYLE_IDS); 1598b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho date_style = (styleID >= 0) ? DATE_STYLES[styleID] : DateFormat::kDefault; 1599ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1600b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (typeID == 1) { 1601b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fmt = DateFormat::createDateInstance(date_style, fLocale); 1602ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 1603b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fmt = DateFormat::createTimeInstance(date_style, fLocale); 1604ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1605ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 160627f654740f2a26ad62a5c155af9199af9e69b889claireho if (styleID < 0 && fmt != NULL) { 160727f654740f2a26ad62a5c155af9199af9e69b889claireho SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(fmt); 160827f654740f2a26ad62a5c155af9199af9e69b889claireho if (sdtfmt != NULL) { 1609b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho sdtfmt->applyPattern(style); 161027f654740f2a26ad62a5c155af9199af9e69b889claireho } 1611ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1612ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1613ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1614b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 3: // spellout 1615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDouble; 1616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fmt = makeRBNF(URBNF_SPELLOUT, fLocale, style, ec); 1617ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1618b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 4: // ordinal 1619b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDouble; 1620b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fmt = makeRBNF(URBNF_ORDINAL, fLocale, style, ec); 1621ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1622b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho case 5: // duration 1623b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kDouble; 1624b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho fmt = makeRBNF(URBNF_DURATION, fLocale, style, ec); 162585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho break; 1626ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru default: 1627b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho formattableType = Formattable::kString; 1628ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 1629ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru break; 1630ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1631ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1632b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return fmt; 1633ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 163427f654740f2a26ad62a5c155af9199af9e69b889claireho 1635b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1636b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho//------------------------------------- 163727f654740f2a26ad62a5c155af9199af9e69b889claireho// Finds the string, s, in the string array, list. 163827f654740f2a26ad62a5c155af9199af9e69b889clairehoint32_t MessageFormat::findKeyword(const UnicodeString& s, 1639ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const UChar * const *list) 1640ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{ 1641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (s.isEmpty()) { 1642ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return 0; // default 1643b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1644ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1645b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t length = s.length(); 1646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UChar *ps = PatternProps::trimWhiteSpace(s.getBuffer(), length); 1647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString buffer(FALSE, ps, length); 1648ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // Trims the space characters and turns all characters 1649ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru // in s to lower case. 1650b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho buffer.toLower(""); 1651ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru for (int32_t i = 0; list[i]; ++i) { 1652ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (!buffer.compare(list[i], u_strlen(list[i]))) { 1653ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return i; 1654ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1655ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1656ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 1657ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 165827f654740f2a26ad62a5c155af9199af9e69b889claireho 1659ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1660ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Convenience method that ought to be in NumberFormat 1661ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 166227f654740f2a26ad62a5c155af9199af9e69b889clairehoNumberFormat* 1663ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruMessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) const { 1664ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru NumberFormat *temp = NumberFormat::createInstance(locale, status); 166527f654740f2a26ad62a5c155af9199af9e69b889claireho DecimalFormat *temp2; 166627f654740f2a26ad62a5c155af9199af9e69b889claireho if (temp != NULL && (temp2 = dynamic_cast<DecimalFormat*>(temp)) != NULL) { 1667ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru temp2->setMaximumFractionDigits(0); 1668ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru temp2->setDecimalSeparatorAlwaysShown(FALSE); 1669ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru temp2->setParseIntegerOnly(TRUE); 1670ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1671ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1672ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return temp; 1673ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1674ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1675ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1676ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return the default number format. Used to format a numeric 1677ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * argument when subformats[i].format is NULL. Returns NULL 1678ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * on failure. 1679ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1680ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Semantically const but may modify *this. 1681ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1682ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst NumberFormat* MessageFormat::getDefaultNumberFormat(UErrorCode& ec) const { 1683ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (defaultNumberFormat == NULL) { 1684ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MessageFormat* t = (MessageFormat*) this; 1685ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t->defaultNumberFormat = NumberFormat::createInstance(fLocale, ec); 168627f654740f2a26ad62a5c155af9199af9e69b889claireho if (U_FAILURE(ec)) { 1687ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru delete t->defaultNumberFormat; 1688ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t->defaultNumberFormat = NULL; 1689ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else if (t->defaultNumberFormat == NULL) { 1690ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_MEMORY_ALLOCATION_ERROR; 1691ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1692ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1693ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return defaultNumberFormat; 1694ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1695ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1696ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 1697ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Return the default date format. Used to format a date 1698ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * argument when subformats[i].format is NULL. Returns NULL 1699ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * on failure. 1700ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 1701ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Semantically const but may modify *this. 1702ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 1703ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst DateFormat* MessageFormat::getDefaultDateFormat(UErrorCode& ec) const { 1704ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (defaultDateFormat == NULL) { 1705ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru MessageFormat* t = (MessageFormat*) this; 1706ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru t->defaultDateFormat = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale); 1707ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (t->defaultDateFormat == NULL) { 1708ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ec = U_MEMORY_ALLOCATION_ERROR; 1709ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1710ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 1711ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return defaultDateFormat; 1712ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 1713ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 171485bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool 171585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoMessageFormat::usesNamedArguments() const { 1716b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgPattern.hasNamedArguments(); 171785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 171885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1719b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t 1720b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMessageFormat::getArgTypeCount() const { 1721b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return argTypeCount; 1722b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1723b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1724b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool MessageFormat::equalFormats(const void* left, const void* right) { 1725b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return *(const Format*)left==*(const Format*)right; 1726b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1727b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1728b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1729b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUBool MessageFormat::DummyFormat::operator==(const Format&) const { 173085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return TRUE; 173185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 173285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1733b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoFormat* MessageFormat::DummyFormat::clone() const { 1734b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return new DummyFormat(); 173527f654740f2a26ad62a5c155af9199af9e69b889claireho} 173685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 1737b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 1738b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString& appendTo, 173954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UErrorCode& status) const { 174054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (U_SUCCESS(status)) { 174154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius status = U_UNSUPPORTED_ERROR; 174254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 174354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return appendTo; 174454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 174554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 174654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 174754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UnicodeString& appendTo, 1748b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho FieldPosition&, 1749b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) const { 1750b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_SUCCESS(status)) { 1751b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_UNSUPPORTED_ERROR; 1752b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1753b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 1754b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1755b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 175654dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 175754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UnicodeString& appendTo, 175854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius FieldPositionIterator*, 175954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UErrorCode& status) const { 176054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (U_SUCCESS(status)) { 176154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius status = U_UNSUPPORTED_ERROR; 176254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 176354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return appendTo; 176454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 176554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 1766b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::DummyFormat::parseObject(const UnicodeString&, 1767b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho Formattable&, 1768b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho ParsePosition& ) const { 1769b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1770b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1771b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 177285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormatNameEnumeration::FormatNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) { 177385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos=0; 177485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho fFormatNames = fNameList; 177585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 177685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 177785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoconst UnicodeString* 177885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormatNameEnumeration::snext(UErrorCode& status) { 177985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho if (U_SUCCESS(status) && pos < fFormatNames->size()) { 178085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return (const UnicodeString*)fFormatNames->elementAt(pos++); 178185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 178285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho return NULL; 178385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 178485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 178585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid 178685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormatNameEnumeration::reset(UErrorCode& /*status*/) { 178785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho pos=0; 178885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 178985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 179085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hoint32_t 179185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormatNameEnumeration::count(UErrorCode& /*status*/) const { 1792b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return (fFormatNames==NULL) ? 0 : fFormatNames->size(); 179385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 179485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho 179585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormatNameEnumeration::~FormatNameEnumeration() { 1796b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete fFormatNames; 1797b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1798b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1799b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 180054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusMessageFormat::PluralSelectorProvider::PluralSelectorProvider(const Locale* loc, UPluralType t) 180154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius : locale(loc), rules(NULL), type(t) { 1802b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1803b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1804b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoMessageFormat::PluralSelectorProvider::~PluralSelectorProvider() { 1805b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // We own the rules but not the locale. 1806b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete rules; 1807b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1808b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1809b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString MessageFormat::PluralSelectorProvider::select(double number, UErrorCode& ec) const { 1810b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 1811b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return UnicodeString(FALSE, OTHER_STRING, 5); 1812b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1813b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho MessageFormat::PluralSelectorProvider* t = const_cast<MessageFormat::PluralSelectorProvider*>(this); 1814b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(rules == NULL) { 181554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius t->rules = PluralRules::forLocale(*locale, type, ec); 1816b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 1817b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return UnicodeString(FALSE, OTHER_STRING, 5); 181885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 181985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho } 1820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return rules->select(number); 182185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho} 1822b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1823b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid MessageFormat::PluralSelectorProvider::reset(const Locale* loc) { 1824b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho locale = loc; 1825b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho delete rules; 1826b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho rules = NULL; 1827b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1828b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1829b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1830ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_NAMESPACE_END 1831ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1832ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 1833ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 1834ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru//eof 1835