1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html#License
3 /*
4  ******************************************************************************
5  * Copyright (C) 2007-2009, International Business Machines Corporation and   *
6  * others. All Rights Reserved.                                               *
7  ******************************************************************************
8  */
9 
10 package com.ibm.icu.impl.duration.impl;
11 
12 import java.util.ArrayList;
13 import java.util.List;
14 
15 /**
16  * DataRecord contains the data used by PeriodFormatterData. Fields are
17  * package-private for ease of access. This is a struct, it knows how to read
18  * and write itself to/from simple XML, that's all.
19  */
20 public class DataRecord {
21     byte pl;
22     String[][] pluralNames;
23     byte[] genders; // EGender
24     String[] singularNames;
25     String[] halfNames;
26     String[] numberNames;
27     String[] mediumNames;
28     String[] shortNames;
29     String[] measures;
30     String[] rqdSuffixes;
31     String[] optSuffixes;
32     String[] halves;
33     byte[] halfPlacements; // EHalfPlacement
34     byte[] halfSupport; // EHalfSupport
35     String fifteenMinutes;
36     String fiveMinutes;
37     boolean requiresDigitSeparator;
38     String digitPrefix;
39     String countSep;
40     String shortUnitSep;
41     String[] unitSep;
42     boolean[] unitSepRequiresDP;
43     boolean[] requiresSkipMarker;
44     byte numberSystem; // ENumberSystem
45     char zero;
46     char decimalSep;
47     boolean omitSingularCount;
48     boolean omitDualCount;
49     byte zeroHandling; // EZeroHandling
50     byte decimalHandling; // EDecimalHandling
51     byte fractionHandling; // EFractionHandling
52     String skippedUnitMarker;
53     boolean allowZero;
54     boolean weeksAloneOnly;
55     byte useMilliseconds; // EMilliSupport
56     ScopeData[] scopeData;
57 
read(String ln, RecordReader in)58     public static DataRecord read(String ln, RecordReader in) {
59         if (in.open("DataRecord")) {
60             DataRecord record = new DataRecord();
61             record.pl = in.namedIndex("pl", EPluralization.names);
62             record.pluralNames = in.stringTable("pluralName");
63             record.genders = in.namedIndexArray("gender", EGender.names);
64             record.singularNames = in.stringArray("singularName");
65             record.halfNames = in.stringArray("halfName");
66             record.numberNames = in.stringArray("numberName");
67             record.mediumNames = in.stringArray("mediumName");
68             record.shortNames = in.stringArray("shortName");
69             record.measures = in.stringArray("measure");
70             record.rqdSuffixes = in.stringArray("rqdSuffix");
71             record.optSuffixes = in.stringArray("optSuffix");
72             record.halves = in.stringArray("halves");
73             record.halfPlacements = in.namedIndexArray("halfPlacement",
74                     EHalfPlacement.names);
75             record.halfSupport = in.namedIndexArray("halfSupport",
76                     EHalfSupport.names);
77             record.fifteenMinutes = in.string("fifteenMinutes");
78             record.fiveMinutes = in.string("fiveMinutes");
79             record.requiresDigitSeparator = in.bool("requiresDigitSeparator");
80             record.digitPrefix = in.string("digitPrefix");
81             record.countSep = in.string("countSep");
82             record.shortUnitSep = in.string("shortUnitSep");
83             record.unitSep = in.stringArray("unitSep");
84             record.unitSepRequiresDP = in.boolArray("unitSepRequiresDP");
85             record.requiresSkipMarker = in.boolArray("requiresSkipMarker");
86             record.numberSystem = in.namedIndex("numberSystem",
87                     ENumberSystem.names);
88             record.zero = in.character("zero");
89             record.decimalSep = in.character("decimalSep");
90             record.omitSingularCount = in.bool("omitSingularCount");
91             record.omitDualCount = in.bool("omitDualCount");
92             record.zeroHandling = in.namedIndex("zeroHandling",
93                     EZeroHandling.names);
94             record.decimalHandling = in.namedIndex("decimalHandling",
95                     EDecimalHandling.names);
96             record.fractionHandling = in.namedIndex("fractionHandling",
97                     EFractionHandling.names);
98             record.skippedUnitMarker = in.string("skippedUnitMarker");
99             record.allowZero = in.bool("allowZero");
100             record.weeksAloneOnly = in.bool("weeksAloneOnly");
101             record.useMilliseconds = in.namedIndex("useMilliseconds",
102                     EMilliSupport.names);
103             if (in.open("ScopeDataList")) {
104                 List<ScopeData> list = new ArrayList<ScopeData>(); // of ScopeData
105                 ScopeData data;
106                 while (null != (data = ScopeData.read(in))) {
107                     list.add(data);
108                 }
109                 if (in.close()) {
110                     record.scopeData = list.toArray(new ScopeData[list.size()]);
111                 }
112             }
113 
114             if (in.close()) {
115                 return record;
116             }
117         } else {
118             throw new InternalError("did not find DataRecord while reading "
119                     + ln);
120         }
121         throw new InternalError("null data read while reading " + ln);
122         // Thread.dumpStack();
123         // return null;
124     }
125 
write(RecordWriter out)126     public void write(RecordWriter out) {
127         out.open("DataRecord");
128         out.namedIndex("pl", EPluralization.names, pl);
129         out.stringTable("pluralName", pluralNames);
130         out.namedIndexArray("gender", EGender.names, genders);
131         out.stringArray("singularName", singularNames);
132         out.stringArray("halfName", halfNames);
133         out.stringArray("numberName", numberNames);
134         out.stringArray("mediumName", mediumNames);
135         out.stringArray("shortName", shortNames);
136         out.stringArray("measure", measures);
137         out.stringArray("rqdSuffix", rqdSuffixes);
138         out.stringArray("optSuffix", optSuffixes);
139         out.stringArray("halves", halves);
140         out.namedIndexArray("halfPlacement", EHalfPlacement.names,
141                 halfPlacements);
142         out.namedIndexArray("halfSupport", EHalfSupport.names, halfSupport);
143         out.string("fifteenMinutes", fifteenMinutes);
144         out.string("fiveMinutes", fiveMinutes);
145         out.bool("requiresDigitSeparator", requiresDigitSeparator);
146         out.string("digitPrefix", digitPrefix);
147         out.string("countSep", countSep);
148         out.string("shortUnitSep", shortUnitSep);
149         out.stringArray("unitSep", unitSep);
150         out.boolArray("unitSepRequiresDP", unitSepRequiresDP);
151         out.boolArray("requiresSkipMarker", requiresSkipMarker);
152         out.namedIndex("numberSystem", ENumberSystem.names, numberSystem);
153         out.character("zero", zero);
154         out.character("decimalSep", decimalSep);
155         out.bool("omitSingularCount", omitSingularCount);
156         out.bool("omitDualCount", omitDualCount);
157         out.namedIndex("zeroHandling", EZeroHandling.names, zeroHandling);
158         out.namedIndex("decimalHandling", EDecimalHandling.names,
159                 decimalHandling);
160         out.namedIndex("fractionHandling", EFractionHandling.names,
161                 fractionHandling);
162         out.string("skippedUnitMarker", skippedUnitMarker);
163         out.bool("allowZero", allowZero);
164         out.bool("weeksAloneOnly", weeksAloneOnly);
165         out.namedIndex("useMilliseconds", EMilliSupport.names, useMilliseconds);
166         if (scopeData != null) {
167             out.open("ScopeDataList");
168             for (int i = 0; i < scopeData.length; ++i) {
169                 scopeData[i].write(out);
170             }
171             out.close();
172         }
173         out.close();
174     }
175 
176     public static class ScopeData {
177         String prefix;
178         boolean requiresDigitPrefix;
179         String suffix;
180 
write(RecordWriter out)181         public void write(RecordWriter out) {
182             out.open("ScopeData");
183             out.string("prefix", prefix);
184             out.bool("requiresDigitPrefix", requiresDigitPrefix);
185             out.string("suffix", suffix);
186             out.close();
187         }
188 
read(RecordReader in)189         public static ScopeData read(RecordReader in) {
190             if (in.open("ScopeData")) {
191                 ScopeData scope = new ScopeData();
192                 scope.prefix = in.string("prefix");
193                 scope.requiresDigitPrefix = in.bool("requiresDigitPrefix");
194                 scope.suffix = in.string("suffix");
195                 if (in.close()) {
196                     return scope;
197                 }
198             }
199             return null;
200         }
201     }
202 
203     public static interface ETimeLimit {
204         public static final byte NOLIMIT = 0;
205         public static final byte LT = 1;
206         public static final byte MT = 2;
207         public static final String[] names = { "NOLIMIT", "LT", "MT" };
208     }
209 
210     public static interface ETimeDirection {
211         public static final byte NODIRECTION = 0;
212         public static final byte PAST = 1;
213         public static final byte FUTURE = 2;
214         public static final String[] names = { "NODIRECTION", "PAST", "FUTURE" };
215     }
216 
217     public static interface EUnitVariant {
218         public static final byte PLURALIZED = 0;
219         public static final byte MEDIUM = 1;
220         public static final byte SHORT = 2;
221         public static final String[] names = { "PLURALIZED", "MEDIUM", "SHORT" };
222     }
223 
224     public static interface ECountVariant {
225         public static final byte INTEGER = 0;
226         public static final byte INTEGER_CUSTOM = 1;
227         public static final byte HALF_FRACTION = 2;
228         public static final byte DECIMAL1 = 3;
229         public static final byte DECIMAL2 = 4;
230         public static final byte DECIMAL3 = 5;
231         public static final String[] names = { "INTEGER", "INTEGER_CUSTOM",
232             "HALF_FRACTION", "DECIMAL1", "DECIMAL2", "DECIMAL3" };
233     }
234 
235     public static interface EPluralization {
236         public static final byte NONE = 0;
237         public static final byte PLURAL = 1;
238         public static final byte DUAL = 2;
239         public static final byte PAUCAL = 3;
240         public static final byte HEBREW = 4;
241         public static final byte ARABIC = 5;
242         public static final String[] names = { "NONE", "PLURAL", "DUAL",
243             "PAUCAL", "HEBREW", "ARABIC" };
244     }
245 
246     public static interface EHalfPlacement {
247         public static final byte PREFIX = 0;
248         public static final byte AFTER_FIRST = 1;
249         public static final byte LAST = 2;
250         public static final String[] names = { "PREFIX", "AFTER_FIRST", "LAST" };
251     }
252 
253     public static interface ENumberSystem {
254         public static final byte DEFAULT = 0;
255         public static final byte CHINESE_TRADITIONAL = 1;
256         public static final byte CHINESE_SIMPLIFIED = 2;
257         public static final byte KOREAN = 3;
258         public static final String[] names = { "DEFAULT",
259             "CHINESE_TRADITIONAL", "CHINESE_SIMPLIFIED", "KOREAN" };
260     }
261 
262     public static interface EZeroHandling {
263         public static final byte ZPLURAL = 0;
264         public static final byte ZSINGULAR = 1;
265         public static final String[] names = { "ZPLURAL", "ZSINGULAR" };
266     }
267 
268     public static interface EDecimalHandling {
269         public static final byte DPLURAL = 0;
270         public static final byte DSINGULAR = 1;
271         public static final byte DSINGULAR_SUBONE = 2;
272         public static final byte DPAUCAL = 3;
273         public static final String[] names = { "DPLURAL", "DSINGULAR",
274             "DSINGULAR_SUBONE", "DPAUCAL" };
275     }
276 
277     public static interface EFractionHandling {
278         public static final byte FPLURAL = 0;
279         public static final byte FSINGULAR_PLURAL = 1;
280         public static final byte FSINGULAR_PLURAL_ANDAHALF = 2;
281         public static final byte FPAUCAL = 3;
282         public static final String[] names = { "FPLURAL", "FSINGULAR_PLURAL",
283             "FSINGULAR_PLURAL_ANDAHALF", "FPAUCAL" };
284     }
285 
286     public static interface EHalfSupport {
287         public static final byte YES = 0;
288         public static final byte NO = 1;
289         public static final byte ONE_PLUS = 2;
290         public static final String[] names = { "YES", "NO", "ONE_PLUS" };
291     }
292 
293     public static interface EMilliSupport {
294         public static final byte YES = 0;
295         public static final byte NO = 1;
296         public static final byte WITH_SECONDS = 2;
297         public static final String[] names = { "YES", "NO", "WITH_SECONDS" };
298     }
299 
300     public static interface ESeparatorVariant {
301         public static final byte NONE = 0;
302         public static final byte SHORT = 1;
303         public static final byte FULL = 2;
304         public static final String[] names = { "NONE", "SHORT", "FULL" };
305     }
306 
307     public static interface EGender {
308         public static final byte M = 0;
309         public static final byte F = 1;
310         public static final byte N = 2;
311         public static final String[] names = { "M", "F", "N" };
312     }
313 }
314