185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho/*
285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
3b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho* Copyright (C) 2009-2011, International Business Machines Corporation and
485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* others. All Rights Reserved.
585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* File PLURFMT.CPP
885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho* Modification History:
1085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*
1185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*   Date        Name        Description
1285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*******************************************************************************
1385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho*/
1485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
15b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/messagepattern.h"
1685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/plurfmt.h"
1785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "unicode/plurrule.h"
18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h"
19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cmemory.h"
20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "messageimpl.h"
2185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#include "plurrule_impl.h"
22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h"
23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uhash.h"
2485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#if !UCONFIG_NO_FORMATTING
2685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
2785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_BEGIN
2885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehostatic const UChar OTHER_STRING[] = {
30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    0x6F, 0x74, 0x68, 0x65, 0x72, 0  // "other"
31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho};
3285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
3385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUOBJECT_DEFINE_RTTI_IMPLEMENTATION(PluralFormat)
3485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
35b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(UErrorCode& status)
36b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(Locale::getDefault()),
37b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
38b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
39b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
40b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(NULL, status);
4185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
4285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
43b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const Locale& loc, UErrorCode& status)
44b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(loc),
45b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
46b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
47b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
48b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(NULL, status);
4985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
5085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
51b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const PluralRules& rules, UErrorCode& status)
52b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(Locale::getDefault()),
53b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
54b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
55b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
56b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(&rules, status);
5785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
5885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
59b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const Locale& loc,
60b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           const PluralRules& rules,
61b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UErrorCode& status)
62b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(loc),
63b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
64b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
65b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
66b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(&rules, status);
6785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
6885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
69b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const UnicodeString& pat,
70b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UErrorCode& status)
71b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(Locale::getDefault()),
72b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
73b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
74b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
75b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(NULL, status);
7685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    applyPattern(pat, status);
7785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
7885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
79b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const Locale& loc,
80b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           const UnicodeString& pat,
81b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UErrorCode& status)
82b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(loc),
83b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
84b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
85b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
86b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(NULL, status);
8785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    applyPattern(pat, status);
8885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
8985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
90b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const PluralRules& rules,
91b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           const UnicodeString& pat,
92b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UErrorCode& status)
93b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(Locale::getDefault()),
94b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
95b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
96b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
97b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(&rules, status);
9885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    applyPattern(pat, status);
9985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
10085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const Locale& loc,
102b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           const PluralRules& rules,
103b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           const UnicodeString& pat,
104b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                           UErrorCode& status)
105b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : locale(loc),
106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(status),
107b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
108b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(0) {
109b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(&rules, status);
11085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    applyPattern(pat, status);
11185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
11285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
113b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralFormat(const PluralFormat& other)
114b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        : Format(other),
115b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          locale(other.locale),
116b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          msgPattern(other.msgPattern),
117b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          numberFormat(NULL),
118b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho          offset(other.offset) {
119b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    copyObjects(other);
120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
121b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
122b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid
123b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::copyObjects(const PluralFormat& other) {
12485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UErrorCode status = U_ZERO_ERROR;
125b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (numberFormat != NULL) {
126b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete numberFormat;
12785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
128b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (pluralRulesWrapper.pluralRules != NULL) {
129b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        delete pluralRulesWrapper.pluralRules;
130b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
131b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
132b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (other.numberFormat == NULL) {
133b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        numberFormat = NumberFormat::createInstance(locale, status);
134b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
135b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        numberFormat = (NumberFormat*)other.numberFormat->clone();
136b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
137b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (other.pluralRulesWrapper.pluralRules == NULL) {
138b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pluralRulesWrapper.pluralRules = PluralRules::forLocale(locale, status);
139b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
140b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pluralRulesWrapper.pluralRules = other.pluralRulesWrapper.pluralRules->clone();
14185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
14285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
14385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
144b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
14585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::~PluralFormat() {
14685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    delete numberFormat;
14785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
14885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
14985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
150b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::init(const PluralRules* rules, UErrorCode& status) {
15185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
15285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
15385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
154b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
155b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (rules==NULL) {
156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pluralRulesWrapper.pluralRules = PluralRules::forLocale(locale, status);
157b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
158b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        pluralRulesWrapper.pluralRules = rules->clone();
159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (pluralRulesWrapper.pluralRules == NULL) {
160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            status = U_MEMORY_ALLOCATION_ERROR;
16185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            return;
16285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
16385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
164b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
165b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    numberFormat= NumberFormat::createInstance(locale, status);
16685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
16785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
16885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
16985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::applyPattern(const UnicodeString& newPattern, UErrorCode& status) {
170b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    msgPattern.parsePluralStyle(newPattern, NULL, status);
17185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
172b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        msgPattern.clear();
173b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        offset = 0;
17485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
17585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
176b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    offset = msgPattern.getPluralOffset(0);
17785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
17885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
17985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString&
18085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::format(const Formattable& obj,
18185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   UnicodeString& appendTo,
18285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   FieldPosition& pos,
18385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                   UErrorCode& status) const
18485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
18585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) return appendTo;
186b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
187b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (obj.isNumeric()) {
188b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return format(obj.getDouble(), appendTo, pos, status);
189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
19085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        status = U_ILLEGAL_ARGUMENT_ERROR;
19185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return appendTo;
19285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
19385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
19485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
19585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString
19685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::format(int32_t number, UErrorCode& status) const {
19785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FieldPosition fpos(0);
19885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString result;
19985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return format(number, result, fpos, status);
20085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
20185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
20285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString
20385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::format(double number, UErrorCode& status) const {
20485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    FieldPosition fpos(0);
20585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    UnicodeString result;
20685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return format(number, result, fpos, status);
20785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
20885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
20985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
21085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString&
21185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::format(int32_t number,
212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString& appendTo,
21385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                     FieldPosition& pos,
21485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                     UErrorCode& status) const {
21585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return format((double)number, appendTo, pos, status);
21685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
21785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
21885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString&
21985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::format(double number,
220b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UnicodeString& appendTo,
22185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                     FieldPosition& pos,
222b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                     UErrorCode& status) const {
223b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(status)) {
224b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return appendTo;
22585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
226b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (msgPattern.countParts() == 0) {
227b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return numberFormat->format(number, appendTo, pos);
228b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
229b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Get the appropriate sub-message.
230b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t partIndex = findSubMessage(msgPattern, 0, pluralRulesWrapper, number, status);
231b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Replace syntactic # signs in the top level of this sub-message
232b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // (not in nested arguments) with the formatted number-offset.
233b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const UnicodeString& pattern = msgPattern.getPatternString();
234b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    number -= offset;
235b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t prevIndex = msgPattern.getPart(partIndex).getLimit();
236b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    for (;;) {
237b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const MessagePattern::Part& part = msgPattern.getPart(++partIndex);
238b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UMessagePatternPartType type = part.getType();
239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        int32_t index = part.getIndex();
240b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if (type == UMSGPAT_PART_TYPE_MSG_LIMIT) {
241b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            return appendTo.append(pattern, prevIndex, index - prevIndex);
242b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if ((type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) ||
243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            (type == UMSGPAT_PART_TYPE_SKIP_SYNTAX && MessageImpl::jdkAposMode(msgPattern))) {
244b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            appendTo.append(pattern, prevIndex, index - prevIndex);
245b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if (type == UMSGPAT_PART_TYPE_REPLACE_NUMBER) {
246b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                numberFormat->format(number, appendTo);
247b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
248b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            prevIndex = part.getLimit();
249b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if (type == UMSGPAT_PART_TYPE_ARG_START) {
250b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            appendTo.append(pattern, prevIndex, index - prevIndex);
251b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            prevIndex = index;
252b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            partIndex = msgPattern.getLimitPartIndex(partIndex);
253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            index = msgPattern.getPart(partIndex).getLimit();
254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            MessageImpl::appendReducedApostrophes(pattern, prevIndex, index, appendTo);
255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            prevIndex = index;
256b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
25785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
25885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
25985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
26085bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUnicodeString&
26185bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::toPattern(UnicodeString& appendTo) {
262b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (0 == msgPattern.countParts()) {
263b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        appendTo.setToBogus();
264b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
265b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        appendTo.append(msgPattern.getPatternString());
26685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
267b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return appendTo;
26885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
26985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
270b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid
271b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::setLocale(const Locale& loc, UErrorCode& status) {
272b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(status)) {
273b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return;
27485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    locale = loc;
276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    msgPattern.clear();
277b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete numberFormat;
278b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    offset = 0;
279b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    numberFormat = NULL;
280b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pluralRulesWrapper.reset();
281b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    init(NULL, status);
28285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
28385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
28485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
285b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::setNumberFormat(const NumberFormat* format, UErrorCode& status) {
28685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (U_FAILURE(status)) {
28785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        return;
28885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
289b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    NumberFormat* nf = (NumberFormat*)format->clone();
290b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (nf != NULL) {
29185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        delete numberFormat;
292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        numberFormat = nf;
293b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
294b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        status = U_MEMORY_ALLOCATION_ERROR;
29585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
29685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
29785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
29885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoFormat*
29985bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::clone() const
30085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
30185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return new PluralFormat(*this);
30285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
30385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
304b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
30585bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat&
30685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::operator=(const PluralFormat& other) {
30785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    if (this != &other) {
30885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        locale = other.locale;
309b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        msgPattern = other.msgPattern;
310b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        offset = other.offset;
311b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        copyObjects(other);
31285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    }
31385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
31485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return *this;
31585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
31685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
31785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
31885bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::operator==(const Format& other) const {
319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (this == &other) {
320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return TRUE;
321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (!Format::operator==(other)) {
323b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return FALSE;
324b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
325b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const PluralFormat& o = (const PluralFormat&)other;
326b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return
327b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        locale == o.locale &&
328b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        msgPattern == o.msgPattern &&  // implies same offset
329b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (numberFormat == NULL) == (o.numberFormat == NULL) &&
330b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (numberFormat == NULL || *numberFormat == *o.numberFormat) &&
331b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (pluralRulesWrapper.pluralRules == NULL) == (o.pluralRulesWrapper.pluralRules == NULL) &&
332b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        (pluralRulesWrapper.pluralRules == NULL ||
333b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            *pluralRulesWrapper.pluralRules == *o.pluralRulesWrapper.pluralRules);
33485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
33585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
33685bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoUBool
33785bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::operator!=(const Format& other) const {
33885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    return  !operator==(other);
33985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
34085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
34185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Hovoid
34285bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoPluralFormat::parseObject(const UnicodeString& /*source*/,
34385bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho                        Formattable& /*result*/,
344b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        ParsePosition& pos) const
34585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho{
346b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Parsing not supported.
347b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pos.setErrorIndex(pos.getIndex());
34885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
34985bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
350b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoint32_t PluralFormat::findSubMessage(const MessagePattern& pattern, int32_t partIndex,
351b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                     const PluralSelector& selector, double number, UErrorCode& ec) {
352b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(ec)) {
353b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return 0;
354b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
355b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t count=pattern.countParts();
356b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    double offset;
357b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    const MessagePattern::Part* part=&pattern.getPart(partIndex);
358b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (MessagePattern::Part::hasNumericValue(part->getType())) {
359b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        offset=pattern.getNumericValue(*part);
360b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        ++partIndex;
361b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } else {
362b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        offset=0;
363b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
364b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // The keyword is empty until we need to match against non-explicit, not-"other" value.
365b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Then we get the keyword from the selector.
366b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // (In other words, we never call the selector if we match against an explicit value,
367b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // or if the only non-explicit keyword is "other".)
368b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString keyword;
369b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UnicodeString other(FALSE, OTHER_STRING, 5);
370b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // When we find a match, we set msgStart>0 and also set this boolean to true
371b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // to avoid matching the keyword again (duplicates are allowed)
372b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // while we continue to look for an explicit-value match.
373b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    UBool haveKeywordMatch=FALSE;
374b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // msgStart is 0 until we find any appropriate sub-message.
375b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // We remember the first "other" sub-message if we have not seen any
376b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // appropriate sub-message before.
377b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // We remember the first matching-keyword sub-message if we have not seen
378b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // one of those before.
379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // (The parser allows [does not check for] duplicate keywords.
380b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // We just have to make sure to take the first one.)
381b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // We avoid matching the keyword twice by also setting haveKeywordMatch=true
382b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // at the first keyword match.
383b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // We keep going until we find an explicit-value match or reach the end of the plural style.
384b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    int32_t msgStart=0;
385b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // Iterate over (ARG_SELECTOR [ARG_INT|ARG_DOUBLE] message) tuples
386b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    // until ARG_LIMIT or end of plural-only pattern.
387b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    do {
388b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        part=&pattern.getPart(partIndex++);
389b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        const UMessagePatternPartType type = part->getType();
390b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(type==UMSGPAT_PART_TYPE_ARG_LIMIT) {
39185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            break;
392b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        }
393b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        U_ASSERT (type==UMSGPAT_PART_TYPE_ARG_SELECTOR);
394b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        // part is an ARG_SELECTOR followed by an optional explicit value, and then a message
395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        if(MessagePattern::Part::hasNumericValue(pattern.getPartType(partIndex))) {
396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // explicit value like "=2"
397b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            part=&pattern.getPart(partIndex++);
398b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(number==pattern.getNumericValue(*part)) {
399b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                // matches explicit value
400b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                return partIndex;
401b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            }
402b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        } else if(!haveKeywordMatch) {
403b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // plural keyword like "few" or "other"
404b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            // Compare "other" first and call the selector if this is not "other".
405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            if(pattern.partSubstringMatches(*part, other)) {
406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(msgStart==0) {
407b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    msgStart=partIndex;
408b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if(0 == keyword.compare(other)) {
409b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // This is the first "other" sub-message,
410b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // and the selected keyword is also "other".
411b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // Do not match "other" again.
412b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        haveKeywordMatch=TRUE;
413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
414b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
415b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho            } else {
416b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(keyword.isEmpty()) {
417b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    keyword=selector.select(number-offset, ec);
418b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    if(msgStart!=0 && (0 == keyword.compare(other))) {
419b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // We have already seen an "other" sub-message.
420b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // Do not match "other" again.
421b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        haveKeywordMatch=TRUE;
422b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                        // Skip keyword matching but do getLimitPartIndex().
423b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    }
424b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
425b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                if(!haveKeywordMatch && pattern.partSubstringMatches(*part, keyword)) {
426b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // keyword matches
427b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    msgStart=partIndex;
428b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    // Do not match this keyword again.
429b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                    haveKeywordMatch=TRUE;
430b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                }
43185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho            }
43285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        }
433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        partIndex=pattern.getLimitPartIndex(partIndex);
434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    } while(++partIndex<count);
435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return msgStart;
43685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
43785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
438b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoPluralFormat::PluralSelectorAdapter::~PluralSelectorAdapter() {
439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete pluralRules;
440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
441b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
442b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoUnicodeString PluralFormat::PluralSelectorAdapter::select(double number,
443b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho                                                          UErrorCode& /*ec*/) const {
444b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    return pluralRules->select(number);
445b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho}
446b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho
447b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehovoid PluralFormat::PluralSelectorAdapter::reset() {
448b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    delete pluralRules;
449b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    pluralRules = NULL;
45085bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho}
45185bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45285bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45385bf2e2fbc60a9f938064abc8127d61da7d19882Claire HoU_NAMESPACE_END
45485bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45585bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho#endif /* #if !UCONFIG_NO_FORMATTING */
45785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
45885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho//eof
459