]>
git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/numparse_symbols.cpp
1 // © 2018 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 #include "unicode/utypes.h"
6 #if !UCONFIG_NO_FORMATTING
8 // Allow implicit conversion from char16_t* to UnicodeString for this file:
9 // Helpful in toString methods and elsewhere.
10 #define UNISTR_FROM_STRING_EXPLICIT
12 #include "numparse_types.h"
13 #include "numparse_symbols.h"
14 #include "numparse_utils.h"
17 using namespace icu::numparse
;
18 using namespace icu::numparse::impl
;
21 SymbolMatcher::SymbolMatcher(const UnicodeString
& symbolString
, unisets::Key key
) {
22 fUniSet
= unisets::get(key
);
23 if (fUniSet
->contains(symbolString
)) {
26 fString
= symbolString
;
30 const UnicodeSet
* SymbolMatcher::getSet() const {
34 bool SymbolMatcher::match(StringSegment
& segment
, ParsedNumber
& result
, UErrorCode
&) const {
35 // Smoke test first; this matcher might be disabled.
36 if (isDisabled(result
)) {
40 // Test the string first in order to consume trailing chars greedily.
42 if (!fString
.isEmpty()) {
43 overlap
= segment
.getCommonPrefixLength(fString
);
44 if (overlap
== fString
.length()) {
45 segment
.adjustOffset(fString
.length());
46 accept(segment
, result
);
51 int cp
= segment
.getCodePoint();
52 if (cp
!= -1 && fUniSet
->contains(cp
)) {
53 segment
.adjustOffset(U16_LENGTH(cp
));
54 accept(segment
, result
);
58 return overlap
== segment
.length();
61 bool SymbolMatcher::smokeTest(const StringSegment
& segment
) const {
62 return segment
.startsWith(*fUniSet
) || segment
.startsWith(fString
);
65 UnicodeString
SymbolMatcher::toString() const {
66 // TODO: Customize output for each symbol
71 IgnorablesMatcher::IgnorablesMatcher(unisets::Key key
)
72 : SymbolMatcher({}, key
) {
75 bool IgnorablesMatcher::isFlexible() const {
79 UnicodeString
IgnorablesMatcher::toString() const {
80 return u
"<Ignorables>";
83 bool IgnorablesMatcher::isDisabled(const ParsedNumber
&) const {
87 void IgnorablesMatcher::accept(StringSegment
&, ParsedNumber
&) const {
92 InfinityMatcher::InfinityMatcher(const DecimalFormatSymbols
& dfs
)
93 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kInfinitySymbol
), unisets::INFINITY_SIGN
) {
96 bool InfinityMatcher::isDisabled(const ParsedNumber
& result
) const {
97 return 0 != (result
.flags
& FLAG_INFINITY
);
100 void InfinityMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
101 result
.flags
|= FLAG_INFINITY
;
102 result
.setCharsConsumed(segment
);
106 MinusSignMatcher::MinusSignMatcher(const DecimalFormatSymbols
& dfs
, bool allowTrailing
)
107 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kMinusSignSymbol
), unisets::MINUS_SIGN
),
108 fAllowTrailing(allowTrailing
) {
111 bool MinusSignMatcher::isDisabled(const ParsedNumber
& result
) const {
112 return !fAllowTrailing
&& result
.seenNumber();
115 void MinusSignMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
116 result
.flags
|= FLAG_NEGATIVE
;
117 result
.setCharsConsumed(segment
);
121 NanMatcher::NanMatcher(const DecimalFormatSymbols
& dfs
)
122 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kNaNSymbol
), unisets::EMPTY
) {
125 bool NanMatcher::isDisabled(const ParsedNumber
& result
) const {
126 return result
.seenNumber();
129 void NanMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
130 result
.flags
|= FLAG_NAN
;
131 result
.setCharsConsumed(segment
);
135 PaddingMatcher::PaddingMatcher(const UnicodeString
& padString
)
136 : SymbolMatcher(padString
, unisets::EMPTY
) {}
138 bool PaddingMatcher::isFlexible() const {
142 bool PaddingMatcher::isDisabled(const ParsedNumber
&) const {
146 void PaddingMatcher::accept(StringSegment
&, ParsedNumber
&) const {
151 PercentMatcher::PercentMatcher(const DecimalFormatSymbols
& dfs
)
152 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kPercentSymbol
), unisets::PERCENT_SIGN
) {
155 bool PercentMatcher::isDisabled(const ParsedNumber
& result
) const {
156 return 0 != (result
.flags
& FLAG_PERCENT
);
159 void PercentMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
160 result
.flags
|= FLAG_PERCENT
;
161 result
.setCharsConsumed(segment
);
165 PermilleMatcher::PermilleMatcher(const DecimalFormatSymbols
& dfs
)
166 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kPerMillSymbol
), unisets::PERMILLE_SIGN
) {
169 bool PermilleMatcher::isDisabled(const ParsedNumber
& result
) const {
170 return 0 != (result
.flags
& FLAG_PERMILLE
);
173 void PermilleMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
174 result
.flags
|= FLAG_PERMILLE
;
175 result
.setCharsConsumed(segment
);
179 PlusSignMatcher::PlusSignMatcher(const DecimalFormatSymbols
& dfs
, bool allowTrailing
)
180 : SymbolMatcher(dfs
.getConstSymbol(DecimalFormatSymbols::kPlusSignSymbol
), unisets::PLUS_SIGN
),
181 fAllowTrailing(allowTrailing
) {
184 bool PlusSignMatcher::isDisabled(const ParsedNumber
& result
) const {
185 return !fAllowTrailing
&& result
.seenNumber();
188 void PlusSignMatcher::accept(StringSegment
& segment
, ParsedNumber
& result
) const {
189 result
.setCharsConsumed(segment
);
193 #endif /* #if !UCONFIG_NO_FORMATTING */