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