1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/selfmt.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,195 @@ 1.4 +/******************************************************************** 1.5 + * COPYRIGHT: 1.6 + * Copyright (c) 1997-2012, International Business Machines Corporation and 1.7 + * others. All Rights Reserved. 1.8 + * Copyright (C) 2010 , Yahoo! Inc. 1.9 + ******************************************************************** 1.10 + * 1.11 + * File SELFMT.CPP 1.12 + * 1.13 + * Modification History: 1.14 + * 1.15 + * Date Name Description 1.16 + * 11/11/09 kirtig Finished first cut of implementation. 1.17 + * 11/16/09 kirtig Improved version 1.18 + ********************************************************************/ 1.19 + 1.20 +#include "utypeinfo.h" // for 'typeid' to work 1.21 + 1.22 +#include "unicode/messagepattern.h" 1.23 +#include "unicode/rbnf.h" 1.24 +#include "unicode/selfmt.h" 1.25 +#include "unicode/uchar.h" 1.26 +#include "unicode/ucnv_err.h" 1.27 +#include "unicode/umsg.h" 1.28 +#include "unicode/ustring.h" 1.29 +#include "unicode/utypes.h" 1.30 +#include "cmemory.h" 1.31 +#include "messageimpl.h" 1.32 +#include "patternprops.h" 1.33 +#include "selfmtimpl.h" 1.34 +#include "uassert.h" 1.35 +#include "ustrfmt.h" 1.36 +#include "util.h" 1.37 +#include "uvector.h" 1.38 + 1.39 +#if !UCONFIG_NO_FORMATTING 1.40 + 1.41 +U_NAMESPACE_BEGIN 1.42 + 1.43 +UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SelectFormat) 1.44 + 1.45 +static const UChar SELECT_KEYWORD_OTHER[] = {LOW_O, LOW_T, LOW_H, LOW_E, LOW_R, 0}; 1.46 + 1.47 +SelectFormat::SelectFormat(const UnicodeString& pat, 1.48 + UErrorCode& status) : msgPattern(status) { 1.49 + applyPattern(pat, status); 1.50 +} 1.51 + 1.52 +SelectFormat::SelectFormat(const SelectFormat& other) : Format(other), 1.53 + msgPattern(other.msgPattern) { 1.54 +} 1.55 + 1.56 +SelectFormat::~SelectFormat() { 1.57 +} 1.58 + 1.59 +void 1.60 +SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) { 1.61 + if (U_FAILURE(status)) { 1.62 + return; 1.63 + } 1.64 + 1.65 + msgPattern.parseSelectStyle(newPattern, NULL, status); 1.66 + if (U_FAILURE(status)) { 1.67 + msgPattern.clear(); 1.68 + } 1.69 +} 1.70 + 1.71 +UnicodeString& 1.72 +SelectFormat::format(const Formattable& obj, 1.73 + UnicodeString& appendTo, 1.74 + FieldPosition& pos, 1.75 + UErrorCode& status) const 1.76 +{ 1.77 + if (U_FAILURE(status)) { 1.78 + return appendTo; 1.79 + } 1.80 + if (obj.getType() == Formattable::kString) { 1.81 + return format(obj.getString(status), appendTo, pos, status); 1.82 + } else { 1.83 + status = U_ILLEGAL_ARGUMENT_ERROR; 1.84 + return appendTo; 1.85 + } 1.86 +} 1.87 + 1.88 +UnicodeString& 1.89 +SelectFormat::format(const UnicodeString& keyword, 1.90 + UnicodeString& appendTo, 1.91 + FieldPosition& /*pos */, 1.92 + UErrorCode& status) const { 1.93 + if (U_FAILURE(status)) { 1.94 + return appendTo; 1.95 + } 1.96 + // Check for the validity of the keyword 1.97 + if (!PatternProps::isIdentifier(keyword.getBuffer(), keyword.length())) { 1.98 + status = U_ILLEGAL_ARGUMENT_ERROR; // Invalid formatting argument. 1.99 + } 1.100 + if (msgPattern.countParts() == 0) { 1.101 + status = U_INVALID_STATE_ERROR; 1.102 + return appendTo; 1.103 + } 1.104 + int32_t msgStart = findSubMessage(msgPattern, 0, keyword, status); 1.105 + if (!MessageImpl::jdkAposMode(msgPattern)) { 1.106 + int32_t patternStart = msgPattern.getPart(msgStart).getLimit(); 1.107 + int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart); 1.108 + appendTo.append(msgPattern.getPatternString(), 1.109 + patternStart, 1.110 + msgPattern.getPatternIndex(msgLimit) - patternStart); 1.111 + return appendTo; 1.112 + } 1.113 + // JDK compatibility mode: Remove SKIP_SYNTAX. 1.114 + return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo); 1.115 +} 1.116 + 1.117 +UnicodeString& 1.118 +SelectFormat::toPattern(UnicodeString& appendTo) { 1.119 + if (0 == msgPattern.countParts()) { 1.120 + appendTo.setToBogus(); 1.121 + } else { 1.122 + appendTo.append(msgPattern.getPatternString()); 1.123 + } 1.124 + return appendTo; 1.125 +} 1.126 + 1.127 + 1.128 +int32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t partIndex, 1.129 + const UnicodeString& keyword, UErrorCode& ec) { 1.130 + if (U_FAILURE(ec)) { 1.131 + return 0; 1.132 + } 1.133 + UnicodeString other(FALSE, SELECT_KEYWORD_OTHER, 5); 1.134 + int32_t count = pattern.countParts(); 1.135 + int32_t msgStart=0; 1.136 + // Iterate over (ARG_SELECTOR, message) pairs until ARG_LIMIT or end of select-only pattern. 1.137 + do { 1.138 + const MessagePattern::Part& part=pattern.getPart(partIndex++); 1.139 + const UMessagePatternPartType type=part.getType(); 1.140 + if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) { 1.141 + break; 1.142 + } 1.143 + // part is an ARG_SELECTOR followed by a message 1.144 + if(pattern.partSubstringMatches(part, keyword)) { 1.145 + // keyword matches 1.146 + return partIndex; 1.147 + } else if(msgStart==0 && pattern.partSubstringMatches(part, other)) { 1.148 + msgStart=partIndex; 1.149 + } 1.150 + partIndex=pattern.getLimitPartIndex(partIndex); 1.151 + } while(++partIndex<count); 1.152 + return msgStart; 1.153 +} 1.154 + 1.155 +Format* SelectFormat::clone() const 1.156 +{ 1.157 + return new SelectFormat(*this); 1.158 +} 1.159 + 1.160 +SelectFormat& 1.161 +SelectFormat::operator=(const SelectFormat& other) { 1.162 + if (this != &other) { 1.163 + msgPattern = other.msgPattern; 1.164 + } 1.165 + return *this; 1.166 +} 1.167 + 1.168 +UBool 1.169 +SelectFormat::operator==(const Format& other) const { 1.170 + if (this == &other) { 1.171 + return TRUE; 1.172 + } 1.173 + if (!Format::operator==(other)) { 1.174 + return FALSE; 1.175 + } 1.176 + const SelectFormat& o = (const SelectFormat&)other; 1.177 + return msgPattern == o.msgPattern; 1.178 +} 1.179 + 1.180 +UBool 1.181 +SelectFormat::operator!=(const Format& other) const { 1.182 + return !operator==(other); 1.183 +} 1.184 + 1.185 +void 1.186 +SelectFormat::parseObject(const UnicodeString& /*source*/, 1.187 + Formattable& /*result*/, 1.188 + ParsePosition& pos) const 1.189 +{ 1.190 + // Parsing not supported. 1.191 + pos.setErrorIndex(pos.getIndex()); 1.192 +} 1.193 + 1.194 +U_NAMESPACE_END 1.195 + 1.196 +#endif /* #if !UCONFIG_NO_FORMATTING */ 1.197 + 1.198 +//eof