150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho/******************************************************************** 227f654740f2a26ad62a5c155af9199af9e69b889claireho * COPYRIGHT: 354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Copyright (c) 1997-2012, International Business Machines Corporation and 450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * others. All Rights Reserved. 527f654740f2a26ad62a5c155af9199af9e69b889claireho * Copyright (C) 2010 , Yahoo! Inc. 650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ******************************************************************** 750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * File SELFMT.CPP 950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 1050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Modification History: 1150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 1250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * Date Name Description 1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * 11/11/09 kirtig Finished first cut of implementation. 1427f654740f2a26ad62a5c155af9199af9e69b889claireho * 11/16/09 kirtig Improved version 1550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ********************************************************************/ 1650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 1754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "utypeinfo.h" // for 'typeid' to work 1827f654740f2a26ad62a5c155af9199af9e69b889claireho 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/messagepattern.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/rbnf.h" 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/selfmt.h" 2250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/uchar.h" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/ucnv_err.h" 2450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/umsg.h" 25b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/ustring.h" 26b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 2750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "cmemory.h" 28b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "messageimpl.h" 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "patternprops.h" 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "selfmtimpl.h" 3150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uassert.h" 3250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "ustrfmt.h" 33b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "util.h" 3450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uvector.h" 3550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 3650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#if !UCONFIG_NO_FORMATTING 3750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 3850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_BEGIN 3950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4050294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(SelectFormat) 4150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 4250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic const UChar SELECT_KEYWORD_OTHER[] = {LOW_O, LOW_T, LOW_H, LOW_E, LOW_R, 0}; 4350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSelectFormat::SelectFormat(const UnicodeString& pat, 45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UErrorCode& status) : msgPattern(status) { 4650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho applyPattern(pat, status); 4750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 4850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 49b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoSelectFormat::SelectFormat(const SelectFormat& other) : Format(other), 50b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern(other.msgPattern) { 5150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::~SelectFormat() { 5427f654740f2a26ad62a5c155af9199af9e69b889claireho} 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 5650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) { 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_FAILURE(status)) { 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 6027f654740f2a26ad62a5c155af9199af9e69b889claireho } 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.parseSelectStyle(newPattern, NULL, status); 63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.clear(); 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 6650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 6750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::format(const Formattable& obj, 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UnicodeString& appendTo, 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho FieldPosition& pos, 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode& status) const 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 76b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 77b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (obj.getType() == Formattable::kString) { 78b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return format(obj.getString(status), appendTo, pos, status); 79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ILLEGAL_ARGUMENT_ERROR; 8150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return appendTo; 8250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 8350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 8450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 8550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& 8650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::format(const UnicodeString& keyword, 8727f654740f2a26ad62a5c155af9199af9e69b889claireho UnicodeString& appendTo, 8827f654740f2a26ad62a5c155af9199af9e69b889claireho FieldPosition& /*pos */, 8950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UErrorCode& status) const { 90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(status)) { 9150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return appendTo; 9250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Check for the validity of the keyword 94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!PatternProps::isIdentifier(keyword.getBuffer(), keyword.length())) { 95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_ILLEGAL_ARGUMENT_ERROR; // Invalid formatting argument. 96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (msgPattern.countParts() == 0) { 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho status = U_INVALID_STATE_ERROR; 9950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return appendTo; 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgStart = findSubMessage(msgPattern, 0, keyword, status); 102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!MessageImpl::jdkAposMode(msgPattern)) { 103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t patternStart = msgPattern.getPart(msgStart).getLimit(); 104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart); 105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(msgPattern.getPatternString(), 106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho patternStart, 107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern.getPatternIndex(msgLimit) - patternStart); 108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 10950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 110b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // JDK compatibility mode: Remove SKIP_SYNTAX. 111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo); 11250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 11350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 11450294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUnicodeString& 11550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::toPattern(UnicodeString& appendTo) { 116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (0 == msgPattern.countParts()) { 117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.setToBogus(); 118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho appendTo.append(msgPattern.getPatternString()); 12050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return appendTo; 12250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 12350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 12450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t partIndex, 126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& keyword, UErrorCode& ec) { 127b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (U_FAILURE(ec)) { 128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return 0; 12950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho UnicodeString other(FALSE, SELECT_KEYWORD_OTHER, 5); 131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t count = pattern.countParts(); 132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t msgStart=0; 133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Iterate over (ARG_SELECTOR, message) pairs until ARG_LIMIT or end of select-only pattern. 134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho do { 135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const MessagePattern::Part& part=pattern.getPart(partIndex++); 136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UMessagePatternPartType type=part.getType(); 137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) { 138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // part is an ARG_SELECTOR followed by a message 141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if(pattern.partSubstringMatches(part, keyword)) { 142b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // keyword matches 143b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return partIndex; 144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else if(msgStart==0 && pattern.partSubstringMatches(part, other)) { 145b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgStart=partIndex; 146b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho partIndex=pattern.getLimitPartIndex(partIndex); 148b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } while(++partIndex<count); 149b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgStart; 15050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoFormat* SelectFormat::clone() const 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return new SelectFormat(*this); 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat& 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::operator=(const SelectFormat& other) { 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (this != &other) { 160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho msgPattern = other.msgPattern; 16150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 16250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return *this; 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::operator==(const Format& other) const { 167b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (this == &other) { 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return TRUE; 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (!Format::operator==(other)) { 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const SelectFormat& o = (const SelectFormat&)other; 174b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho return msgPattern == o.msgPattern; 17550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 17650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoUBool 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::operator!=(const Format& other) const { 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return !operator==(other); 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 18150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehovoid 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoSelectFormat::parseObject(const UnicodeString& /*source*/, 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Formattable& /*result*/, 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ParsePosition& pos) const 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho{ 187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // Parsing not supported. 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho pos.setErrorIndex(pos.getIndex()); 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoU_NAMESPACE_END 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#endif /* #if !UCONFIG_NO_FORMATTING */ 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho//eof 196