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