/* (C) 2012 Pragmatic Software
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/
*/
package com.googlecode.networklog;
import java.lang.RuntimeException;
// Inspired by Hugh Perkins's jfastparser
// https://github.com/hughperkins/jfastparser/blob/1434212efac5ed422724d75dbb3359b72dd7c614/src/jfastparser/Parser.java
public class FastParser {
char[] line;
int len;
int pos;
char delimiter;
public FastParser() {
this(null, 0, ' ');
}
public FastParser(char delimiter) {
this(null, 0, delimiter);
}
public FastParser(char[] line, int len) {
this(line, len, ' ');
}
public FastParser(char[] line, int len, char delimiter) {
this.line = line;
this.len = len;
this.delimiter = delimiter;
}
public void setLine(char[] line, int len) {
if(MyLog.enabled && MyLog.level >= 6) {
MyLog.d(6, "setLine line: [" + new String(line, 0, len) + "] len: " + len);
}
this.line = line;
this.len = len;
pos = 0;
}
public void setPos(int newpos) {
if(newpos < 0 || newpos >= len) {
throw new IndexOutOfBoundsException("Attempt to set new pos " + newpos + " is out of range 0 - " + len);
}
pos = newpos;
}
public void setDelimiter(char delimiter) {
this.delimiter = delimiter;
}
public long getLong() {
return getLong(delimiter);
}
public long getLong(char delimiter) {
int newpos = pos;
long value = 0;
boolean neg = false;
if(pos >= len) {
throw new RuntimeException("pos at end of string");
}
if(line[pos] == '-') {
neg = true;
newpos++;
}
if(line[pos] == '+') {
pos++;
newpos++;
}
char thischar = 0;
while(newpos < len && (thischar = line[newpos]) != delimiter && thischar >= '0' && thischar <= '9') {
value = value * 10 + (line[newpos] - '0');
newpos++;
}
if(pos == newpos) {
throw new RuntimeException("expected long but found [" + line[pos] + "] in [" + new String(line, pos, len - pos) + "]");
}
pos = newpos;
eatDelimiter();
return neg ? -value : value;
}
public int getInt() {
return getInt(delimiter);
}
public int getInt(char delimiter) {
int newpos = pos;
int value = 0;
boolean neg = false;
if(pos >= len) {
throw new RuntimeException("pos at end of string");
}
if(line[pos] == '-') {
neg = true;
newpos++;
}
if(line[pos] == '+') {
pos++;
newpos++;
}
char thischar = 0;
while(newpos < len && (thischar = line[newpos]) != delimiter && thischar >= '0' && thischar <= '9') {
value = value * 10 + (line[newpos] - '0');
newpos++;
}
if(pos == newpos) {
throw new RuntimeException("expected int but found [" + line[pos] + "] in [" + new String(line, pos, len - pos) + "]");
}
pos = newpos;
eatDelimiter();
return neg ? -value : value;
}
public double getDouble() {
int newpos = pos;
double value = 0;
boolean negative = false;
boolean afterpoint = false;
double divider = 1;
char thischar = 0;
while(newpos < len && (thischar = line[newpos]) != ' ' && thischar != 'e' && thischar != '\t') {
if(thischar == '-') {
negative = true;
} else if(thischar == '.') {
afterpoint = true;
} else {
int thisdigit = thischar - '0';
value = value * 10 + thisdigit;
if(afterpoint) {
divider *= 10;
}
}
newpos++;
}
if(thischar == 'e') {
newpos++;
boolean exponentnegative = false;
int exponent = 0;
while(newpos < len && (thischar = line[newpos]) != delimiter) {
if(thischar == '-') {
exponentnegative = true;
} else if(thischar != '+') {
exponent = exponent * 10 + (thischar - '0');
}
newpos++;
}
if(exponentnegative) {
exponent = -exponent;
}
value *= Math.pow(10, exponent);
}
if(negative) {
value = -value;
}
value /= divider;
if(pos == newpos) {
throw new RuntimeException("expected double but found [" + line[pos] + "] in [" + new String(line, pos, len - pos) + "]");
}
pos = newpos;
eatDelimiter();
return value;
}
public String getString() {
return getString(delimiter);
}
public String getString(char delimiter) {
int newpos = pos;
String value;
while(newpos < len && line[newpos] != delimiter) {
newpos++;
}
if(pos == newpos) {
value = "";
} else {
value = StringPool.get(line, pos, newpos - pos);
}
pos = newpos;
eatDelimiter();
return value;
}
public void eatDelimiter() {
eatChar(delimiter);
}
public void eatChar(char target) {
if(pos < len && line[pos] != target) {
throw new RuntimeException("expected [" + target + "] but got " + line[pos] + " in [" + new String(line, pos, len - pos) + "]");
}
pos++;
}
public boolean hasMore() {
return pos < len;
}
}