replicant-packages_apps_Email/imap2/src/com/android/imap2/Parser.java

203 lines
5.2 KiB
Java

/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.imap2;
public class Parser {
String str;
int pos;
int len;
static final String white = "\r\n \t";
public Parser (String _str) {
str = _str;
pos = 0;
len = str.length();
}
public Parser (String _str, int start) {
str = _str;
pos = start;
len = str.length();
}
public void skipWhite () {
while ((pos < len) && white.indexOf(str.charAt(pos)) >= 0)
pos++;
}
public String parseAtom () {
skipWhite();
int start = pos;
while ((pos < len) && white.indexOf(str.charAt(pos)) < 0)
pos++;
if (pos > start)
return str.substring(start, pos);
return null;
}
public char nextChar () {
if (pos >= len)
return 0;
else
return str.charAt(pos++);
}
public char peekChar () {
if (pos >= len)
return 0;
else
return str.charAt(pos);
}
public String parseString () {
return parseString(false);
}
public String parseStringOrAtom () {
return parseString(true);
}
public String parseString (boolean orAtom) {
skipWhite();
char c = nextChar();
if (c != '\"') {
if (c == '{') {
int cnt = parseInteger();
c = nextChar();
if (c != '}')
return null;
int start = pos + 2;
int end = start + cnt;
String s = str.substring(start, end);
pos = end;
return s;
} else if (orAtom) {
backChar();
return parseAtom();
} else if (c == 'n' || c == 'N') {
parseAtom();
return null;
} else
return null;
}
int start = pos;
boolean quote = false;
while (true) {
c = nextChar();
if (c == 0)
return null;
else if (quote)
quote = false;
else if (c == '\\')
quote = true;
else if (c == '\"')
break;
}
return str.substring(start, pos - 1);
}
public void backChar () {
if (pos > 0)
pos--;
}
public String parseListOrNil () {
String list = parseList();
if (list == null) {
parseAtom();
list = "";
}
return list;
}
public String parseList () {
skipWhite();
if (nextChar() != '(') {
backChar();
return null;
}
int start = pos;
int level = 0;
boolean quote = false;
boolean string = false;
while (true) {
char c = nextChar();
if (c == 0)
return null;
else if (quote)
quote = false;
else if (c == '\\' && string)
quote = true;
else if (c == '\"')
string = !string;
else if (c == '(' && !string)
level++;
else if (c == ')' && !string) {
if (level-- == 0)
break;
}
}
return str.substring(start, pos - 1);
}
public Integer parseInteger () {
skipWhite();
int start = pos;
while (pos < len) {
char c = str.charAt(pos);
if (c >= '0' && c <= '9')
pos++;
else
break;
}
if (pos > start) {
try {
Integer i = Integer.parseInt(str.substring(start, pos));
return i;
} catch (NumberFormatException e) {
return -1;
}
} else
return -1;
}
public int[] gatherInts () {
int[] list = new int[128];
int size = 128;
int offs = 0;
while (true) {
// TODO Slow; handle this inline rather than calling the method
Integer i = parseInteger();
if (i >= 0) {
if (offs == size) {
// Double the size of the array as necessary
size <<= 1;
int[] tmp = new int[size];
System.arraycopy(list, 0, tmp, 0, offs);
list = tmp;
}
list[offs++] = i;
}
else
break;
}
int[] res = new int[offs];
System.arraycopy(list, 0, res, 0, offs);
return res;
}
}