intl/icu/source/i18n/selfmt.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /********************************************************************
michael@0 2 * COPYRIGHT:
michael@0 3 * Copyright (c) 1997-2012, International Business Machines Corporation and
michael@0 4 * others. All Rights Reserved.
michael@0 5 * Copyright (C) 2010 , Yahoo! Inc.
michael@0 6 ********************************************************************
michael@0 7 *
michael@0 8 * File SELFMT.CPP
michael@0 9 *
michael@0 10 * Modification History:
michael@0 11 *
michael@0 12 * Date Name Description
michael@0 13 * 11/11/09 kirtig Finished first cut of implementation.
michael@0 14 * 11/16/09 kirtig Improved version
michael@0 15 ********************************************************************/
michael@0 16
michael@0 17 #include "utypeinfo.h" // for 'typeid' to work
michael@0 18
michael@0 19 #include "unicode/messagepattern.h"
michael@0 20 #include "unicode/rbnf.h"
michael@0 21 #include "unicode/selfmt.h"
michael@0 22 #include "unicode/uchar.h"
michael@0 23 #include "unicode/ucnv_err.h"
michael@0 24 #include "unicode/umsg.h"
michael@0 25 #include "unicode/ustring.h"
michael@0 26 #include "unicode/utypes.h"
michael@0 27 #include "cmemory.h"
michael@0 28 #include "messageimpl.h"
michael@0 29 #include "patternprops.h"
michael@0 30 #include "selfmtimpl.h"
michael@0 31 #include "uassert.h"
michael@0 32 #include "ustrfmt.h"
michael@0 33 #include "util.h"
michael@0 34 #include "uvector.h"
michael@0 35
michael@0 36 #if !UCONFIG_NO_FORMATTING
michael@0 37
michael@0 38 U_NAMESPACE_BEGIN
michael@0 39
michael@0 40 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SelectFormat)
michael@0 41
michael@0 42 static const UChar SELECT_KEYWORD_OTHER[] = {LOW_O, LOW_T, LOW_H, LOW_E, LOW_R, 0};
michael@0 43
michael@0 44 SelectFormat::SelectFormat(const UnicodeString& pat,
michael@0 45 UErrorCode& status) : msgPattern(status) {
michael@0 46 applyPattern(pat, status);
michael@0 47 }
michael@0 48
michael@0 49 SelectFormat::SelectFormat(const SelectFormat& other) : Format(other),
michael@0 50 msgPattern(other.msgPattern) {
michael@0 51 }
michael@0 52
michael@0 53 SelectFormat::~SelectFormat() {
michael@0 54 }
michael@0 55
michael@0 56 void
michael@0 57 SelectFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) {
michael@0 58 if (U_FAILURE(status)) {
michael@0 59 return;
michael@0 60 }
michael@0 61
michael@0 62 msgPattern.parseSelectStyle(newPattern, NULL, status);
michael@0 63 if (U_FAILURE(status)) {
michael@0 64 msgPattern.clear();
michael@0 65 }
michael@0 66 }
michael@0 67
michael@0 68 UnicodeString&
michael@0 69 SelectFormat::format(const Formattable& obj,
michael@0 70 UnicodeString& appendTo,
michael@0 71 FieldPosition& pos,
michael@0 72 UErrorCode& status) const
michael@0 73 {
michael@0 74 if (U_FAILURE(status)) {
michael@0 75 return appendTo;
michael@0 76 }
michael@0 77 if (obj.getType() == Formattable::kString) {
michael@0 78 return format(obj.getString(status), appendTo, pos, status);
michael@0 79 } else {
michael@0 80 status = U_ILLEGAL_ARGUMENT_ERROR;
michael@0 81 return appendTo;
michael@0 82 }
michael@0 83 }
michael@0 84
michael@0 85 UnicodeString&
michael@0 86 SelectFormat::format(const UnicodeString& keyword,
michael@0 87 UnicodeString& appendTo,
michael@0 88 FieldPosition& /*pos */,
michael@0 89 UErrorCode& status) const {
michael@0 90 if (U_FAILURE(status)) {
michael@0 91 return appendTo;
michael@0 92 }
michael@0 93 // Check for the validity of the keyword
michael@0 94 if (!PatternProps::isIdentifier(keyword.getBuffer(), keyword.length())) {
michael@0 95 status = U_ILLEGAL_ARGUMENT_ERROR; // Invalid formatting argument.
michael@0 96 }
michael@0 97 if (msgPattern.countParts() == 0) {
michael@0 98 status = U_INVALID_STATE_ERROR;
michael@0 99 return appendTo;
michael@0 100 }
michael@0 101 int32_t msgStart = findSubMessage(msgPattern, 0, keyword, status);
michael@0 102 if (!MessageImpl::jdkAposMode(msgPattern)) {
michael@0 103 int32_t patternStart = msgPattern.getPart(msgStart).getLimit();
michael@0 104 int32_t msgLimit = msgPattern.getLimitPartIndex(msgStart);
michael@0 105 appendTo.append(msgPattern.getPatternString(),
michael@0 106 patternStart,
michael@0 107 msgPattern.getPatternIndex(msgLimit) - patternStart);
michael@0 108 return appendTo;
michael@0 109 }
michael@0 110 // JDK compatibility mode: Remove SKIP_SYNTAX.
michael@0 111 return MessageImpl::appendSubMessageWithoutSkipSyntax(msgPattern, msgStart, appendTo);
michael@0 112 }
michael@0 113
michael@0 114 UnicodeString&
michael@0 115 SelectFormat::toPattern(UnicodeString& appendTo) {
michael@0 116 if (0 == msgPattern.countParts()) {
michael@0 117 appendTo.setToBogus();
michael@0 118 } else {
michael@0 119 appendTo.append(msgPattern.getPatternString());
michael@0 120 }
michael@0 121 return appendTo;
michael@0 122 }
michael@0 123
michael@0 124
michael@0 125 int32_t SelectFormat::findSubMessage(const MessagePattern& pattern, int32_t partIndex,
michael@0 126 const UnicodeString& keyword, UErrorCode& ec) {
michael@0 127 if (U_FAILURE(ec)) {
michael@0 128 return 0;
michael@0 129 }
michael@0 130 UnicodeString other(FALSE, SELECT_KEYWORD_OTHER, 5);
michael@0 131 int32_t count = pattern.countParts();
michael@0 132 int32_t msgStart=0;
michael@0 133 // Iterate over (ARG_SELECTOR, message) pairs until ARG_LIMIT or end of select-only pattern.
michael@0 134 do {
michael@0 135 const MessagePattern::Part& part=pattern.getPart(partIndex++);
michael@0 136 const UMessagePatternPartType type=part.getType();
michael@0 137 if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) {
michael@0 138 break;
michael@0 139 }
michael@0 140 // part is an ARG_SELECTOR followed by a message
michael@0 141 if(pattern.partSubstringMatches(part, keyword)) {
michael@0 142 // keyword matches
michael@0 143 return partIndex;
michael@0 144 } else if(msgStart==0 && pattern.partSubstringMatches(part, other)) {
michael@0 145 msgStart=partIndex;
michael@0 146 }
michael@0 147 partIndex=pattern.getLimitPartIndex(partIndex);
michael@0 148 } while(++partIndex<count);
michael@0 149 return msgStart;
michael@0 150 }
michael@0 151
michael@0 152 Format* SelectFormat::clone() const
michael@0 153 {
michael@0 154 return new SelectFormat(*this);
michael@0 155 }
michael@0 156
michael@0 157 SelectFormat&
michael@0 158 SelectFormat::operator=(const SelectFormat& other) {
michael@0 159 if (this != &other) {
michael@0 160 msgPattern = other.msgPattern;
michael@0 161 }
michael@0 162 return *this;
michael@0 163 }
michael@0 164
michael@0 165 UBool
michael@0 166 SelectFormat::operator==(const Format& other) const {
michael@0 167 if (this == &other) {
michael@0 168 return TRUE;
michael@0 169 }
michael@0 170 if (!Format::operator==(other)) {
michael@0 171 return FALSE;
michael@0 172 }
michael@0 173 const SelectFormat& o = (const SelectFormat&)other;
michael@0 174 return msgPattern == o.msgPattern;
michael@0 175 }
michael@0 176
michael@0 177 UBool
michael@0 178 SelectFormat::operator!=(const Format& other) const {
michael@0 179 return !operator==(other);
michael@0 180 }
michael@0 181
michael@0 182 void
michael@0 183 SelectFormat::parseObject(const UnicodeString& /*source*/,
michael@0 184 Formattable& /*result*/,
michael@0 185 ParsePosition& pos) const
michael@0 186 {
michael@0 187 // Parsing not supported.
michael@0 188 pos.setErrorIndex(pos.getIndex());
michael@0 189 }
michael@0 190
michael@0 191 U_NAMESPACE_END
michael@0 192
michael@0 193 #endif /* #if !UCONFIG_NO_FORMATTING */
michael@0 194
michael@0 195 //eof

mercurial