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
17package com.android.internal.telephony;
18
19/**
20 * {@hide}
21 */
22public 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