package org.joni;
import org.jcodings.Encoding;
import org.jcodings.IntHolder;
import org.joni.exception.ErrorMessages;
import org.joni.exception.InternalException;
import org.joni.exception.SyntaxException;
import org.joni.exception.ValueException;
abstract class ScannerSupport extends IntHolder implements ErrorMessages {
protected final Encoding enc;
protected final byte[]bytes;
protected int p;
protected int stop;
private int lastFetched;
protected int c;
private final int begin;
private final int end;
protected int _p;
protected ScannerSupport(Encoding enc, byte[]bytes, int p, int end) {
this.enc = enc;
this.bytes = bytes;
this.begin = p;
this.end = end;
}
protected final int getBegin() {
return begin;
}
protected final int getEnd() {
return end;
}
private static final int INT_SIGN_BIT = 1 << 31;
protected final int scanUnsignedNumber() {
int last = c;
int num = 0;
while(left()) {
fetch();
if (enc.isDigit(c)) {
int onum = num;
num = num * 10 + Encoding.digitVal(c);
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
unfetch();
break;
}
}
c = last;
return num;
}
protected final int scanUnsignedHexadecimalNumber(int minLength, int maxLength) {
int last = c;
int num = 0;
int restLen = maxLength - minLength;
while(left() && maxLength-- != 0) {
fetch();
if (enc.isXDigit(c)) {
int val = enc.xdigitVal(c);
if ((Integer.MAX_VALUE - val) / 16 < num) return -1;
num = (num << 4) + val;
} else {
unfetch();
maxLength++;
break;
}
}
if (maxLength > restLen) return -2;
c = last;
return num;
}
protected final int scanUnsignedOctalNumber(int maxLength) {
int last = c;
int num = 0;
while(left() && maxLength-- != 0) {
fetch();
if (enc.isDigit(c) && c < '8') {
int onum = num;
int val = Encoding.odigitVal(c);
num = (num << 3) + val;
if (((onum ^ num) & INT_SIGN_BIT) != 0) return -1;
} else {
unfetch();
break;
}
}
c = last;
return num;
}
protected final void reset() {
p = begin;
stop = end;
}
protected final void mark() {
_p = p;
}
protected final void restore() {
p = _p;
}
protected final void inc() {
lastFetched = p;
p += enc.length(bytes, p, stop);
}
protected final void fetch() {
c = enc.mbcToCode(bytes, p, stop);
lastFetched = p;
p += enc.length(bytes, p, stop);
}
protected int fetchTo() {
int to = enc.mbcToCode(bytes, p, stop);
lastFetched = p;
p += enc.length(bytes, p, stop);
return to;
}
protected final void unfetch() {
p = lastFetched;
}
protected final int peek() {
return p < stop ? enc.mbcToCode(bytes, p, stop) : 0;
}
protected final boolean peekIs(int c) {
return peek() == c;
}
protected final boolean left() {
return p < stop;
}
protected void newSyntaxException(String message) {
throw new SyntaxException(message);
}
protected void newValueException(String message) {
throw new ValueException(message);
}
protected void newValueException(String message, String str) {
throw new ValueException(message, str);
}
protected void newValueException(String message, int p, int end) {
throw new ValueException(message, new String(bytes, p, end - p));
}
protected void newInternalException(String message) {
throw new InternalException(message);
}
}