• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GENERATED SOURCE. DO NOT MODIFY. */
2 // © 2016 and later: Unicode, Inc. and others.
3 // License & terms of use: http://www.unicode.org/copyright.html#License
4 /*
5 ******************************************************************************
6 * Copyright (C) 2007-2012, International Business Machines Corporation and   *
7 * others. All Rights Reserved.                                               *
8 ******************************************************************************
9 */
10 
11 package ohos.global.icu.impl.duration.impl;
12 
13 import java.util.Locale;
14 
15 /**
16  * @hide exposed on OHOS
17  */
18 public class Utils {
localeFromString(String s)19   public static final Locale localeFromString(String s) {
20     String language = s;
21     String region = "";
22     String variant = "";
23 
24     int x = language.indexOf("_");
25     if (x != -1) {
26       region = language.substring(x+1);
27       language = language.substring(0, x);
28     }
29     x = region.indexOf("_");
30     if (x != -1) {
31       variant = region.substring(x+1);
32       region = region.substring(0, x);
33     }
34     return new Locale(language, region, variant);
35   }
36     /*
37   public static <T> T[] arraycopy(T[] src) {
38     T[] result = (T[])Array.newInstance(src.getClass().getComponentType(), src.length); // can we do this without casting?
39     for (int i = 0; i < src.length; ++i) {
40       result[i] = src[i];
41     }
42     return result;
43   }
44     */
45 
46   /**
47    * Interesting features of chinese numbers:
48    * - Each digit is followed by a unit symbol (10's, 100's, 1000's).
49    * - Units repeat in levels of 10,000, there are symbols for each level too (except 1's).
50    * - The digit 2 has a special form before the 10 symbol and at the end of the number.
51    * - If the first digit in the number is 1 and its unit is 10, the 1 is omitted.
52    * - Sequences of 0 digits and their units are replaced by a single 0 and no unit.
53    * - If there are two such sequences of 0 digits in a level (1000's and 10's), the 1000's 0 is also omitted.
54    * - The 1000's 0 is also omitted in alternating levels, such that it is omitted in the rightmost
55    *     level with a 10's 0, or if none, in the rightmost level.
56    * - Level symbols are omitted if all of their units are omitted
57    */
chineseNumber(long n, ChineseDigits zh)58   public static String chineseNumber(long n, ChineseDigits zh) {
59     if (n < 0) {
60       n = -n;
61     }
62     if (n <= 10) {
63       if (n == 2) {
64         return String.valueOf(zh.liang);
65       }
66       return String.valueOf(zh.digits[(int)n]);
67     }
68 
69     // 9223372036854775807
70     char[] buf = new char[40]; // as long as we get, and actually we can't get this high, no units past zhao
71     char[] digits = String.valueOf(n).toCharArray();
72 
73     // first, generate all the digits in place
74     // convert runs of zeros into a single zero, but keep places
75     //
76     boolean inZero = true; // true if we should zap zeros in this block, resets at start of block
77     boolean forcedZero = false; // true if we have a 0 in tens's place
78     int x = buf.length;
79     for (int i = digits.length, u = -1, l = -1; --i >= 0;) {
80       if (u == -1) {
81         if (l != -1) {
82           buf[--x] = zh.levels[l];
83           inZero = true;
84           forcedZero = false;
85         }
86         ++u;
87       } else {
88         buf[--x] = zh.units[u++];
89         if (u == 3) {
90           u = -1;
91           ++l;
92         }
93       }
94       int d = digits[i] - '0';
95       if (d == 0) {
96         if (x < buf.length-1 && u != 0) {
97           buf[x] = '*';
98         }
99         if (inZero || forcedZero) {
100           buf[--x] = '*';
101         } else {
102           buf[--x] = zh.digits[0];
103           inZero = true;
104           forcedZero = u == 1;
105         }
106       } else {
107         inZero = false;
108         buf[--x] = zh.digits[d];
109       }
110     }
111 
112     // scanning from right, find first required 'ling'
113     // we only care if n > 101,0000 as this is the first case where
114     // it might shift.  remove optional lings in alternating blocks.
115     if (n > 1000000) {
116       boolean last = true;
117       int i = buf.length - 3;
118       do {
119         if (buf[i] == '0') {
120           break;
121         }
122         i -= 8;
123         last = !last;
124       } while (i > x);
125 
126       i = buf.length - 7;
127       do {
128         if (buf[i] == zh.digits[0] && !last) {
129           buf[i] = '*';
130         }
131         i -= 8;
132         last = !last;
133       } while (i > x);
134 
135       // remove levels for empty blocks
136       if (n >= 100000000) {
137         i = buf.length - 8;
138         do {
139           boolean empty = true;
140           for (int j = i-1, e = Math.max(x-1, i-8); j > e; --j) {
141             if (buf[j] != '*') {
142               empty = false;
143               break;
144             }
145           }
146           if (empty) {
147             if (buf[i+1] != '*' && buf[i+1] != zh.digits[0]) {
148               buf[i] = zh.digits[0];
149             } else {
150               buf[i] = '*';
151             }
152           }
153           i -= 8;
154         } while (i > x);
155       }
156     }
157 
158     // replace er by liang except before or after shi or after ling
159     for (int i = x; i < buf.length; ++i) {
160       if (buf[i] != zh.digits[2]) continue;
161       if (i < buf.length - 1 && buf[i+1] == zh.units[0]) continue;
162       if (i > x && (buf[i-1] == zh.units[0] || buf[i-1] == zh.digits[0] || buf[i-1] == '*')) continue;
163 
164       buf[i] = zh.liang;
165     }
166 
167     // eliminate leading 1 if following unit is shi
168     if (buf[x] == zh.digits[1] && (zh.ko || buf[x+1] == zh.units[0])) {
169       ++x;
170     }
171 
172     // now, compress out the '*'
173     int w = x;
174     for (int r = x; r < buf.length; ++r) {
175       if (buf[r] != '*') {
176         buf[w++] = buf[r];
177       }
178     }
179     return new String(buf, x, w-x);
180   }
181 
182 //  public static void main(String[] args) {
183 //    for (int i = 0; i < args.length; ++i) {
184 //      String arg = args[i];
185 //      System.out.print(arg);
186 //      System.out.print(" > ");
187 //      long n = Long.parseLong(arg);
188 //      System.out.println(chineseNumber(n, ChineseDigits.DEBUG));
189 //    }
190 //  }
191 
192   /**
193  * @hide exposed on OHOS
194  */
195 public static class ChineseDigits {
196     final char[] digits;
197     final char[] units;
198     final char[] levels;
199     final char liang;
200     final boolean ko;
201 
ChineseDigits(String digits, String units, String levels, char liang, boolean ko)202     ChineseDigits(String digits, String units, String levels, char liang, boolean ko) {
203       this.digits = digits.toCharArray();
204       this.units = units.toCharArray();
205       this.levels = levels.toCharArray();
206       this.liang = liang;
207       this.ko = ko;
208     }
209 
210     public static final ChineseDigits DEBUG =
211       new ChineseDigits("0123456789s", "sbq", "WYZ", 'L', false);
212 
213     public static final ChineseDigits TRADITIONAL =
214       new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
215                         "\u5341\u767e\u5343", // shi, bai, qian
216                         "\u842c\u5104\u5146", // wan, yi, zhao
217                         '\u5169', false); // liang
218 
219     public static final ChineseDigits SIMPLIFIED =
220       new ChineseDigits("\u96f6\u4e00\u4e8c\u4e09\u56db\u4e94\u516d\u4e03\u516b\u4e5d\u5341", // to shi
221                         "\u5341\u767e\u5343", // shi, bai, qian
222                         "\u4e07\u4ebf\u5146", // wan, yi, zhao
223                         '\u4e24', false); // liang
224 
225     // no 1 before first unit no matter what it is
226     // not sure if there are 'ling' units
227     public static final ChineseDigits KOREAN =
228       new ChineseDigits("\uc601\uc77c\uc774\uc0bc\uc0ac\uc624\uc721\uce60\ud314\uad6c\uc2ed", // to ten
229                         "\uc2ed\ubc31\ucc9c", // 10, 100, 1000
230                         "\ub9cc\uc5b5?", // 10^4, 10^8, 10^12
231                         '\uc774', true);
232   }
233 }
234