16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/******************************************************************** 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * COPYRIGHT: 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (c) 1997-2013, International Business Machines Corporation and 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************** 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * File MSGFMT.CPP 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Modification History: 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Date Name Description 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 02/19/97 aliu Converted from java. 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 03/20/97 helena Finished first cut of implementation. 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 04/10/97 aliu Made to work on AIX. Added stoi to replace wtoi. 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 06/11/97 helena Fixed addPattern to take the pattern correctly. 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 06/17/97 helena Fixed the getPattern to return the correct pattern. 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 07/09/97 helena Made ParsePosition into a class. 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 02/22/99 stephen Removed character literals for EBCDIC safety 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 11/01/09 kirtig Added SelectFormat 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************/ 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/appendable.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/choicfmt.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/datefmt.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/decimfmt.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/localpointer.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/msgfmt.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/plurfmt.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/rbnf.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/selfmt.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/smpdtfmt.h" 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/umsg.h" 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "patternprops.h" 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "messageimpl.h" 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "msgfmt_impl.h" 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "plurrule_impl.h" 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uelement.h" 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uhash.h" 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustrfmt.h" 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "util.h" 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h" 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ***************************************************************************** 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// class MessageFormat 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ***************************************************************************** 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define SINGLE_QUOTE ((UChar)0x0027) 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define COMMA ((UChar)0x002C) 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define LEFT_CURLY_BRACE ((UChar)0x007B) 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#define RIGHT_CURLY_BRACE ((UChar)0x007D) 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//--------------------------------------- 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// static data 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_NUMBER[] = { 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6E, 0x75, 0x6D, 0x62, 0x65, 0x72, 0 /* "number" */ 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_DATE[] = { 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x64, 0x61, 0x74, 0x65, 0 /* "date" */ 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_TIME[] = { 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x74, 0x69, 0x6D, 0x65, 0 /* "time" */ 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_SPELLOUT[] = { 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x73, 0x70, 0x65, 0x6c, 0x6c, 0x6f, 0x75, 0x74, 0 /* "spellout" */ 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_ORDINAL[] = { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x6c, 0 /* "ordinal" */ 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_DURATION[] = { 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0 /* "duration" */ 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// MessageFormat Type List Number, Date, Time or Choice 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar * const TYPE_IDS[] = { 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_NUMBER, 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_DATE, 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_TIME, 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_SPELLOUT, 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_ORDINAL, 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_DURATION, 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_EMPTY[] = { 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0 /* empty string, used for default so that null can mark end of list */ 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_CURRENCY[] = { 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x63, 0x75, 0x72, 0x72, 0x65, 0x6E, 0x63, 0x79, 0 /* "currency" */ 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_PERCENT[] = { 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x70, 0x65, 0x72, 0x63, 0x65, 0x6E, 0x74, 0 /* "percent" */ 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_INTEGER[] = { 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x69, 0x6E, 0x74, 0x65, 0x67, 0x65, 0x72, 0 /* "integer" */ 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// NumberFormat modifier list, default, currency, percent or integer 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar * const NUMBER_STYLE_IDS[] = { 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_EMPTY, 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_CURRENCY, 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_PERCENT, 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_INTEGER, 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_SHORT[] = { 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x73, 0x68, 0x6F, 0x72, 0x74, 0 /* "short" */ 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_MEDIUM[] = { 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6D, 0x65, 0x64, 0x69, 0x75, 0x6D, 0 /* "medium" */ 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_LONG[] = { 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6C, 0x6F, 0x6E, 0x67, 0 /* "long" */ 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar ID_FULL[] = { 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x66, 0x75, 0x6C, 0x6C, 0 /* "full" */ 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// DateFormat modifier list, default, short, medium, long or full 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar * const DATE_STYLE_IDS[] = { 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_EMPTY, 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_SHORT, 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_MEDIUM, 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_LONG, 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ID_FULL, 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const icu::DateFormat::EStyle DATE_STYLES[] = { 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::DateFormat::kDefault, 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::DateFormat::kShort, 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::DateFormat::kMedium, 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::DateFormat::kLong, 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org icu::DateFormat::kFull, 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const int32_t DEFAULT_INITIAL_CAPACITY = 10; 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar NULL_STRING[] = { 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6E, 0x75, 0x6C, 0x6C, 0 // "null" 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar OTHER_STRING[] = { 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0x6F, 0x74, 0x68, 0x65, 0x72, 0 // "other" 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_BEGIN 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UBool U_CALLCONV equalFormatsForHash(const UHashTok key1, 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UHashTok key2) { 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return icu::MessageFormat::equalFormats(key1.pointer, key2.pointer); 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CDECL_END 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(MessageFormat) 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(FormatNameEnumeration) 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//-------------------------------------------------------------------- 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Convert an integer value to a string and append the result to 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * the given UnicodeString. 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic UnicodeString& itos(int32_t i, UnicodeString& appendTo) { 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar temp[16]; 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_itou(temp,16,i,10,0); // 10 == radix 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(temp, -1); 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// AppendableWrapper: encapsulates the result of formatting, keeping track 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// of the string and its length. 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass AppendableWrapper : public UMemory { 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AppendableWrapper(Appendable& appendable) : app(appendable), len(0) { 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void append(const UnicodeString& s) { 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org app.appendString(s.getBuffer(), s.length()); 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len += s.length(); 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void append(const UChar* s, const int32_t sLength) { 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org app.appendString(s, sLength); 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org len += sLength; 1966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void append(const UnicodeString& s, int32_t start, int32_t length) { 1986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org append(s.tempSubString(start, length)); 1996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void formatAndAppend(const Format* formatter, const Formattable& arg, UErrorCode& ec) { 2016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString s; 2026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatter->format(arg, s, ec); 2036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(ec)) { 2046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org append(s); 2056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void formatAndAppend(const Format* formatter, const Formattable& arg, 2086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString &argString, UErrorCode& ec) { 2096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!argString.isEmpty()) { 2106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(ec)) { 2116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org append(argString); 2126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 2146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAndAppend(formatter, arg, ec); 2156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length() { 2186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return len; 2196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 2206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgprivate: 2216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Appendable& app; 2226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len; 2236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 2246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 2276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a MessageFormat instance based on the pattern. 2286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::MessageFormat(const UnicodeString& pattern, 2306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) 2316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLocale(Locale::getDefault()), // Uses the default locale 2326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(success), 2336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliases(NULL), 2346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliasesCapacity(0), 2356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes(NULL), 2366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount(0), 2376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCapacity(0), 2386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts(FALSE), 2396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultNumberFormat(NULL), 2406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultDateFormat(NULL), 2416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters(NULL), 2426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts(NULL), 2436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralProvider(*this, UPLURAL_TYPE_CARDINAL), 2446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ordinalProvider(*this, UPLURAL_TYPE_ORDINAL) 2456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setLocaleIDs(fLocale.getName(), fLocale.getName()); 2476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(pattern, success); 2486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::MessageFormat(const UnicodeString& pattern, 2516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Locale& newLocale, 2526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) 2536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLocale(newLocale), 2546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(success), 2556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliases(NULL), 2566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliasesCapacity(0), 2576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes(NULL), 2586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount(0), 2596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCapacity(0), 2606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts(FALSE), 2616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultNumberFormat(NULL), 2626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultDateFormat(NULL), 2636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters(NULL), 2646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts(NULL), 2656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralProvider(*this, UPLURAL_TYPE_CARDINAL), 2666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ordinalProvider(*this, UPLURAL_TYPE_ORDINAL) 2676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setLocaleIDs(fLocale.getName(), fLocale.getName()); 2696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(pattern, success); 2706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::MessageFormat(const UnicodeString& pattern, 2736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Locale& newLocale, 2746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 2756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) 2766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: fLocale(newLocale), 2776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(success), 2786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliases(NULL), 2796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliasesCapacity(0), 2806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes(NULL), 2816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount(0), 2826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCapacity(0), 2836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts(FALSE), 2846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultNumberFormat(NULL), 2856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultDateFormat(NULL), 2866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters(NULL), 2876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts(NULL), 2886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralProvider(*this, UPLURAL_TYPE_CARDINAL), 2896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ordinalProvider(*this, UPLURAL_TYPE_ORDINAL) 2906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 2916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setLocaleIDs(fLocale.getName(), fLocale.getName()); 2926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(pattern, parseError, success); 2936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 2946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 2956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::MessageFormat(const MessageFormat& that) 2966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org: 2976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format(that), 2986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLocale(that.fLocale), 2996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(that.msgPattern), 3006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliases(NULL), 3016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatAliasesCapacity(0), 3026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes(NULL), 3036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount(0), 3046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCapacity(0), 3056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts(that.hasArgTypeConflicts), 3066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultNumberFormat(NULL), 3076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultDateFormat(NULL), 3086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters(NULL), 3096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts(NULL), 3106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralProvider(*this, UPLURAL_TYPE_CARDINAL), 3116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ordinalProvider(*this, UPLURAL_TYPE_ORDINAL) 3126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This will take care of creating the hash tables (since they are NULL). 3146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 3156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org copyObjects(that, ec); 3166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 3176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resetPattern(); 3186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::~MessageFormat() 3226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(cachedFormatters); 3246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(customFormatArgStarts); 3256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(argTypes); 3276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(formatAliases); 3286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete defaultNumberFormat; 3296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete defaultDateFormat; 3306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//-------------------------------------------------------------------- 3336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Variable-size array management 3346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 3366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Allocate argTypes[] to at least the given capacity and return 3376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * TRUE if successful. If not, leave argTypes[] unchanged. 3386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 3396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * If argTypes is NULL, allocate it. If it is not NULL, enlarge it 3406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * if necessary to be at least as large as specified. 3416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 3426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool MessageFormat::allocateArgTypes(int32_t capacity, UErrorCode& status) { 3436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 3446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 3456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argTypeCapacity >= capacity) { 3476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 3486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (capacity < DEFAULT_INITIAL_CAPACITY) { 3506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org capacity = DEFAULT_INITIAL_CAPACITY; 3516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (capacity < 2*argTypeCapacity) { 3526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org capacity = 2*argTypeCapacity; 3536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable::Type* a = (Formattable::Type*) 3556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_realloc(argTypes, sizeof(*argTypes) * capacity); 3566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (a == NULL) { 3576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 3586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 3596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes = a; 3616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCapacity = capacity; 3626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 3636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 3666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// assignment operator 3676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst MessageFormat& 3696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::operator=(const MessageFormat& that) 3706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this != &that) { 3726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Calls the super class for assignment first. 3736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format::operator=(that); 3746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setLocale(that.fLocale); 3766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern = that.msgPattern; 3776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts = that.hasArgTypeConflicts; 3786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 3806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org copyObjects(that, ec); 3816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 3826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resetPattern(); 3836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 3856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 3866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 3876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 3896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::operator==(const Format& rhs) const 3906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 3916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this == &rhs) return TRUE; 3926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat& that = (MessageFormat&)rhs; 3946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 3956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check class ID before checking MessageFormat members 3966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!Format::operator==(rhs) || 3976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern != that.msgPattern || 3986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLocale != that.fLocale) { 3996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Compare hashtables. 4036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((customFormatArgStarts == NULL) != (that.customFormatArgStarts == NULL)) { 4046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts == NULL) { 4076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 4116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t count = uhash_count(customFormatArgStarts); 4126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t rhs_count = uhash_count(that.customFormatArgStarts); 4136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (count != rhs_count) { 4146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t idx = 0, rhs_idx = 0, pos = -1, rhs_pos = -1; 4176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (; idx < count && rhs_idx < rhs_count && U_SUCCESS(ec); ++idx, ++rhs_idx) { 4186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UHashElement* cur = uhash_nextElement(customFormatArgStarts, &pos); 4196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UHashElement* rhs_cur = uhash_nextElement(that.customFormatArgStarts, &rhs_pos); 4206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cur->key.integer != rhs_cur->key.integer) { 4216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format* format = (const Format*)uhash_iget(cachedFormatters, cur->key.integer); 4246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format* rhs_format = (const Format*)uhash_iget(that.cachedFormatters, rhs_cur->key.integer); 4256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (*format != *rhs_format) { 4266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 4276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 4306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Creates a copy of this MessageFormat, the caller owns the copy. 4346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* 4366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::clone() const 4376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new MessageFormat(*this); 4396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the locale of this MessageFormat object to theLocale. 4436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 4456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::setLocale(const Locale& theLocale) 4466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fLocale != theLocale) { 4486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete defaultNumberFormat; 4496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultNumberFormat = NULL; 4506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete defaultDateFormat; 4516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org defaultDateFormat = NULL; 4526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fLocale = theLocale; 4536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setLocaleIDs(fLocale.getName(), fLocale.getName()); 4546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralProvider.reset(); 4556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ordinalProvider.reset(); 4566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the locale of this MessageFormat object. 4616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Locale& 4636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::getLocale() const 4646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fLocale; 4666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 4696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::applyPattern(const UnicodeString& newPattern, 4706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) 4716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError parseError; 4736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(newPattern,parseError,status); 4746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 4786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Applies the new pattern and returns an error if the pattern 4796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// is not correct. 4806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 4816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::applyPattern(const UnicodeString& pattern, 4826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError& parseError, 4836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& ec) 4846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 4856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(U_FAILURE(ec)) { 4866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 4876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.parse(pattern, &parseError, ec); 4896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cacheExplicitFormats(ec); 4906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 4926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resetPattern(); 4936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 4946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 4956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 4966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::resetPattern() { 4976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.clear(); 4986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(cachedFormatters); 4996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters = NULL; 5006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_close(customFormatArgStarts); 5016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts = NULL; 5026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount = 0; 5036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts = FALSE; 5046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 5076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::applyPattern(const UnicodeString& pattern, 5086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternApostropheMode aposMode, 5096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError* parseError, 5106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) { 5116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (aposMode != msgPattern.getApostropheMode()) { 5126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.clearPatternAndSetApostropheMode(aposMode); 5136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(pattern, *parseError, status); 5156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 5186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Converts this MessageFormat instance to a pattern. 5196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 5216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::toPattern(UnicodeString& appendTo) const { 5226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((customFormatArgStarts != NULL && 0 != uhash_count(customFormatArgStarts)) || 5236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 0 == msgPattern.countParts() 5246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 5256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.setToBogus(); 5266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 5276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo.append(msgPattern.getPatternString()); 5296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t MessageFormat::nextTopLevelArgStart(int32_t partIndex) const { 5326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (partIndex != 0) { 5336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex = msgPattern.getLimitPartIndex(partIndex); 5346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (;;) { 5366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternPartType type = msgPattern.getPartType(++partIndex); 5376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_ARG_START) { 5386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return partIndex; 5396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 5416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 5426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::setArgStartFormat(int32_t argStart, 5476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* formatter, 5486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) { 5496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete formatter; 5516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters == NULL) { 5546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters=uhash_open(uhash_hashLong, uhash_compareLong, 5556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org equalFormatsForHash, &status); 5566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 5576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete formatter; 5586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 5596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setValueDeleter(cachedFormatters, uprv_deleteUObject); 5616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (formatter == NULL) { 5636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatter = new DummyFormat(); 5646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_iput(cachedFormatters, argStart, formatter, &status); 5666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool MessageFormat::argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber) { 5706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part = msgPattern.getPart(partIndex); 5716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return part.getType() == UMSGPAT_PART_TYPE_ARG_NAME ? 5726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.partSubstringMatches(part, argName) : 5736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org part.getValue() == argNumber; // ARG_NUMBER 5746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets a custom formatter for a MessagePattern ARG_START part index. 5776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// "Custom" formatters are provided by the user via setFormat() or similar APIs. 5786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::setCustomArgStartFormat(int32_t argStart, 5796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* formatter, 5806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) { 5816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setArgStartFormat(argStart, formatter, status); 5826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts == NULL) { 5836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts=uhash_open(uhash_hashLong, uhash_compareLong, 5846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, &status); 5856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_iputi(customFormatArgStarts, argStart, 1, &status); 5876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 5886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 5896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* MessageFormat::getCachedFormatter(int32_t argumentNumber) const { 5906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters == NULL) { 5916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 5936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org void* ptr = uhash_iget(cachedFormatters, argumentNumber); 5946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (ptr != NULL && dynamic_cast<DummyFormat*>((Format*)ptr) == NULL) { 5956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (Format*) ptr; 5966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 5976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Not cached, or a DummyFormat representing setFormat(NULL). 5986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 5996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 6036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Adopts the new formats array and updates the array count. 6046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This MessageFormat instance owns the new formats. 6056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 6066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::adoptFormats(Format** newFormats, 6076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count) { 6086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newFormats == NULL || count < 0) { 6096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 6106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Throw away any cached formatters. 6126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters != NULL) { 6136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(cachedFormatters); 6146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts != NULL) { 6166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(customFormatArgStarts); 6176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t formatNumber = 0; 6206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; 6226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatNumber < count && U_SUCCESS(status) && 6236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 6246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, newFormats[formatNumber], status); 6256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++formatNumber; 6266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Delete those that didn't get used (if any). 6286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (; formatNumber < count; ++formatNumber) { 6296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete newFormats[formatNumber]; 6306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 6356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Sets the new formats array and updates the array count. 6366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// This MessageFormat instance maks a copy of the new formats. 6376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 6396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::setFormats(const Format** newFormats, 6406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count) { 6416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newFormats == NULL || count < 0) { 6426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 6436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Throw away any cached formatters. 6456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters != NULL) { 6466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(cachedFormatters); 6476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts != NULL) { 6496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(customFormatArgStarts); 6506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t formatNumber = 0; 6546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; 6556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatNumber < count && U_SUCCESS(status) && (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 6566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* newFormat = NULL; 6576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newFormats[formatNumber] != NULL) { 6586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org newFormat = newFormats[formatNumber]->clone(); 6596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newFormat == NULL) { 6606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 6616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, newFormat, status); 6646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++formatNumber; 6656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 6676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org resetPattern(); 6686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 6726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Adopt a single format by format number. 6736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Do nothing if the format number is not less than the array count. 6746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 6766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::adoptFormat(int32_t n, Format *newFormat) { 6776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LocalPointer<Format> p(newFormat); 6786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 6796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t formatNumber = 0; 6806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 6816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n == formatNumber) { 6826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 6836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, p.orphan(), status); 6846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 6856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++formatNumber; 6876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 6896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 6906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 6916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 6926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Adopt a single format by format name. 6936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Do nothing if there is no match of formatName. 6946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 6956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::adoptFormat(const UnicodeString& formatName, 6966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* formatToAdopt, 6976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) { 6986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LocalPointer<Format> p(formatToAdopt); 6996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 7006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = MessagePattern::validateArgumentName(formatName); 7036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 7046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 7056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; 7086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (partIndex = nextTopLevelArgStart(partIndex)) >= 0 && U_SUCCESS(status); 7096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 7106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNameMatches(partIndex + 1, formatName, argNumber)) { 7116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* f; 7126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (p.isValid()) { 7136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org f = p.orphan(); 7146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (formatToAdopt == NULL) { 7156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org f = NULL; 7166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org f = formatToAdopt->clone(); 7186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (f == NULL) { 7196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 7206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, f, status); 7246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 7296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Set a single format. 7306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Do nothing if the variable is not less than the array count. 7316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 7326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::setFormat(int32_t n, const Format& newFormat) { 7336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n >= 0) { 7356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t formatNumber = 0; 7366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; 7376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 7386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (n == formatNumber) { 7396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* new_format = newFormat.clone(); 7406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (new_format) { 7416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode status = U_ZERO_ERROR; 7426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, new_format, status); 7436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++formatNumber; 7476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 7526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Get a single format by format name. 7536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Do nothing if the variable is not less than the array count. 7546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat * 7556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::getFormat(const UnicodeString& formatName, UErrorCode& status) { 7566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status) || cachedFormatters == NULL) return NULL; 7576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = MessagePattern::validateArgumentName(formatName); 7596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 7606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 7616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 7626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 7646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNameMatches(partIndex + 1, formatName, argNumber)) { 7656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return getCachedFormatter(partIndex); 7666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 7696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 7706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 7726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Set a single format by format name 7736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Do nothing if the variable is not less than the array count. 7746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 7756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::setFormat(const UnicodeString& formatName, 7766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format& newFormat, 7776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) { 7786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) return; 7796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 7806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = MessagePattern::validateArgumentName(formatName); 7816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNumber < UMSGPAT_ARG_NAME_NOT_NUMBER) { 7826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 7836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; 7866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (partIndex = nextTopLevelArgStart(partIndex)) >= 0 && U_SUCCESS(status); 7876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 7886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNameMatches(partIndex + 1, formatName, argNumber)) { 7896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (&newFormat == NULL) { 7906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, NULL, status); 7916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 7926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* new_format = newFormat.clone(); 7936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (new_format == NULL) { 7946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 7956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 7966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setCustomArgStartFormat(partIndex, new_format, status); 7986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 7996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 8046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Gets the format array. 8056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Format** 8066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::getFormats(int32_t& cnt) const 8076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 8086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This old API returns an array (which we hold) of Format* 8096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // pointers. The array is valid up to the next call to any 8106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // method on this object. We construct and resize an array 8116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // on demand that contains aliases to the subformats[i].format 8126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // pointers. 8136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat* t = const_cast<MessageFormat*> (this); 8146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt = 0; 8156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (formatAliases == NULL) { 8166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliasesCapacity = (argTypeCount<10) ? 10 : argTypeCount; 8176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format** a = (Format**) 8186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_malloc(sizeof(Format*) * formatAliasesCapacity); 8196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (a == NULL) { 8206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliasesCapacity = 0; 8216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 8226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliases = a; 8246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (argTypeCount > formatAliasesCapacity) { 8256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format** a = (Format**) 8266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_realloc(formatAliases, sizeof(Format*) * argTypeCount); 8276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (a == NULL) { 8286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliasesCapacity = 0; 8296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 8306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliases = a; 8326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliasesCapacity = argTypeCount; 8336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 8366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->formatAliases[cnt++] = getCachedFormatter(partIndex); 8376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (const Format**)formatAliases; 8406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString MessageFormat::getArgName(int32_t partIndex) { 8446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part = msgPattern.getPart(partIndex); 8456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgPattern.getSubstring(part); 8466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgStringEnumeration* 8496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::getFormatNames(UErrorCode& status) { 8506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) return NULL; 8516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UVector *fFormatNames = new UVector(status); 8536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 8546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 8556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 8566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fFormatNames->setDeleter(uprv_deleteUObject); 8586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t partIndex = 0; (partIndex = nextTopLevelArgStart(partIndex)) >= 0;) { 8606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fFormatNames->addElement(new UnicodeString(getArgName(partIndex + 1)), status); 8616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 8626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org StringEnumeration* nameEnumerator = new FormatNameEnumeration(fFormatNames, status); 8646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return nameEnumerator; 8656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 8686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats the source Formattable array and copy into the result buffer. 8696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Ignore the FieldPosition result for error checking. 8706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 8726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::format(const Formattable* source, 8736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 8746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 8756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& ignore, 8766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const 8776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 8786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format(source, NULL, cnt, appendTo, &ignore, success); 8796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 8826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Internally creates a MessageFormat instance based on the 8836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// pattern and formats the arguments Formattable array and 8846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// copy into the appendTo buffer. 8856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 8876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::format( const UnicodeString& pattern, 8886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* arguments, 8896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 8906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 8916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) 8926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 8936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat temp(pattern, success); 8946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return temp.format(arguments, NULL, cnt, appendTo, NULL, success); 8956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 8966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 8976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 8986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formats the source Formattable object and copy into the 8996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// appendTo buffer. The Formattable object must be an array 9006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// of Formattable instances, returns error otherwise. 9016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 9036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::format(const Formattable& source, 9046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 9056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& ignore, 9066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const 9076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 9086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(success)) 9096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 9106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (source.getType() != Formattable::kArray) { 9116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_ILLEGAL_ARGUMENT_ERROR; 9126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 9136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt; 9156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* tmpPtr = source.getArray(cnt); 9166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format(tmpPtr, NULL, cnt, appendTo, &ignore, success); 9176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 9206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::format(const UnicodeString* argumentNames, 9216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* arguments, 9226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count, 9236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 9246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const { 9256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format(arguments, argumentNames, count, appendTo, NULL, success); 9266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Does linear search to find the match for an ArgName. 9296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst Formattable* MessageFormat::getArgFromListByName(const Formattable* arguments, 9306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *argumentNames, 9316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, UnicodeString& name) const { 9326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < cnt; ++i) { 9336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (0 == argumentNames[i].compare(name)) { 9346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return arguments + i; 9356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 9386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 9426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::format(const Formattable* arguments, 9436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *argumentNames, 9446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 9456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 9466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition* pos, 9476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 9486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 9496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 9506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeStringAppendable usapp(appendTo); 9536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AppendableWrapper app(usapp); 9546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org format(0, NULL, arguments, argumentNames, cnt, app, pos, status); 9556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 9566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 9576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgnamespace { 9596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 9616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Mutable input/output values for the PluralSelectorProvider. 9626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Separate so that it is possible to make MessageFormat Freezable. 9636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 9646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgclass PluralSelectorContext { 9656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgpublic: 9666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PluralSelectorContext(int32_t start, const UnicodeString &name, 9676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable &num, double off, UErrorCode &errorCode) 9686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : startIndex(start), argName(name), offset(off), 9696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org numberArgIndex(-1), formatter(NULL), forReplaceNumber(FALSE) { 9706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // number needs to be set even when select() is not called. 9716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Keep it as a Number/Formattable: 9726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // For format() methods, and to preserve information (e.g., BigDecimal). 9736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(off == 0) { 9746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org number = num; 9756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 9766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org number = num.getDouble(errorCode) - off; 9776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 9796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Input values for plural selection with decimals. 9816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t startIndex; 9826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString &argName; 9836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** argument number - plural offset */ 9846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable number; 9856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double offset; 9866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Output values for plural selection with decimals. 9876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** -1 if REPLACE_NUMBER, 0 arg not found, >0 ARG_START index */ 9886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t numberArgIndex; 9896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format *formatter; 9906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** formatted argument number - plural offset */ 9916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString numberString; 9926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /** TRUE if number-offset was formatted with the stock number formatter */ 9936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool forReplaceNumber; 9946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org}; 9956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} // namespace 9976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 9986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// if argumentNames is NULL, this means arguments is a numeric array. 9996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// arguments can not be NULL. 10006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// We use const void *plNumber rather than const PluralSelectorContext *pluralNumber 10016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// so that we need not declare the PluralSelectorContext in the public header file. 10026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::format(int32_t msgStart, const void *plNumber, 10036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* arguments, 10046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *argumentNames, 10056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 10066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AppendableWrapper& appendTo, 10076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition* ignore, 10086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const { 10096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(success)) { 10106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 10116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 10136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& msgString = msgPattern.getPatternString(); 10146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevIndex = msgPattern.getPart(msgStart).getLimit(); 10156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = msgStart + 1; U_SUCCESS(success) ; ++i) { 10166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part* part = &msgPattern.getPart(i); 10176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UMessagePatternPartType type = part->getType(); 10186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index = part->getIndex(); 10196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(msgString, prevIndex, index - prevIndex); 10206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 10216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 10226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = part->getLimit(); 10246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) { 10256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const PluralSelectorContext &pluralNumber = 10266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *static_cast<const PluralSelectorContext *>(plNumber); 10276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pluralNumber.forReplaceNumber) { 10286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // number-offset was already formatted. 10296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(pluralNumber.formatter, 10306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralNumber.number, pluralNumber.numberString, success); 10316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const NumberFormat* nf = getDefaultNumberFormat(success); 10336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(nf, pluralNumber.number, success); 10346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 10366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type != UMSGPAT_PART_TYPE_ARG_START) { 10386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 10396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argLimit = msgPattern.getLimitPartIndex(i); 10416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternArgType argType = part->getArgType(); 10426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org part = &msgPattern.getPart(++i); 10436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* arg; 10446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool noArg = FALSE; 10456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString argName = msgPattern.getSubstring(*part); 10466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argumentNames == NULL) { 10476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = part->getValue(); // ARG_NUMBER 10486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (0 <= argNumber && argNumber < cnt) { 10496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org arg = arguments + argNumber; 10506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org arg = NULL; 10526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org noArg = TRUE; 10536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org arg = getArgFromListByName(arguments, argumentNames, cnt, argName); 10566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (arg == NULL) { 10576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org noArg = TRUE; 10586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++i; 10616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevDestLength = appendTo.length(); 10626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format* formatter = NULL; 10636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (noArg) { 10646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append( 10656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString(LEFT_CURLY_BRACE).append(argName).append(RIGHT_CURLY_BRACE)); 10666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (arg == NULL) { 10676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(NULL_STRING, 4); 10686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(plNumber!=NULL && 10696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org static_cast<const PluralSelectorContext *>(plNumber)->numberArgIndex==(i-2)) { 10706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const PluralSelectorContext &pluralNumber = 10716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *static_cast<const PluralSelectorContext *>(plNumber); 10726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pluralNumber.offset == 0) { 10736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The number was already formatted with this formatter. 10746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(pluralNumber.formatter, pluralNumber.number, 10756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pluralNumber.numberString, success); 10766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Do not use the formatted (number-offset) string for a named argument 10786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // that formats the number without subtracting the offset. 10796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(pluralNumber.formatter, *arg, success); 10806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if ((formatter = getCachedFormatter(i -2))) { 10826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Handles all ArgType.SIMPLE, and formatters from setFormat() and its siblings. 10836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (dynamic_cast<const ChoiceFormat*>(formatter) || 10846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dynamic_cast<const PluralFormat*>(formatter) || 10856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dynamic_cast<const SelectFormat*>(formatter)) { 10866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We only handle nested formats here if they were provided via 10876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // setFormat() or its siblings. Otherwise they are not cached and instead 10886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // handled below according to argType. 10896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString subMsgString; 10906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatter->format(*arg, subMsgString, success); 10916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (subMsgString.indexOf(LEFT_CURLY_BRACE) >= 0 || 10926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (subMsgString.indexOf(SINGLE_QUOTE) >= 0 && !MessageImpl::jdkAposMode(msgPattern)) 10936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ) { 10946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat subMsgFormat(subMsgString, fLocale, success); 10956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org subMsgFormat.format(0, NULL, arguments, argumentNames, cnt, appendTo, ignore, success); 10966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 10976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(subMsgString); 10986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 10996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(formatter, *arg, success); 11016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (argType == UMSGPAT_ARG_TYPE_NONE || (cachedFormatters && uhash_iget(cachedFormatters, i - 2))) { 11036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We arrive here if getCachedFormatter returned NULL, but there was actually an element in the hash table. 11046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This can only happen if the hash table contained a DummyFormat, so the if statement above is a check 11056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for the hash table containind DummyFormat. 11066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (arg->isNumeric()) { 11076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const NumberFormat* nf = getDefaultNumberFormat(success); 11086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(nf, *arg, success); 11096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (arg->getType() == Formattable::kDate) { 11106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DateFormat* df = getDefaultDateFormat(success); 11116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.formatAndAppend(df, *arg, success); 11126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(arg->getString(success)); 11146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (argType == UMSGPAT_ARG_TYPE_CHOICE) { 11166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!arg->isNumeric()) { 11176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_ILLEGAL_ARGUMENT_ERROR; 11186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We must use the Formattable::getDouble() variant with the UErrorCode parameter 11216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // because only this one converts non-double numeric types to double. 11226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const double number = arg->getDouble(success); 11236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t subMsgStart = ChoiceFormat::findSubMessage(msgPattern, i, number); 11246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatComplexSubMessage(subMsgStart, NULL, arguments, argumentNames, 11256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt, appendTo, success); 11266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType)) { 11276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!arg->isNumeric()) { 11286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_ILLEGAL_ARGUMENT_ERROR; 11296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const PluralSelectorProvider &selector = 11326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argType == UMSGPAT_ARG_TYPE_PLURAL ? pluralProvider : ordinalProvider; 11336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We must use the Formattable::getDouble() variant with the UErrorCode parameter 11346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // because only this one converts non-double numeric types to double. 11356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double offset = msgPattern.getPluralOffset(i); 11366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PluralSelectorContext context(i, argName, *arg, offset, success); 11376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t subMsgStart = PluralFormat::findSubMessage( 11386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern, i, selector, &context, arg->getDouble(success), success); 11396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatComplexSubMessage(subMsgStart, &context, arguments, argumentNames, 11406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt, appendTo, success); 11416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (argType == UMSGPAT_ARG_TYPE_SELECT) { 11426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t subMsgStart = SelectFormat::findSubMessage(msgPattern, i, arg->getString(success), success); 11436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatComplexSubMessage(subMsgStart, NULL, arguments, argumentNames, 11446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cnt, appendTo, success); 11456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This should never happen. 11476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_INTERNAL_PROGRAM_ERROR; 11486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ignore = updateMetaData(appendTo, prevDestLength, ignore, arg); 11516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = msgPattern.getPart(argLimit).getLimit(); 11526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i = argLimit; 11536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 11556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::formatComplexSubMessage(int32_t msgStart, 11586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const void *plNumber, 11596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Formattable* arguments, 11606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString *argumentNames, 11616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt, 11626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org AppendableWrapper& appendTo, 11636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const { 11646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(success)) { 11656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!MessageImpl::jdkAposMode(msgPattern)) { 11696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org format(msgStart, plNumber, arguments, argumentNames, cnt, appendTo, NULL, success); 11706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 11716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 11726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 11736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // JDK compatibility mode: (see JDK MessageFormat.format() API docs) 11746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // - remove SKIP_SYNTAX; that is, remove half of the apostrophes 11756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // - if the result string contains an open curly brace '{' then 11766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // instantiate a temporary MessageFormat object and format again; 11776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // otherwise just append the result string 11786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& msgString = msgPattern.getPatternString(); 11796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString sb; 11806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevIndex = msgPattern.getPart(msgStart).getLimit(); 11816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = msgStart;;) { 11826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part = msgPattern.getPart(++i); 11836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UMessagePatternPartType type = part.getType(); 11846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index = part.getIndex(); 11856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) { 11866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sb.append(msgString, prevIndex, index - prevIndex); 11876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 11886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER || type == UMSGPAT_PART_TYPE_SKIP_SYNTAX) { 11896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sb.append(msgString, prevIndex, index - prevIndex); 11906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) { 11916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const PluralSelectorContext &pluralNumber = 11926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *static_cast<const PluralSelectorContext *>(plNumber); 11936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pluralNumber.forReplaceNumber) { 11946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // number-offset was already formatted. 11956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sb.append(pluralNumber.numberString); 11966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 11976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const NumberFormat* nf = getDefaultNumberFormat(success); 11986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sb.append(nf->format(pluralNumber.number, sb, success)); 11996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = part.getLimit(); 12026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (type == UMSGPAT_PART_TYPE_ARG_START) { 12036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sb.append(msgString, prevIndex, index - prevIndex); 12046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = index; 12056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i = msgPattern.getLimitPartIndex(i); 12066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org index = msgPattern.getPart(i).getLimit(); 12076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageImpl::appendReducedApostrophes(msgString, prevIndex, index, sb); 12086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex = index; 12096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sb.indexOf(LEFT_CURLY_BRACE) >= 0) { 12126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString emptyPattern; // gcc 3.3.3 fails with "UnicodeString()" as the first parameter. 12136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat subMsgFormat(emptyPattern, fLocale, success); 12146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org subMsgFormat.applyPattern(sb, UMSGPAT_APOS_DOUBLE_REQUIRED, NULL, success); 12156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org subMsgFormat.format(0, NULL, arguments, argumentNames, cnt, appendTo, NULL, success); 12166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 12176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(sb); 12186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString MessageFormat::getLiteralStringUntilNextArgument(int32_t from) const { 12236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& msgString=msgPattern.getPatternString(); 12246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevIndex=msgPattern.getPart(from).getLimit(); 12256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString b; 12266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = from + 1; ; ++i) { 12276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part = msgPattern.getPart(i); 12286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UMessagePatternPartType type=part.getType(); 12296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index=part.getIndex(); 12306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org b.append(msgString, prevIndex, index - prevIndex); 12316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_ARG_START || type==UMSGPAT_PART_TYPE_MSG_LIMIT) { 12326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return b; 12336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Unexpected Part "part" in parsed message. 12356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(type==UMSGPAT_PART_TYPE_SKIP_SYNTAX || type==UMSGPAT_PART_TYPE_INSERT_CHAR); 12366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex=part.getLimit(); 12376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFieldPosition* MessageFormat::updateMetaData(AppendableWrapper& /*dest*/, int32_t /*prevLength*/, 12426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition* /*fp*/, const Formattable* /*argId*/) const { 12436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Unlike in Java, there are no field attributes defined for MessageFormat. Do nothing. 12446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 12456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 12466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fp != NULL && Field.ARGUMENT.equals(fp.getFieldAttribute())) { 12476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fp->setBeginIndex(prevLength); 12486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fp->setEndIndex(dest.get_length()); 12496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 12506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fp; 12526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 12536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 12566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::findOtherSubMessage(int32_t partIndex) const { 12576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count=msgPattern.countParts(); 12586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part *part = &msgPattern.getPart(partIndex); 12596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(MessagePattern::Part::hasNumericValue(part->getType())) { 12606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++partIndex; 12616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Iterate over (ARG_SELECTOR [ARG_INT|ARG_DOUBLE] message) tuples 12636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // until ARG_LIMIT or end of plural-only pattern. 12646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString other(FALSE, OTHER_STRING, 5); 12656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 12666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org part=&msgPattern.getPart(partIndex++); 12676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternPartType type=part->getType(); 12686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) { 12696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 12706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(type==UMSGPAT_PART_TYPE_ARG_SELECTOR); 12726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // part is an ARG_SELECTOR followed by an optional explicit value, and then a message 12736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(msgPattern.partSubstringMatches(*part, other)) { 12746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return partIndex; 12756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(MessagePattern::Part::hasNumericValue(msgPattern.getPartType(partIndex))) { 12776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++partIndex; // skip the numeric-value part of "=1" etc. 12786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex=msgPattern.getLimitPartIndex(partIndex); 12806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(++partIndex<count); 12816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 12826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 12836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 12846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 12856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const { 12866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int32_t i=msgStart+1;; ++i) { 12876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part &part=msgPattern.getPart(i); 12886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternPartType type=part.getType(); 12896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_MSG_LIMIT) { 12906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 12916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_REPLACE_NUMBER) { 12936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 12946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 12956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_ARG_START) { 12966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternArgType argType=part.getArgType(); 12976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(!argName.isEmpty() && (argType==UMSGPAT_ARG_TYPE_NONE || argType==UMSGPAT_ARG_TYPE_SIMPLE)) { 12986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ARG_NUMBER or ARG_NAME 12996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(msgPattern.partSubstringMatches(msgPattern.getPart(i+1), argName)) { 13006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 13016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=msgPattern.getLimitPartIndex(i); 13046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::copyObjects(const MessageFormat& that, UErrorCode& ec) { 13096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Deep copy pointer fields. 13106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We need not copy the formatAliases because they are re-filled 13116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in each getFormats() call. 13126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The defaultNumberFormat, defaultDateFormat and pluralProvider.rules 13136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // also get created on demand. 13146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount = that.argTypeCount; 13156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argTypeCount > 0) { 13166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!allocateArgTypes(argTypeCount, ec)) { 13176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 13186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(argTypes, that.argTypes, argTypeCount * sizeof(argTypes[0])); 13206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters != NULL) { 13226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(cachedFormatters); 13236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts != NULL) { 13256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(customFormatArgStarts); 13266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (that.cachedFormatters) { 13286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters == NULL) { 13296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org cachedFormatters=uhash_open(uhash_hashLong, uhash_compareLong, 13306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org equalFormatsForHash, &ec); 13316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 13326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 13336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_setValueDeleter(cachedFormatters, uprv_deleteUObject); 13356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t count = uhash_count(that.cachedFormatters); 13386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t pos, idx; 13396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 0, pos = -1; idx < count && U_SUCCESS(ec); ++idx) { 13406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UHashElement* cur = uhash_nextElement(that.cachedFormatters, &pos); 13416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* newFormat = ((Format*)(cur->value.pointer))->clone(); 13426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (newFormat) { 13436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_iput(cachedFormatters, cur->key.integer, newFormat, &ec); 13446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_MEMORY_ALLOCATION_ERROR; 13466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 13476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (that.customFormatArgStarts) { 13516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts == NULL) { 13526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org customFormatArgStarts=uhash_open(uhash_hashLong, uhash_compareLong, 13536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NULL, &ec); 13546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int32_t count = uhash_count(that.customFormatArgStarts); 13566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t pos, idx; 13576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (idx = 0, pos = -1; idx < count && U_SUCCESS(ec); ++idx) { 13586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UHashElement* cur = uhash_nextElement(that.customFormatArgStarts, &pos); 13596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_iputi(customFormatArgStarts, cur->key.integer, cur->value.integer, &ec); 13606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 13636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable* 13666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::parse(int32_t msgStart, 13676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& source, 13686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& pos, 13696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t& count, 13706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& ec) const { 13716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count = 0; 13726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 13736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(pos.getIndex()); 13746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 13756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // parse() does not work with named arguments. 13776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (msgPattern.hasNamedArguments()) { 13786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_ARGUMENT_TYPE_MISMATCH; 13796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(pos.getIndex()); 13806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 13816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 13826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org LocalArray<Formattable> resultArray(new Formattable[argTypeCount ? argTypeCount : 1]); 13836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& msgString=msgPattern.getPatternString(); 13846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t prevIndex=msgPattern.getPart(msgStart).getLimit(); 13856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t sourceOffset = pos.getIndex(); 13866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition tempStatus(0); 13876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 13886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for(int32_t i=msgStart+1; ; ++i) { 13896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool haveArgResult = FALSE; 13906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part* part=&msgPattern.getPart(i); 13916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UMessagePatternPartType type=part->getType(); 13926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index=part->getIndex(); 13936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Make sure the literal string matches. 13946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = index - prevIndex; 13956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (len == 0 || (0 == msgString.compare(prevIndex, len, source, sourceOffset, len))) { 13966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceOffset += len; 13976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex += len; 13986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 13996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(sourceOffset); 14006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; // leave index as is to signal error 14016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_MSG_LIMIT) { 14036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Things went well! Done. 14046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setIndex(sourceOffset); 14056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return resultArray.orphan(); 14066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_SKIP_SYNTAX || type==UMSGPAT_PART_TYPE_INSERT_CHAR) { 14086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex=part->getLimit(); 14096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 14106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We do not support parsing Plural formats. (No REPLACE_NUMBER here.) 14126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Unexpected Part "part" in parsed message. 14136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(type==UMSGPAT_PART_TYPE_ARG_START); 14146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argLimit=msgPattern.getLimitPartIndex(i); 14156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternArgType argType=part->getArgType(); 14176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org part=&msgPattern.getPart(++i); 14186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = part->getValue(); // ARG_NUMBER 14196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString key; 14206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++i; 14216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const Format* formatter = NULL; 14226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable& argResult = resultArray[argNumber]; 14236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(cachedFormatters!=NULL && (formatter = getCachedFormatter(i - 2))!=NULL) { 14256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Just parse using the formatter. 14266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempStatus.setIndex(sourceOffset); 14276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formatter->parseObject(source, argResult, tempStatus); 14286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tempStatus.getIndex() == sourceOffset) { 14296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(sourceOffset); 14306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; // leave index as is to signal error 14316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceOffset = tempStatus.getIndex(); 14336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org haveArgResult = TRUE; 14346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if( 14356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argType==UMSGPAT_ARG_TYPE_NONE || (cachedFormatters && uhash_iget(cachedFormatters, i -2))) { 14366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We arrive here if getCachedFormatter returned NULL, but there was actually an element in the hash table. 14376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This can only happen if the hash table contained a DummyFormat, so the if statement above is a check 14386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // for the hash table containind DummyFormat. 14396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Match as a string. 14416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // if at end, use longest possible match 14426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // otherwise uses first match to intervening string 14436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // does NOT recursively try all possibilities 14446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString stringAfterArgument = getLiteralStringUntilNextArgument(argLimit); 14456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t next; 14466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!stringAfterArgument.isEmpty()) { 14476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org next = source.indexOf(stringAfterArgument, sourceOffset); 14486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 14496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org next = source.length(); 14506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (next < 0) { 14526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(sourceOffset); 14536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; // leave index as is to signal error 14546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 14556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString strValue(source.tempSubString(sourceOffset, next - sourceOffset)); 14566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString compValue; 14576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org compValue.append(LEFT_CURLY_BRACE); 14586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org itos(argNumber, compValue); 14596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org compValue.append(RIGHT_CURLY_BRACE); 14606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (0 != strValue.compare(compValue)) { 14616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argResult.setString(strValue); 14626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org haveArgResult = TRUE; 14636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceOffset = next; 14656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(argType==UMSGPAT_ARG_TYPE_CHOICE) { 14676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org tempStatus.setIndex(sourceOffset); 14686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org double choiceResult = ChoiceFormat::parseArgument(msgPattern, i, source, tempStatus); 14696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tempStatus.getIndex() == sourceOffset) { 14706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(sourceOffset); 14716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; // leave index as is to signal error 14726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argResult.setDouble(choiceResult); 14746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org haveArgResult = TRUE; 14756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sourceOffset = tempStatus.getIndex(); 14766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) || argType==UMSGPAT_ARG_TYPE_SELECT) { 14776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Parsing not supported. 14786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_UNSUPPORTED_ERROR; 14796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 14806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 14816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This should never happen. 14826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_INTERNAL_PROGRAM_ERROR; 14836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 14846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (haveArgResult && count <= argNumber) { 14866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org count = argNumber + 1; 14876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org prevIndex=msgPattern.getPart(argLimit).getLimit(); 14896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i=argLimit; 14906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 14916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 14926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 14936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Parses the source pattern and returns the Formattable objects array, 14946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// the array count and the ending parse position. The caller of this method 14956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// owns the array. 14966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 14976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable* 14986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::parse(const UnicodeString& source, 14996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& pos, 15006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t& count) const { 15016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode ec = U_ZERO_ERROR; 15026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return parse(0, source, pos, count, ec); 15036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 15066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Parses the source string and returns the array of 15076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Formattable objects and the array count. The caller 15086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// owns the returned array. 15096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormattable* 15116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::parse(const UnicodeString& source, 15126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t& cnt, 15136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& success) const 15146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (msgPattern.hasNamedArguments()) { 15166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_ARGUMENT_TYPE_MISMATCH; 15176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 15186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition status(0); 15206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Calls the actual implementation method and starts 15216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // from zero offset of the source text. 15226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable* result = parse(source, status, cnt); 15236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (status.getIndex() == 0) { 15246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org success = U_MESSAGE_PARSE_ERROR; 15256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete[] result; 15266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 15276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 15296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 15326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Parses the source text and copy into the result buffer. 15336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 15356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::parseObject( const UnicodeString& source, 15366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable& result, 15376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& status) const 15386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 15396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t cnt = 0; 15406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable* tmpResult = parse(source, status, cnt); 15416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (tmpResult != NULL) 15426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.adoptArray(tmpResult, cnt); 15436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString 15466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::autoQuoteApostrophe(const UnicodeString& pattern, UErrorCode& status) { 15476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString result; 15486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 15496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t plen = pattern.length(); 15506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar* pat = pattern.getBuffer(); 15516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t blen = plen * 2 + 1; // space for null termination, convenience 15526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UChar* buf = result.getBuffer(blen); 15536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (buf == NULL) { 15546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_MEMORY_ALLOCATION_ERROR; 15556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 15566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t len = umsg_autoQuoteApostrophe(pat, plen, buf, blen, &status); 15576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.releaseBuffer(U_SUCCESS(status) ? len : 0); 15586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 15616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org result.setToBogus(); 15626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return result; 15646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// ------------------------------------- 15676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic Format* makeRBNF(URBNFRuleSetTag tag, const Locale& locale, const UnicodeString& defaultRuleSet, UErrorCode& ec) { 15696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org RuleBasedNumberFormat* fmt = new RuleBasedNumberFormat(tag, locale, ec); 15706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fmt == NULL) { 15716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_MEMORY_ALLOCATION_ERROR; 15726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (U_SUCCESS(ec) && defaultRuleSet.length() > 0) { 15736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode localStatus = U_ZERO_ERROR; // ignore unrecognized default rule set 15746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt->setDefaultRuleSet(defaultRuleSet, localStatus); 15756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fmt; 15776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 15786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::cacheExplicitFormats(UErrorCode& status) { 15806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 15816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 15826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (cachedFormatters != NULL) { 15856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(cachedFormatters); 15866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (customFormatArgStarts != NULL) { 15886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uhash_removeAll(customFormatArgStarts); 15896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 15906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 15916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // The last two "parts" can at most be ARG_LIMIT and MSG_LIMIT 15926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // which we need not examine. 15936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t limit = msgPattern.countParts() - 2; 15946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount = 0; 15956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We also need not look at the first two "parts" 15966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // (at most MSG_START and ARG_START) in this loop. 15976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We determine the argTypeCount first so that we can allocateArgTypes 15986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // so that the next loop can set argTypes[argNumber]. 15996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // (This is for the C API which needs the argTypes to read its va_arg list.) 16006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 2; i < limit && U_SUCCESS(status); ++i) { 16016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part = msgPattern.getPart(i); 16026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (part.getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) { 16036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const int argNumber = part.getValue(); 16046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNumber >= argTypeCount) { 16056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypeCount = argNumber + 1; 16066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!allocateArgTypes(argTypeCount, status)) { 16106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 16116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Set all argTypes to kObject, as a "none" value, for lack of any better value. 16136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We never use kObject for real arguments. 16146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We use it as "no argument yet" for the check for hasArgTypeConflicts. 16156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; i < argTypeCount; ++i) { 16166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes[i] = Formattable::kObject; 16176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts = FALSE; 16196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // This loop starts at part index 1 because we do need to examine 16216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // ARG_START parts. (But we can ignore the MSG_START.) 16226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 1; i < limit && U_SUCCESS(status); ++i) { 16236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part* part = &msgPattern.getPart(i); 16246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (part->getType() != UMSGPAT_PART_TYPE_ARG_START) { 16256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org continue; 16266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UMessagePatternArgType argType = part->getArgType(); 16286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t argNumber = -1; 16306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org part = &msgPattern.getPart(i + 1); 16316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (part->getType() == UMSGPAT_PART_TYPE_ARG_NUMBER) { 16326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argNumber = part->getValue(); 16336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable::Type formattableType; 16356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (argType) { 16376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_NONE: 16386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kString; 16396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_SIMPLE: { 16416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t index = i; 16426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org i += 2; 16436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString explicitType = msgPattern.getSubstring(msgPattern.getPart(i++)); 16446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString style; 16456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if ((part = &msgPattern.getPart(i))->getType() == UMSGPAT_PART_TYPE_ARG_STYLE) { 16466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org style = msgPattern.getSubstring(*part); 16476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ++i; 16486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UParseError parseError; 16506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* formatter = createAppropriateFormat(explicitType, style, formattableType, parseError, status); 16516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org setArgStartFormat(index, formatter, status); 16526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_CHOICE: 16556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_PLURAL: 16566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_SELECTORDINAL: 16576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDouble; 16586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case UMSGPAT_ARG_TYPE_SELECT: 16606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kString; 16616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 16636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INTERNAL_PROGRAM_ERROR; // Should be unreachable. 16646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kString; 16656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argNumber != -1) { 16686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (argTypes[argNumber] != Formattable::kObject && argTypes[argNumber] != formattableType) { 16696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org hasArgTypeConflicts = TRUE; 16706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org argTypes[argNumber] = formattableType; 16726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 16756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* MessageFormat::createAppropriateFormat(UnicodeString& type, UnicodeString& style, 16786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable::Type& formattableType, UParseError& parseError, 16796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& ec) { 16806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 16816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 16826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 16836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Format* fmt = NULL; 16846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t typeID, styleID; 16856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DateFormat::EStyle date_style; 16866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 16876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (typeID = findKeyword(type, TYPE_IDS)) { 16886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 0: // number 16896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDouble; 16906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org switch (findKeyword(style, NUMBER_STYLE_IDS)) { 16916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 0: // default 16926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = NumberFormat::createInstance(fLocale, ec); 16936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 1: // currency 16956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = NumberFormat::createCurrencyInstance(fLocale, ec); 16966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 16976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 2: // percent 16986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = NumberFormat::createPercentInstance(fLocale, ec); 16996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 3: // integer 17016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kLong; 17026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = createIntegerFormat(fLocale, ec); 17036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: // pattern 17056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = NumberFormat::createInstance(fLocale, ec); 17066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (fmt) { 17076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(fmt); 17086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (decfmt != NULL) { 17096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org decfmt->applyPattern(style,parseError,ec); 17106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 1: // date 17176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 2: // time 17186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDate; 17196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org styleID = findKeyword(style, DATE_STYLE_IDS); 17206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org date_style = (styleID >= 0) ? DATE_STYLES[styleID] : DateFormat::kDefault; 17216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (typeID == 1) { 17236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = DateFormat::createDateInstance(date_style, fLocale); 17246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 17256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = DateFormat::createTimeInstance(date_style, fLocale); 17266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (styleID < 0 && fmt != NULL) { 17296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org SimpleDateFormat* sdtfmt = dynamic_cast<SimpleDateFormat*>(fmt); 17306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (sdtfmt != NULL) { 17316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org sdtfmt->applyPattern(style); 17326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 3: // spellout 17376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDouble; 17386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = makeRBNF(URBNF_SPELLOUT, fLocale, style, ec); 17396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 4: // ordinal 17416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDouble; 17426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = makeRBNF(URBNF_ORDINAL, fLocale, style, ec); 17436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org case 5: // duration 17456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kDouble; 17466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fmt = makeRBNF(URBNF_DURATION, fLocale, style, ec); 17476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org default: 17496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org formattableType = Formattable::kString; 17506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_ILLEGAL_ARGUMENT_ERROR; 17516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 17526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return fmt; 17556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//------------------------------------- 17596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org// Finds the string, s, in the string array, list. 17606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t MessageFormat::findKeyword(const UnicodeString& s, 17616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar * const *list) 17626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 17636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (s.isEmpty()) { 17646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; // default 17656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t length = s.length(); 17686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UChar *ps = PatternProps::trimWhiteSpace(s.getBuffer(), length); 17696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString buffer(FALSE, ps, length); 17706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Trims the space characters and turns all characters 17716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // in s to lower case. 17726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org buffer.toLower(""); 17736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org for (int32_t i = 0; list[i]; ++i) { 17746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!buffer.compare(list[i], u_strlen(list[i]))) { 17756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return i; 17766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 17796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 17826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Convenience method that ought to be in NumberFormat 17836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 17846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgNumberFormat* 17856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::createIntegerFormat(const Locale& locale, UErrorCode& status) const { 17866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org NumberFormat *temp = NumberFormat::createInstance(locale, status); 17876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org DecimalFormat *temp2; 17886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (temp != NULL && (temp2 = dynamic_cast<DecimalFormat*>(temp)) != NULL) { 17896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp2->setMaximumFractionDigits(0); 17906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp2->setDecimalSeparatorAlwaysShown(FALSE); 17916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org temp2->setParseIntegerOnly(TRUE); 17926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 17936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return temp; 17956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 17966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 17976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 17986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return the default number format. Used to format a numeric 17996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * argument when subformats[i].format is NULL. Returns NULL 18006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * on failure. 18016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 18026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Semantically const but may modify *this. 18036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 18046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst NumberFormat* MessageFormat::getDefaultNumberFormat(UErrorCode& ec) const { 18056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (defaultNumberFormat == NULL) { 18066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat* t = (MessageFormat*) this; 18076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->defaultNumberFormat = NumberFormat::createInstance(fLocale, ec); 18086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 18096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete t->defaultNumberFormat; 18106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->defaultNumberFormat = NULL; 18116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if (t->defaultNumberFormat == NULL) { 18126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_MEMORY_ALLOCATION_ERROR; 18136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return defaultNumberFormat; 18166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 18196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Return the default date format. Used to format a date 18206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * argument when subformats[i].format is NULL. Returns NULL 18216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * on failure. 18226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 18236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Semantically const but may modify *this. 18246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 18256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst DateFormat* MessageFormat::getDefaultDateFormat(UErrorCode& ec) const { 18266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (defaultDateFormat == NULL) { 18276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat* t = (MessageFormat*) this; 18286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->defaultDateFormat = DateFormat::createDateTimeInstance(DateFormat::kShort, DateFormat::kShort, fLocale); 18296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (t->defaultDateFormat == NULL) { 18306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ec = U_MEMORY_ALLOCATION_ERROR; 18316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return defaultDateFormat; 18346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 18376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::usesNamedArguments() const { 18386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgPattern.hasNamedArguments(); 18396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 18426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::getArgTypeCount() const { 18436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return argTypeCount; 18446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool MessageFormat::equalFormats(const void* left, const void* right) { 18476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *(const Format*)left==*(const Format*)right; 18486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool MessageFormat::DummyFormat::operator==(const Format&) const { 18526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 18536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* MessageFormat::DummyFormat::clone() const { 18566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new DummyFormat(); 18576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 18606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 18616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 18626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 18636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_UNSUPPORTED_ERROR; 18646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 18666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 18696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 18706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition&, 18716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 18726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 18736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_UNSUPPORTED_ERROR; 18746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 18766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& MessageFormat::DummyFormat::format(const Formattable&, 18796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 18806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPositionIterator*, 18816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 18826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status)) { 18836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_UNSUPPORTED_ERROR; 18846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 18856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 18866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::DummyFormat::parseObject(const UnicodeString&, 18896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable&, 18906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& ) const { 18916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormatNameEnumeration::FormatNameEnumeration(UVector *fNameList, UErrorCode& /*status*/) { 18956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos=0; 18966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org fFormatNames = fNameList; 18976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 18986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 18996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgconst UnicodeString* 19006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormatNameEnumeration::snext(UErrorCode& status) { 19016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_SUCCESS(status) && pos < fFormatNames->size()) { 19026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (const UnicodeString*)fFormatNames->elementAt(pos++); 19036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 19056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 19086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormatNameEnumeration::reset(UErrorCode& /*status*/) { 19096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos=0; 19106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t 19136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormatNameEnumeration::count(UErrorCode& /*status*/) const { 19146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (fFormatNames==NULL) ? 0 : fFormatNames->size(); 19156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormatNameEnumeration::~FormatNameEnumeration() { 19186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete fFormatNames; 19196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::PluralSelectorProvider::PluralSelectorProvider(const MessageFormat &mf, UPluralType t) 19226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org : msgFormat(mf), rules(NULL), type(t) { 19236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgMessageFormat::PluralSelectorProvider::~PluralSelectorProvider() { 19266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete rules; 19276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString MessageFormat::PluralSelectorProvider::select(void *ctx, double number, 19306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& ec) const { 19316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 19326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UnicodeString(FALSE, OTHER_STRING, 5); 19336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org MessageFormat::PluralSelectorProvider* t = const_cast<MessageFormat::PluralSelectorProvider*>(this); 19356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(rules == NULL) { 19366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org t->rules = PluralRules::forLocale(msgFormat.fLocale, type, ec); 19376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 19386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return UnicodeString(FALSE, OTHER_STRING, 5); 19396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Select a sub-message according to how the number is formatted, 19426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // which is specified in the selected sub-message. 19436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // We avoid this circle by looking at how 19446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // the number is formatted in the "other" sub-message 19456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // which must always be present and usually contains the number. 19466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Message authors should be consistent across sub-messages. 19476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org PluralSelectorContext &context = *static_cast<PluralSelectorContext *>(ctx); 19486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t otherIndex = msgFormat.findOtherSubMessage(context.startIndex); 19496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context.numberArgIndex = msgFormat.findFirstPluralNumberArg(otherIndex, context.argName); 19506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(context.numberArgIndex > 0 && msgFormat.cachedFormatters != NULL) { 19516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context.formatter = 19526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org (const Format*)uhash_iget(msgFormat.cachedFormatters, context.numberArgIndex); 19536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(context.formatter == NULL) { 19556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context.formatter = msgFormat.getDefaultNumberFormat(ec); 19566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context.forReplaceNumber = TRUE; 19576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org U_ASSERT(context.number.getDouble(ec) == number); // argument number minus the offset 19596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org context.formatter->format(context.number, context.numberString, ec); 19606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DecimalFormat *decFmt = dynamic_cast<const DecimalFormat *>(context.formatter); 19616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(decFmt != NULL) { 19626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FixedDecimal dec = decFmt->getFixedDecimal(context.number, ec); 19636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return rules->select(dec); 19646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 19656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return rules->select(number); 19666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 19676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid MessageFormat::PluralSelectorProvider::reset() { 19706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org delete rules; 19716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org rules = NULL; 19726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 19736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 19766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 19786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 19796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 1980