10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/*
20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2006 The Android Open Source Project
30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License.
60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at
70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *
100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software
110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and
140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License.
150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony;
180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/**
200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide}
210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */
220825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class ATResponseParser
230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville{
240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /*************************** Instance Variables **************************/
250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
2622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private String mLine;
2722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private int mNext = 0;
2822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville    private int mTokStart, mTokEnd;
290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /***************************** Class Methods *****************************/
310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public
330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    ATResponseParser (String line)
340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
3522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mLine = line;
360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    nextBoolean()
400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "\s*(\d)(,|$)"
420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // \d is '0' or '1'
430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        nextTok();
450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
4622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mTokEnd - mTokStart > 1) {
470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new ATParseEx();
480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
4922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        char c = mLine.charAt(mTokStart);
500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (c == '0') return false;
520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (c ==  '1') return true;
530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new ATParseEx();
540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** positive int only */
580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public int
590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    nextInt()
600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // "\s*(\d+)(,|$)"
620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int ret = 0;
630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        nextTok();
650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
6622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        for (int i = mTokStart ; i < mTokEnd ; i++) {
6722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            char c = mLine.charAt(i);
680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // Yes, ASCII decimal digits only
700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c < '0' || c > '9') {
710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                throw new ATParseEx();
720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ret *= 10;
750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            ret += c - '0';
760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return ret;
790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public String
820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    nextString()
830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        nextTok();
850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
8622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mLine.substring(mTokStart, mTokEnd);
870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    public boolean
900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    hasMore()
910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
9222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        return mNext < mLine.length();
930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    nextTok()
970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
9822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int len = mLine.length();
990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mNext == 0) {
1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            skipPrefix();
1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
10422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        if (mNext >= len) {
1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new ATParseEx();
1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        try {
1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            // \s*("([^"]*)"|(.*)\s*)(,|$)
1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
11122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            char c = mLine.charAt(mNext++);
1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            boolean hasQuote = false;
1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            c = skipWhiteSpace(c);
1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c == '"') {
11722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mNext >= len) {
1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new ATParseEx();
1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12022d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                c = mLine.charAt(mNext++);
12122d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mTokStart = mNext - 1;
12222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                while (c != '"' && mNext < len) {
12322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c = mLine.charAt(mNext++);
1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                if (c != '"') {
1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new ATParseEx();
1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
12822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mTokEnd = mNext - 1;
12922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                if (mNext < len && mLine.charAt(mNext++) != ',') {
1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    throw new ATParseEx();
1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            } else {
13322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mTokStart = mNext - 1;
13422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                mTokEnd = mTokStart;
1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                while (c != ',') {
1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    if (!Character.isWhitespace(c)) {
13722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                        mTokEnd = mNext;
1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
13922d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    if (mNext == len) {
1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                        break;
1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                    }
14222d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville                    c = mLine.charAt(mNext++);
1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                }
1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        } catch (StringIndexOutOfBoundsException ex) {
1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new ATParseEx();
1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    /** Throws ATParseEx if whitespace extends to the end of string */
1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private char
1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    skipWhiteSpace (char c)
1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        int len;
15622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        len = mLine.length();
15722d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        while (mNext < len && Character.isWhitespace(c)) {
15822d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            c = mLine.charAt(mNext++);
1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        if (Character.isWhitespace(c)) {
1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            throw new ATParseEx();
1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        return c;
1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    private void
1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    skipPrefix()
1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    {
1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        // consume "^[^:]:"
1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
17322d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        mNext = 0;
17422d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        int s = mLine.length();
17522d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville        while (mNext < s){
17622d85a8e3a575a6d01d2c788587971657dfe20c6Wink Saville            char c = mLine.charAt(mNext++);
1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            if (c == ':') {
1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville                return;
1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville            }
1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        }
1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville        throw new ATParseEx("missing prefix");
1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville    }
1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville
1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville}
187