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