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 mLine; 27 private int mNext = 0; 28 private int mTokStart, mTokEnd; 29 30 /***************************** Class Methods *****************************/ 31 32 public ATResponseParser(String line)33 ATResponseParser (String line) 34 { 35 mLine = line; 36 } 37 38 public boolean nextBoolean()39 nextBoolean() 40 { 41 // "\s*(\d)(,|$)" 42 // \d is '0' or '1' 43 44 nextTok(); 45 46 if (mTokEnd - mTokStart > 1) { 47 throw new ATParseEx(); 48 } 49 char c = mLine.charAt(mTokStart); 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 nextInt()59 nextInt() 60 { 61 // "\s*(\d+)(,|$)" 62 int ret = 0; 63 64 nextTok(); 65 66 for (int i = mTokStart ; i < mTokEnd ; i++) { 67 char c = mLine.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 nextString()82 nextString() 83 { 84 nextTok(); 85 86 return mLine.substring(mTokStart, mTokEnd); 87 } 88 89 public boolean hasMore()90 hasMore() 91 { 92 return mNext < mLine.length(); 93 } 94 95 private void nextTok()96 nextTok() 97 { 98 int len = mLine.length(); 99 100 if (mNext == 0) { 101 skipPrefix(); 102 } 103 104 if (mNext >= len) { 105 throw new ATParseEx(); 106 } 107 108 try { 109 // \s*("([^"]*)"|(.*)\s*)(,|$) 110 111 char c = mLine.charAt(mNext++); 112 boolean hasQuote = false; 113 114 c = skipWhiteSpace(c); 115 116 if (c == '"') { 117 if (mNext >= len) { 118 throw new ATParseEx(); 119 } 120 c = mLine.charAt(mNext++); 121 mTokStart = mNext - 1; 122 while (c != '"' && mNext < len) { 123 c = mLine.charAt(mNext++); 124 } 125 if (c != '"') { 126 throw new ATParseEx(); 127 } 128 mTokEnd = mNext - 1; 129 if (mNext < len && mLine.charAt(mNext++) != ',') { 130 throw new ATParseEx(); 131 } 132 } else { 133 mTokStart = mNext - 1; 134 mTokEnd = mTokStart; 135 while (c != ',') { 136 if (!Character.isWhitespace(c)) { 137 mTokEnd = mNext; 138 } 139 if (mNext == len) { 140 break; 141 } 142 c = mLine.charAt(mNext++); 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 skipWhiteSpace(char c)153 skipWhiteSpace (char c) 154 { 155 int len; 156 len = mLine.length(); 157 while (mNext < len && Character.isWhitespace(c)) { 158 c = mLine.charAt(mNext++); 159 } 160 161 if (Character.isWhitespace(c)) { 162 throw new ATParseEx(); 163 } 164 return c; 165 } 166 167 168 private void skipPrefix()169 skipPrefix() 170 { 171 // consume "^[^:]:" 172 173 mNext = 0; 174 int s = mLine.length(); 175 while (mNext < s){ 176 char c = mLine.charAt(mNext++); 177 178 if (c == ':') { 179 return; 180 } 181 } 182 183 throw new ATParseEx("missing prefix"); 184 } 185 186 } 187