16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/******************************************************************** 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * COPYRIGHT: 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (c) 1997-2012, International Business Machines Corporation and 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * others. All Rights Reserved. 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Copyright (C) 2010 , Yahoo! Inc. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ******************************************************************** 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * File SELFMT.CPP 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Modification History: 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Date Name Description 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 11/11/09 kirtig Finished first cut of implementation. 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 11/16/09 kirtig Improved version 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ********************************************************************/ 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "utypeinfo.h" // for 'typeid' to work 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/messagepattern.h" 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/rbnf.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/selfmt.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/uchar.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ucnv_err.h" 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/umsg.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/ustring.h" 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "messageimpl.h" 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "patternprops.h" 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "selfmtimpl.h" 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uassert.h" 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "ustrfmt.h" 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "util.h" 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "uvector.h" 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if !UCONFIG_NO_FORMATTING 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_BEGIN 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUOBJECT_DEFINE_RTTI_IMPLEMENTATION(SelectFormat) 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgstatic const UChar SELECT_KEYWORD_OTHER[] = {LOW_O, LOW_T, LOW_H, LOW_E, LOW_R, 0}; 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::SelectFormat(const UnicodeString& pat, 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) : msgPattern(status) { 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org applyPattern(pat, status); 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::SelectFormat(const SelectFormat& other) : Format(other), 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern(other.msgPattern) { 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::~SelectFormat() { 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) { 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.parseSelectStyle(newPattern, NULL, status); 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.clear(); 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::format(const Formattable& obj, 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& pos, 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (obj.getType() == Formattable::kString) { 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return format(obj.getString(status), appendTo, pos, status); 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::format(const UnicodeString& keyword, 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString& appendTo, 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org FieldPosition& /*pos */, 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UErrorCode& status) const { 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(status)) { 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Check for the validity of the keyword 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!PatternProps::isIdentifier(keyword.getBuffer(), keyword.length())) { 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_ILLEGAL_ARGUMENT_ERROR; // Invalid formatting argument. 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (msgPattern.countParts() == 0) { 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org status = U_INVALID_STATE_ERROR; 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgStart = findSubMessage(msgPattern, 0, keyword, status); 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!MessageImpl::jdkAposMode(msgPattern)) { 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t patternStart = msgPattern.getPart(msgStart).getLimit(); 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart); 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(msgPattern.getPatternString(), 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org patternStart, 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern.getPatternIndex(msgLimit) - patternStart); 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // JDK compatibility mode: Remove SKIP_SYNTAX. 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo); 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUnicodeString& 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::toPattern(UnicodeString& appendTo) { 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (0 == msgPattern.countParts()) { 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.setToBogus(); 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org appendTo.append(msgPattern.getPatternString()); 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return appendTo; 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgint32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t partIndex, 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UnicodeString& keyword, UErrorCode& ec) { 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(ec)) { 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return 0; 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UnicodeString other(FALSE, SELECT_KEYWORD_OTHER, 5); 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t count = pattern.countParts(); 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org int32_t msgStart=0; 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Iterate over (ARG_SELECTOR, message) pairs until ARG_LIMIT or end of select-only pattern. 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org do { 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const MessagePattern::Part& part=pattern.getPart(partIndex++); 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const UMessagePatternPartType type=part.getType(); 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) { 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org break; 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // part is an ARG_SELECTOR followed by a message 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pattern.partSubstringMatches(part, keyword)) { 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // keyword matches 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return partIndex; 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else if(msgStart==0 && pattern.partSubstringMatches(part, other)) { 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgStart=partIndex; 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org partIndex=pattern.getLimitPartIndex(partIndex); 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } while(++partIndex<count); 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgStart; 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgFormat* SelectFormat::clone() const 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return new SelectFormat(*this); 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat& 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::operator=(const SelectFormat& other) { 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this != &other) { 1606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org msgPattern = other.msgPattern; 1616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return *this; 1636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 1666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::operator==(const Format& other) const { 1676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (this == &other) { 1686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return TRUE; 1696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (!Format::operator==(other)) { 1716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return FALSE; 1726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const SelectFormat& o = (const SelectFormat&)other; 1746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return msgPattern == o.msgPattern; 1756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUBool 1786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::operator!=(const Format& other) const { 1796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return !operator==(other); 1806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgvoid 1836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgSelectFormat::parseObject(const UnicodeString& /*source*/, 1846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org Formattable& /*result*/, 1856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org ParsePosition& pos) const 1866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org{ 1876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org // Parsing not supported. 1886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pos.setErrorIndex(pos.getIndex()); 1896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_NAMESPACE_END 1926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif /* #if !UCONFIG_NO_FORMATTING */ 1946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org//eof 196