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-2010, International Business Machines Corporation and * 7 * others. All Rights Reserved. * 8 ****************************************************************************** 9 */ 10 11 package android.icu.impl.duration.impl; 12 13 import java.io.IOException; 14 import java.io.Reader; 15 import java.util.ArrayList; 16 import java.util.List; 17 18 import android.icu.lang.UCharacter; 19 20 /** 21 * @hide Only a subset of ICU is exposed in Android 22 */ 23 public class XMLRecordReader implements RecordReader { 24 private Reader r; 25 26 private List<String> nameStack; 27 28 private boolean atTag; 29 30 private String tag; // cache 31 32 public XMLRecordReader(Reader r) { 33 this.r = r; 34 this.nameStack = new ArrayList<String>(); 35 36 // skip XML prologue 37 if (getTag().startsWith("?xml")) { 38 advance(); 39 } 40 41 // skip FIRST comment 42 if (getTag().startsWith("!--")) { 43 advance(); 44 } 45 } 46 47 @Override 48 public boolean open(String title) { 49 if (getTag().equals(title)) { 50 nameStack.add(title); 51 advance(); 52 return true; 53 } 54 return false; 55 } 56 57 @Override 58 public boolean close() { 59 int ix = nameStack.size() - 1; 60 String name = nameStack.get(ix); 61 if (getTag().equals("/" + name)) { 62 nameStack.remove(ix); 63 advance(); 64 return true; 65 } 66 return false; 67 } 68 69 @Override 70 public boolean bool(String name) { 71 String s = string(name); 72 if (s != null) { 73 return "true".equals(s); 74 } 75 return false; 76 } 77 78 @Override 79 public boolean[] boolArray(String name) { 80 String[] sa = stringArray(name); 81 if (sa != null) { 82 boolean[] result = new boolean[sa.length]; 83 for (int i = 0; i < sa.length; ++i) { 84 result[i] = "true".equals(sa[i]); 85 } 86 return result; 87 } 88 return null; 89 } 90 91 @Override 92 public char character(String name) { 93 String s = string(name); 94 if (s != null) { 95 return s.charAt(0); 96 } 97 return '\uffff'; 98 } 99 100 @Override 101 public char[] characterArray(String name) { 102 String[] sa = stringArray(name); 103 if (sa != null) { 104 char[] result = new char[sa.length]; 105 for (int i = 0; i < sa.length; ++i) { 106 result[i] = sa[i].charAt(0); 107 } 108 return result; 109 } 110 return null; 111 } 112 113 @Override 114 public byte namedIndex(String name, String[] names) { 115 String sa = string(name); 116 if (sa != null) { 117 for (int i = 0; i < names.length; ++i) { 118 if (sa.equals(names[i])) { 119 return (byte) i; 120 } 121 } 122 } 123 return (byte) -1; 124 } 125 126 @Override 127 public byte[] namedIndexArray(String name, String[] names) { 128 String[] sa = stringArray(name); 129 if (sa != null) { 130 byte[] result = new byte[sa.length]; 131 loop: for (int i = 0; i < sa.length; ++i) { 132 String s = sa[i]; 133 for (int j = 0; j < names.length; ++j) { 134 if (names[j].equals(s)) { 135 result[i] = (byte) j; 136 continue loop; 137 } 138 } 139 result[i] = (byte) -1; 140 } 141 return result; 142 } 143 return null; 144 } 145 146 @Override 147 public String string(String name) { 148 if (match(name)) { 149 String result = readData(); 150 if (match("/" + name)) { 151 return result; 152 } 153 } 154 return null; 155 } 156 157 @Override 158 public String[] stringArray(String name) { 159 if (match(name + "List")) { 160 List<String> list = new ArrayList<String>(); 161 String s; 162 while (null != (s = string(name))) { 163 if ("Null".equals(s)) { 164 s = null; 165 } 166 list.add(s); 167 } 168 if (match("/" + name + "List")) { 169 return list.toArray(new String[list.size()]); 170 } 171 } 172 return null; 173 } 174 175 @Override 176 public String[][] stringTable(String name) { 177 if (match(name + "Table")) { 178 List<String[]> list = new ArrayList<String[]>(); 179 String[] sa; 180 while (null != (sa = stringArray(name))) { 181 list.add(sa); 182 } 183 if (match("/" + name + "Table")) { 184 return list.toArray(new String[list.size()][]); 185 } 186 } 187 return null; 188 } 189 190 private boolean match(String target) { 191 if (getTag().equals(target)) { 192 // System.out.println("match '" + target + "'"); 193 advance(); 194 return true; 195 } 196 return false; 197 } 198 199 private String getTag() { 200 if (tag == null) { 201 tag = readNextTag(); 202 } 203 return tag; 204 } 205 206 private void advance() { 207 tag = null; 208 } 209 210 private String readData() { 211 StringBuilder sb = new StringBuilder(); 212 boolean inWhitespace = false; 213 // boolean inAmp = false; 214 while (true) { 215 int c = readChar(); 216 if (c == -1 || c == '<') { 217 atTag = c == '<'; 218 break; 219 } 220 if (c == '&') { 221 c = readChar(); 222 if (c == '#') { 223 StringBuilder numBuf = new StringBuilder(); 224 int radix = 10; 225 c = readChar(); 226 if (c == 'x') { 227 radix = 16; 228 c = readChar(); 229 } 230 while (c != ';' && c != -1) { 231 numBuf.append((char) c); 232 c = readChar(); 233 } 234 try { 235 int num = Integer.parseInt(numBuf.toString(), radix); 236 c = (char) num; 237 } catch (NumberFormatException ex) { 238 System.err.println("numbuf: " + numBuf.toString() 239 + " radix: " + radix); 240 throw ex; 241 } 242 } else { 243 StringBuilder charBuf = new StringBuilder(); 244 while (c != ';' && c != -1) { 245 charBuf.append((char) c); 246 c = readChar(); 247 } 248 String charName = charBuf.toString(); 249 if (charName.equals("lt")) { 250 c = '<'; 251 } else if (charName.equals("gt")) { 252 c = '>'; 253 } else if (charName.equals("quot")) { 254 c = '"'; 255 } else if (charName.equals("apos")) { 256 c = '\''; 257 } else if (charName.equals("amp")) { 258 c = '&'; 259 } else { 260 System.err.println("unrecognized character entity: '" 261 + charName + "'"); 262 continue; 263 } 264 } 265 } 266 267 if (UCharacter.isWhitespace(c)) { 268 if (inWhitespace) { 269 continue; 270 } 271 c = ' '; 272 inWhitespace = true; 273 } else { 274 inWhitespace = false; 275 } 276 sb.append((char) c); 277 } 278 //System.err.println("read data: '" + sb.toString() + "'"); 279 return sb.toString(); 280 } 281 282 private String readNextTag() { 283 int c = '\0'; 284 while (!atTag) { 285 c = readChar(); 286 if (c == '<' || c == -1) { 287 if (c == '<') { 288 atTag = true; 289 } 290 break; 291 } 292 if (!UCharacter.isWhitespace(c)) { 293 System.err.println("Unexpected non-whitespace character " 294 + Integer.toHexString(c)); 295 break; 296 } 297 } 298 299 if (atTag) { 300 atTag = false; 301 StringBuilder sb = new StringBuilder(); 302 while (true) { 303 c = readChar(); 304 if (c == '>' || c == -1) { 305 break; 306 } 307 sb.append((char) c); 308 } 309 // System.err.println("read tag: '" + sb.toString() + "'"); 310 return sb.toString(); 311 } 312 return null; 313 } 314 315 int readChar() { 316 try { 317 return r.read(); 318 } catch (IOException e) { 319 // assume end of input 320 } 321 return -1; 322 } 323 } 324