• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2018 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 package ohos.global.icu.impl.number.parse;
5 
6 import java.util.ArrayList;
7 import java.util.List;
8 
9 import ohos.global.icu.impl.StringSegment;
10 
11 /**
12  * Composes a number of matchers, running one after another. Matches the input string only if all of the
13  * matchers in the series succeed. Performs greedy matches within the context of the series.
14  *
15  * @author sffc
16  * @hide exposed on OHOS
17  */
18 public class SeriesMatcher implements NumberParseMatcher {
19 
20     protected List<NumberParseMatcher> matchers = null;
21     protected boolean frozen = false;
22 
addMatcher(NumberParseMatcher matcher)23     public void addMatcher(NumberParseMatcher matcher) {
24         assert !frozen;
25         if (matchers == null) {
26             matchers = new ArrayList<NumberParseMatcher>();
27         }
28         matchers.add(matcher);
29     }
30 
freeze()31     public void freeze() {
32         frozen = true;
33     }
34 
length()35     public int length() {
36         return matchers == null ? 0 : matchers.size();
37     }
38 
39     @Override
match(StringSegment segment, ParsedNumber result)40     public boolean match(StringSegment segment, ParsedNumber result) {
41         assert frozen;
42         if (matchers == null) {
43             return false;
44         }
45 
46         // TODO: Give a nice way to reset ParsedNumber to avoid the copy here.
47         ParsedNumber backup = new ParsedNumber();
48         backup.copyFrom(result);
49 
50         int initialOffset = segment.getOffset();
51         boolean maybeMore = true;
52         for (int i = 0; i < matchers.size();) {
53             NumberParseMatcher matcher = matchers.get(i);
54             int matcherOffset = segment.getOffset();
55             if (segment.length() != 0) {
56                 maybeMore = matcher.match(segment, result);
57             } else {
58                 // Nothing for this matcher to match; ask for more.
59                 maybeMore = true;
60             }
61 
62             boolean success = (segment.getOffset() != matcherOffset);
63             boolean isFlexible = matcher instanceof NumberParseMatcher.Flexible;
64             if (success && isFlexible) {
65                 // Match succeeded, and this is a flexible matcher. Re-run it.
66             } else if (success) {
67                 // Match succeeded, and this is NOT a flexible matcher. Proceed to the next matcher.
68                 i++;
69                 // Small hack: if there is another matcher coming, do not accept trailing weak chars.
70                 // Needed for proper handling of currency spacing.
71                 if (i < matchers.size() && segment.getOffset() != result.charEnd && result.charEnd > matcherOffset) {
72                     segment.setOffset(result.charEnd);
73                 }
74             } else if (isFlexible) {
75                 // Match failed, and this is a flexible matcher. Try again with the next matcher.
76                 i++;
77             } else {
78                 // Match failed, and this is NOT a flexible matcher. Exit.
79                 segment.setOffset(initialOffset);
80                 result.copyFrom(backup);
81                 return maybeMore;
82             }
83         }
84 
85         // All matchers in the series succeeded.
86         return maybeMore;
87     }
88 
89     @Override
smokeTest(StringSegment segment)90     public boolean smokeTest(StringSegment segment) {
91         assert frozen;
92         if (matchers == null) {
93             return false;
94         }
95 
96         // SeriesMatchers are never allowed to start with a Flexible matcher.
97         assert !(matchers.get(0) instanceof NumberParseMatcher.Flexible);
98         return matchers.get(0).smokeTest(segment);
99     }
100 
101     @Override
postProcess(ParsedNumber result)102     public void postProcess(ParsedNumber result) {
103         assert frozen;
104         if (matchers == null) {
105             return;
106         }
107 
108         for (int i = 0; i < matchers.size(); i++) {
109             NumberParseMatcher matcher = matchers.get(i);
110             matcher.postProcess(result);
111         }
112     }
113 
114     @Override
toString()115     public String toString() {
116         return "<SeriesMatcher " + matchers + ">";
117     }
118 
119 }
120