1 /* 2 * Copyright (C) 2006 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.internal.telephony; 18 19 /** 20 * {@hide} 21 */ 22 public class ATResponseParser 23 { 24 /*************************** Instance Variables **************************/ 25 26 private String line; 27 private int next = 0; 28 private int tokStart, tokEnd; 29 30 /***************************** Class Methods *****************************/ 31 32 public 33 ATResponseParser (String line) 34 { 35 this.line = line; 36 } 37 38 public boolean 39 nextBoolean() 40 { 41 // "\s*(\d)(,|$)" 42 // \d is '0' or '1' 43 44 nextTok(); 45 46 if (tokEnd - tokStart > 1) { 47 throw new ATParseEx(); 48 } 49 char c = line.charAt(tokStart); 50 51 if (c == '0') return false; 52 if (c == '1') return true; 53 throw new ATParseEx(); 54 } 55 56 57 /** positive int only */ 58 public int 59 nextInt() 60 { 61 // "\s*(\d+)(,|$)" 62 int ret = 0; 63 64 nextTok(); 65 66 for (int i = tokStart ; i < tokEnd ; i++) { 67 char c = line.charAt(i); 68 69 // Yes, ASCII decimal digits only 70 if (c < '0' || c > '9') { 71 throw new ATParseEx(); 72 } 73 74 ret *= 10; 75 ret += c - '0'; 76 } 77 78 return ret; 79 } 80 81 public String 82 nextString() 83 { 84 nextTok(); 85 86 return line.substring(tokStart, tokEnd); 87 } 88 89 public boolean 90 hasMore() 91 { 92 return next < line.length(); 93 } 94 95 private void 96 nextTok() 97 { 98 int len = line.length(); 99 100 if (next == 0) { 101 skipPrefix(); 102 } 103 104 if (next >= len) { 105 throw new ATParseEx(); 106 } 107 108 try { 109 // \s*("([^"]*)"|(.*)\s*)(,|$) 110 111 char c = line.charAt(next++); 112 boolean hasQuote = false; 113 114 c = skipWhiteSpace(c); 115 116 if (c == '"') { 117 if (next >= len) { 118 throw new ATParseEx(); 119 } 120 c = line.charAt(next++); 121 tokStart = next - 1; 122 while (c != '"' && next < len) { 123 c = line.charAt(next++); 124 } 125 if (c != '"') { 126 throw new ATParseEx(); 127 } 128 tokEnd = next - 1; 129 if (next < len && line.charAt(next++) != ',') { 130 throw new ATParseEx(); 131 } 132 } else { 133 tokStart = next - 1; 134 tokEnd = tokStart; 135 while (c != ',') { 136 if (!Character.isWhitespace(c)) { 137 tokEnd = next; 138 } 139 if (next == len) { 140 break; 141 } 142 c = line.charAt(next++); 143 } 144 } 145 } catch (StringIndexOutOfBoundsException ex) { 146 throw new ATParseEx(); 147 } 148 } 149 150 151 /** Throws ATParseEx if whitespace extends to the end of string */ 152 private char 153 skipWhiteSpace (char c) 154 { 155 int len; 156 len = line.length(); 157 while (next < len && Character.isWhitespace(c)) { 158 c = line.charAt(next++); 159 } 160 161 if (Character.isWhitespace(c)) { 162 throw new ATParseEx(); 163 } 164 return c; 165 } 166 167 168 private void 169 skipPrefix() 170 { 171 // consume "^[^:]:" 172 173 next = 0; 174 int s = line.length(); 175 while (next < s){ 176 char c = line.charAt(next++); 177 178 if (c == ':') { 179 return; 180 } 181 } 182 183 throw new ATParseEx("missing prefix"); 184 } 185 186 } 187