Home | History | Annotate | Download | only in impl
      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