419 lines
12 KiB
Java
419 lines
12 KiB
Java
package org.nfunk.jep;
|
|
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStreamReader;
|
|
import java.io.Reader;
|
|
|
|
public class JavaCharStream {
|
|
public static final boolean staticFlag = false;
|
|
|
|
public int bufpos = -1;
|
|
|
|
int bufsize;
|
|
|
|
int available;
|
|
|
|
int tokenBegin;
|
|
|
|
protected int[] bufline;
|
|
|
|
protected int[] bufcolumn;
|
|
|
|
protected int column = 0;
|
|
|
|
protected int line = 1;
|
|
|
|
protected boolean prevCharIsCR = false;
|
|
|
|
protected boolean prevCharIsLF = false;
|
|
|
|
protected Reader inputStream;
|
|
|
|
protected char[] nextCharBuf;
|
|
|
|
protected char[] buffer;
|
|
|
|
protected int maxNextCharInd = 0;
|
|
|
|
protected int nextCharInd = -1;
|
|
|
|
protected int inBuf = 0;
|
|
|
|
static final int hexval(char paramChar) throws IOException {
|
|
switch (paramChar) {
|
|
case '0':
|
|
return 0;
|
|
case '1':
|
|
return 1;
|
|
case '2':
|
|
return 2;
|
|
case '3':
|
|
return 3;
|
|
case '4':
|
|
return 4;
|
|
case '5':
|
|
return 5;
|
|
case '6':
|
|
return 6;
|
|
case '7':
|
|
return 7;
|
|
case '8':
|
|
return 8;
|
|
case '9':
|
|
return 9;
|
|
case 'A':
|
|
case 'a':
|
|
return 10;
|
|
case 'B':
|
|
case 'b':
|
|
return 11;
|
|
case 'C':
|
|
case 'c':
|
|
return 12;
|
|
case 'D':
|
|
case 'd':
|
|
return 13;
|
|
case 'E':
|
|
case 'e':
|
|
return 14;
|
|
case 'F':
|
|
case 'f':
|
|
return 15;
|
|
}
|
|
throw new IOException();
|
|
}
|
|
|
|
protected void ExpandBuff(boolean paramBoolean) {
|
|
char[] arrayOfChar = new char[this.bufsize + 2048];
|
|
int[] arrayOfInt1 = new int[this.bufsize + 2048];
|
|
int[] arrayOfInt2 = new int[this.bufsize + 2048];
|
|
try {
|
|
if (paramBoolean) {
|
|
System.arraycopy(this.buffer, this.tokenBegin, arrayOfChar, 0, this.bufsize - this.tokenBegin);
|
|
System.arraycopy(this.buffer, 0, arrayOfChar, this.bufsize - this.tokenBegin, this.bufpos);
|
|
this.buffer = arrayOfChar;
|
|
System.arraycopy(this.bufline, this.tokenBegin, arrayOfInt1, 0, this.bufsize - this.tokenBegin);
|
|
System.arraycopy(this.bufline, 0, arrayOfInt1, this.bufsize - this.tokenBegin, this.bufpos);
|
|
this.bufline = arrayOfInt1;
|
|
System.arraycopy(this.bufcolumn, this.tokenBegin, arrayOfInt2, 0, this.bufsize - this.tokenBegin);
|
|
System.arraycopy(this.bufcolumn, 0, arrayOfInt2, this.bufsize - this.tokenBegin, this.bufpos);
|
|
this.bufcolumn = arrayOfInt2;
|
|
this.bufpos += this.bufsize - this.tokenBegin;
|
|
} else {
|
|
System.arraycopy(this.buffer, this.tokenBegin, arrayOfChar, 0, this.bufsize - this.tokenBegin);
|
|
this.buffer = arrayOfChar;
|
|
System.arraycopy(this.bufline, this.tokenBegin, arrayOfInt1, 0, this.bufsize - this.tokenBegin);
|
|
this.bufline = arrayOfInt1;
|
|
System.arraycopy(this.bufcolumn, this.tokenBegin, arrayOfInt2, 0, this.bufsize - this.tokenBegin);
|
|
this.bufcolumn = arrayOfInt2;
|
|
this.bufpos -= this.tokenBegin;
|
|
}
|
|
} catch (Throwable throwable) {
|
|
throw new Error(throwable.getMessage());
|
|
}
|
|
this.available = this.bufsize += 2048;
|
|
this.tokenBegin = 0;
|
|
}
|
|
|
|
protected void FillBuff() throws IOException {
|
|
if (this.maxNextCharInd == 4096)
|
|
this.maxNextCharInd = this.nextCharInd = 0;
|
|
try {
|
|
int i;
|
|
if ((i = this.inputStream.read(this.nextCharBuf, this.maxNextCharInd, 4096 - this.maxNextCharInd)) == -1) {
|
|
this.inputStream.close();
|
|
throw new IOException();
|
|
}
|
|
this.maxNextCharInd += i;
|
|
return;
|
|
} catch (IOException iOException) {
|
|
if (this.bufpos != 0) {
|
|
this.bufpos--;
|
|
backup(0);
|
|
} else {
|
|
this.bufline[this.bufpos] = this.line;
|
|
this.bufcolumn[this.bufpos] = this.column;
|
|
}
|
|
throw iOException;
|
|
}
|
|
}
|
|
|
|
protected char ReadByte() throws IOException {
|
|
if (++this.nextCharInd >= this.maxNextCharInd)
|
|
FillBuff();
|
|
return this.nextCharBuf[this.nextCharInd];
|
|
}
|
|
|
|
public char BeginToken() throws IOException {
|
|
if (this.inBuf > 0) {
|
|
this.inBuf--;
|
|
if (++this.bufpos == this.bufsize)
|
|
this.bufpos = 0;
|
|
this.tokenBegin = this.bufpos;
|
|
return this.buffer[this.bufpos];
|
|
}
|
|
this.tokenBegin = 0;
|
|
this.bufpos = -1;
|
|
return readChar();
|
|
}
|
|
|
|
protected void AdjustBuffSize() {
|
|
if (this.available == this.bufsize) {
|
|
if (this.tokenBegin > 2048) {
|
|
this.bufpos = 0;
|
|
this.available = this.tokenBegin;
|
|
} else {
|
|
ExpandBuff(false);
|
|
}
|
|
} else if (this.available > this.tokenBegin) {
|
|
this.available = this.bufsize;
|
|
} else if (this.tokenBegin - this.available < 2048) {
|
|
ExpandBuff(true);
|
|
} else {
|
|
this.available = this.tokenBegin;
|
|
}
|
|
}
|
|
|
|
protected void UpdateLineColumn(char paramChar) {
|
|
this.column++;
|
|
if (this.prevCharIsLF) {
|
|
this.prevCharIsLF = false;
|
|
this.line += this.column = 1;
|
|
} else if (this.prevCharIsCR) {
|
|
this.prevCharIsCR = false;
|
|
if (paramChar == '\n') {
|
|
this.prevCharIsLF = true;
|
|
} else {
|
|
this.line += this.column = 1;
|
|
}
|
|
}
|
|
switch (paramChar) {
|
|
case '\r':
|
|
this.prevCharIsCR = true;
|
|
break;
|
|
case '\n':
|
|
this.prevCharIsLF = true;
|
|
break;
|
|
case '\t':
|
|
this.column--;
|
|
this.column += 8 - (this.column & 0x7);
|
|
break;
|
|
}
|
|
this.bufline[this.bufpos] = this.line;
|
|
this.bufcolumn[this.bufpos] = this.column;
|
|
}
|
|
|
|
public char readChar() throws IOException {
|
|
if (this.inBuf > 0) {
|
|
this.inBuf--;
|
|
if (++this.bufpos == this.bufsize)
|
|
this.bufpos = 0;
|
|
return this.buffer[this.bufpos];
|
|
}
|
|
if (++this.bufpos == this.available)
|
|
AdjustBuffSize();
|
|
char c = ReadByte();
|
|
if ((c = ReadByte()) == '\\') {
|
|
UpdateLineColumn(c);
|
|
byte b = 1;
|
|
while (true) {
|
|
if (++this.bufpos == this.available)
|
|
AdjustBuffSize();
|
|
try {
|
|
this.buffer[this.bufpos] = c = ReadByte();
|
|
if ((c = ReadByte()) != '\\') {
|
|
UpdateLineColumn(c);
|
|
if (c == 'u' && (b & 0x1) == 1) {
|
|
if (--this.bufpos < 0) {
|
|
this.bufpos = this.bufsize - 1;
|
|
break;
|
|
}
|
|
} else {
|
|
backup(b);
|
|
return '\\';
|
|
}
|
|
} else {
|
|
UpdateLineColumn(c);
|
|
b++;
|
|
continue;
|
|
}
|
|
} catch (IOException iOException) {
|
|
if (b > 1)
|
|
backup(b);
|
|
return '\\';
|
|
}
|
|
try {
|
|
break;
|
|
} catch (IOException iOException) {
|
|
throw new Error("Invalid escape character at line " + this.line + " column " + this.column + ".");
|
|
}
|
|
}
|
|
while ((c = ReadByte()) == 'u')
|
|
this.column++;
|
|
this.buffer[this.bufpos] = c = (char)(hexval(c) << 12 | hexval(ReadByte()) << 8 | hexval(ReadByte()) << 4 | hexval(ReadByte()));
|
|
this.column += 4;
|
|
if (b == 1)
|
|
return c;
|
|
backup(b - 1);
|
|
return '\\';
|
|
}
|
|
UpdateLineColumn(c);
|
|
return c;
|
|
}
|
|
|
|
public int getColumn() {
|
|
return this.bufcolumn[this.bufpos];
|
|
}
|
|
|
|
public int getLine() {
|
|
return this.bufline[this.bufpos];
|
|
}
|
|
|
|
public int getEndColumn() {
|
|
return this.bufcolumn[this.bufpos];
|
|
}
|
|
|
|
public int getEndLine() {
|
|
return this.bufline[this.bufpos];
|
|
}
|
|
|
|
public int getBeginColumn() {
|
|
return this.bufcolumn[this.tokenBegin];
|
|
}
|
|
|
|
public int getBeginLine() {
|
|
return this.bufline[this.tokenBegin];
|
|
}
|
|
|
|
public void backup(int paramInt) {
|
|
this.inBuf += paramInt;
|
|
if ((this.bufpos -= paramInt) < 0)
|
|
this.bufpos += this.bufsize;
|
|
}
|
|
|
|
public JavaCharStream(Reader paramReader, int paramInt1, int paramInt2, int paramInt3) {
|
|
this.inputStream = paramReader;
|
|
this.line = paramInt1;
|
|
this.column = paramInt2 - 1;
|
|
this.available = this.bufsize = paramInt3;
|
|
this.buffer = new char[paramInt3];
|
|
this.bufline = new int[paramInt3];
|
|
this.bufcolumn = new int[paramInt3];
|
|
this.nextCharBuf = new char[4096];
|
|
}
|
|
|
|
public JavaCharStream(Reader paramReader, int paramInt1, int paramInt2) {
|
|
this(paramReader, paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public JavaCharStream(Reader paramReader) {
|
|
this(paramReader, 1, 1, 4096);
|
|
}
|
|
|
|
public void ReInit(Reader paramReader, int paramInt1, int paramInt2, int paramInt3) {
|
|
this.inputStream = paramReader;
|
|
this.line = paramInt1;
|
|
this.column = paramInt2 - 1;
|
|
if (this.buffer == null || paramInt3 != this.buffer.length) {
|
|
this.available = this.bufsize = paramInt3;
|
|
this.buffer = new char[paramInt3];
|
|
this.bufline = new int[paramInt3];
|
|
this.bufcolumn = new int[paramInt3];
|
|
this.nextCharBuf = new char[4096];
|
|
}
|
|
this.prevCharIsLF = this.prevCharIsCR = false;
|
|
this.tokenBegin = this.inBuf = this.maxNextCharInd = 0;
|
|
this.nextCharInd = this.bufpos = -1;
|
|
}
|
|
|
|
public void ReInit(Reader paramReader, int paramInt1, int paramInt2) {
|
|
ReInit(paramReader, paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public void ReInit(Reader paramReader) {
|
|
ReInit(paramReader, 1, 1, 4096);
|
|
}
|
|
|
|
public JavaCharStream(InputStream paramInputStream, int paramInt1, int paramInt2, int paramInt3) {
|
|
this(new InputStreamReader(paramInputStream), paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public JavaCharStream(InputStream paramInputStream, int paramInt1, int paramInt2) {
|
|
this(paramInputStream, paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public JavaCharStream(InputStream paramInputStream) {
|
|
this(paramInputStream, 1, 1, 4096);
|
|
}
|
|
|
|
public void ReInit(InputStream paramInputStream, int paramInt1, int paramInt2, int paramInt3) {
|
|
ReInit(new InputStreamReader(paramInputStream), paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public void ReInit(InputStream paramInputStream, int paramInt1, int paramInt2) {
|
|
ReInit(paramInputStream, paramInt1, paramInt2, 4096);
|
|
}
|
|
|
|
public void ReInit(InputStream paramInputStream) {
|
|
ReInit(paramInputStream, 1, 1, 4096);
|
|
}
|
|
|
|
public String GetImage() {
|
|
return (this.bufpos >= this.tokenBegin) ? new String(this.buffer, this.tokenBegin, this.bufpos - this.tokenBegin + 1) : (new String(this.buffer, this.tokenBegin, this.bufsize - this.tokenBegin) + new String(this.buffer, 0, this.bufpos + 1));
|
|
}
|
|
|
|
public char[] GetSuffix(int paramInt) {
|
|
char[] arrayOfChar = new char[paramInt];
|
|
if (this.bufpos + 1 >= paramInt) {
|
|
System.arraycopy(this.buffer, this.bufpos - paramInt + 1, arrayOfChar, 0, paramInt);
|
|
} else {
|
|
System.arraycopy(this.buffer, this.bufsize - paramInt - this.bufpos - 1, arrayOfChar, 0, paramInt - this.bufpos - 1);
|
|
System.arraycopy(this.buffer, 0, arrayOfChar, paramInt - this.bufpos - 1, this.bufpos + 1);
|
|
}
|
|
return arrayOfChar;
|
|
}
|
|
|
|
public void Done() {
|
|
this.nextCharBuf = null;
|
|
this.buffer = null;
|
|
this.bufline = null;
|
|
this.bufcolumn = null;
|
|
}
|
|
|
|
public void adjustBeginLineColumn(int paramInt1, int paramInt2) {
|
|
int j;
|
|
int i = this.tokenBegin;
|
|
if (this.bufpos >= this.tokenBegin) {
|
|
j = this.bufpos - this.tokenBegin + this.inBuf + 1;
|
|
} else {
|
|
j = this.bufsize - this.tokenBegin + this.bufpos + 1 + this.inBuf;
|
|
}
|
|
byte b = 0;
|
|
int k = 0;
|
|
int m = 0;
|
|
int n = 0;
|
|
int i1 = 0;
|
|
while (b < j && this.bufline[k = i % this.bufsize] == this.bufline[m = ++i % this.bufsize]) {
|
|
this.bufline[k] = paramInt1;
|
|
n = i1 + this.bufcolumn[m] - this.bufcolumn[k];
|
|
this.bufcolumn[k] = paramInt2 + i1;
|
|
i1 = n;
|
|
b++;
|
|
}
|
|
if (b < j) {
|
|
this.bufline[k] = paramInt1++;
|
|
this.bufcolumn[k] = paramInt2 + i1;
|
|
while (b++ < j) {
|
|
if (this.bufline[k = i % this.bufsize] != this.bufline[++i % this.bufsize]) {
|
|
this.bufline[k] = paramInt1++;
|
|
continue;
|
|
}
|
|
this.bufline[k] = paramInt1;
|
|
}
|
|
}
|
|
this.line = this.bufline[k];
|
|
this.column = this.bufcolumn[k];
|
|
}
|
|
}
|