1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2015, International Business Machines Corporation
6 * and others. All Rights Reserved.
7 *******************************************************************************
8 * standardplural.cpp
9 *
10 * created on: 2015dec14
11 * created by: Markus W. Scherer
12 */
13
14 #include "unicode/utypes.h"
15
16 #if !UCONFIG_NO_FORMATTING
17
18 #include "unicode/unistr.h"
19 #include "cstring.h"
20 #include "standardplural.h"
21 #include "uassert.h"
22
23 U_NAMESPACE_BEGIN
24
25 static const char *gKeywords[StandardPlural::COUNT] = {
26 "zero", "one", "two", "few", "many", "other", "=0", "=1"
27 };
28
getKeyword(Form p)29 const char *StandardPlural::getKeyword(Form p) {
30 U_ASSERT(ZERO <= p && p < COUNT);
31 return gKeywords[p];
32 }
33
indexOrNegativeFromString(const char * keyword)34 int32_t StandardPlural::indexOrNegativeFromString(const char *keyword) {
35 switch (*keyword++) {
36 case 'f':
37 if (uprv_strcmp(keyword, "ew") == 0) {
38 return FEW;
39 }
40 break;
41 case 'm':
42 if (uprv_strcmp(keyword, "any") == 0) {
43 return MANY;
44 }
45 break;
46 case 'o':
47 if (uprv_strcmp(keyword, "ther") == 0) {
48 return OTHER;
49 } else if (uprv_strcmp(keyword, "ne") == 0) {
50 return ONE;
51 }
52 break;
53 case 't':
54 if (uprv_strcmp(keyword, "wo") == 0) {
55 return TWO;
56 }
57 break;
58 case 'z':
59 if (uprv_strcmp(keyword, "ero") == 0) {
60 return ZERO;
61 }
62 break;
63 case '=':
64 if (uprv_strcmp(keyword, "0") == 0) {
65 return EQ_0;
66 } else if (uprv_strcmp(keyword, "1") == 0) {
67 return EQ_1;
68 }
69 break;
70 // Also allow "0" and "1"
71 case '0':
72 if (*keyword == 0) {
73 return EQ_0;
74 }
75 break;
76 case '1':
77 if (*keyword == 0) {
78 return EQ_1;
79 }
80 break;
81 default:
82 break;
83 }
84 return -1;
85 }
86
87 static const UChar gZero[] = u"zero";
88 static const UChar gOne[] = u"one";
89 static const UChar gTwo[] = u"two";
90 static const UChar gFew[] = u"few";
91 static const UChar gMany[] = u"many";
92 static const UChar gOther[] = u"other";
93 static const UChar gEq0[] = u"=0";
94 static const UChar gEq1[] = u"=1";
95
indexOrNegativeFromString(const UnicodeString & keyword)96 int32_t StandardPlural::indexOrNegativeFromString(const UnicodeString &keyword) {
97 switch (keyword.length()) {
98 case 1:
99 if (keyword.charAt(0) == '0') {
100 return EQ_0;
101 } else if (keyword.charAt(0) == '1') {
102 return EQ_1;
103 }
104 break;
105 case 2:
106 if (keyword.compare(gEq0, 2) == 0) {
107 return EQ_0;
108 } else if (keyword.compare(gEq1, 2) == 0) {
109 return EQ_1;
110 }
111 break;
112 case 3:
113 if (keyword.compare(gOne, 3) == 0) {
114 return ONE;
115 } else if (keyword.compare(gTwo, 3) == 0) {
116 return TWO;
117 } else if (keyword.compare(gFew, 3) == 0) {
118 return FEW;
119 }
120 break;
121 case 4:
122 if (keyword.compare(gMany, 4) == 0) {
123 return MANY;
124 } else if (keyword.compare(gZero, 4) == 0) {
125 return ZERO;
126 }
127 break;
128 case 5:
129 if (keyword.compare(gOther, 5) == 0) {
130 return OTHER;
131 }
132 break;
133 default:
134 break;
135 }
136 return -1;
137 }
138
indexFromString(const char * keyword,UErrorCode & errorCode)139 int32_t StandardPlural::indexFromString(const char *keyword, UErrorCode &errorCode) {
140 if (U_FAILURE(errorCode)) { return OTHER; }
141 int32_t i = indexOrNegativeFromString(keyword);
142 if (i >= 0) {
143 return i;
144 } else {
145 errorCode = U_ILLEGAL_ARGUMENT_ERROR;
146 return OTHER;
147 }
148 }
149
indexFromString(const UnicodeString & keyword,UErrorCode & errorCode)150 int32_t StandardPlural::indexFromString(const UnicodeString &keyword, UErrorCode &errorCode) {
151 if (U_FAILURE(errorCode)) { return OTHER; }
152 int32_t i = indexOrNegativeFromString(keyword);
153 if (i >= 0) {
154 return i;
155 } else {
156 errorCode = U_ILLEGAL_ARGUMENT_ERROR;
157 return OTHER;
158 }
159 }
160
161 U_NAMESPACE_END
162
163 #endif // !UCONFIG_NO_FORMATTING
164