/*
* Copyright 2016 Cel Skeggs.
*
* This file is part of the CCRE, the Common Chicken Runtime Engine.
*
* The CCRE is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* The CCRE is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the CCRE. If not, see <http://www.gnu.org/licenses/>.
*/
package ccre.verifier;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
class ByteArrayDataInput implements DataInput {
private final byte[] bytes;
private final int offset;
private final int length;
private int index;
public ByteArrayDataInput(byte[] bytes, int offset, int length) {
this.bytes = bytes;
this.offset = offset;
this.length = length;
}
public ByteArrayDataInput(byte[] bytes) {
this(bytes, 0, bytes.length);
}
public boolean isEOF() {
return index >= length;
}
@Override
public void readFully(byte[] b, int off, int len) throws EOFException {
if (off < 0 || len < 0 || off + len > b.length) {
throw new IndexOutOfBoundsException();
}
if (len > length - index) {
throw new EOFException();
}
System.arraycopy(bytes, offset + index, b, off, len);
index += len;
}
@Override
public int skipBytes(int len) {
if (len < 0) {
throw new IndexOutOfBoundsException();
}
len = Math.min(len, length - index);
index += len;
return len;
}
@Override
public byte readByte() throws EOFException {
if (index >= length) {
throw new EOFException();
}
return bytes[offset + index++];
}
protected void pushbackOne() throws IOException {
if (index <= 0) {
throw new IOException("Cannot push back at start of stream!");
}
index--;
}
// and all the derived impls
@Override
public void readFully(byte[] b) throws EOFException {
readFully(b, 0, b.length);
}
@Override
public boolean readBoolean() throws EOFException {
return readByte() != 0;
}
@Override
public int readUnsignedByte() throws EOFException {
return readByte() & 0xFF;
}
@Override
public short readShort() throws EOFException {
int a = readByte();
int b = readByte();
return (short) ((a << 8) | (b & 0xFF));
}
@Override
public int readUnsignedShort() throws EOFException {
return readShort() & 0xFFFF;
}
@Override
public char readChar() throws EOFException {
return (char) readShort();
}
@Override
public int readInt() throws EOFException {
int a = readByte() & 0xFF;
int b = readByte() & 0xFF;
int c = readByte() & 0xFF;
int d = readByte() & 0xFF;
return (a << 24) | (b << 16) | (c << 8) | d;
}
@Override
public long readLong() throws EOFException {
long a = readByte() & 0xFFL;
long b = readByte() & 0xFFL;
long c = readByte() & 0xFFL;
long d = readByte() & 0xFFL;
long e = readByte() & 0xFFL;
long f = readByte() & 0xFFL;
long g = readByte() & 0xFFL;
long h = readByte() & 0xFFL;
return (a << 56) | (b << 48) | (c << 40) | (d << 32) | (e << 24) | (f << 16) | (g << 8) | h;
}
@Override
public float readFloat() throws EOFException {
return Float.intBitsToFloat(readInt());
}
@Override
public double readDouble() throws EOFException {
return Double.longBitsToDouble(readLong());
}
@Override
public String readLine() throws IOException {
StringBuilder sb = new StringBuilder();
while (true) {
char c = (char) readUnsignedByte();
if (c == '\n') {
break;
} else if (c == '\r') {
if (readUnsignedByte() != '\n') {
pushbackOne();
}
break;
} else {
sb.append(c);
}
}
return sb.toString();
}
@Override
public String readUTF() throws IOException {
return DataInputStream.readUTF(this);
}
}