/*
Copyright (C) 2011 ApPeAL Group, Politecnico di Torino
This file is part of TraCI4J.
TraCI4J is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
TraCI4J 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with TraCI4J. If not, see <http://www.gnu.org/licenses/>.
*/
package de.uniluebeck.itm.tcpip;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;
public class FastStorage extends Storage {
public static class NotReadableException extends IllegalStateException {
private static final long serialVersionUID = 7821333062605489575L;
}
public static class NotWritableException extends IllegalStateException {
private static final long serialVersionUID = 7821333062605489575L;
}
byte[] data;
boolean readable;
ByteArrayInputStream bais;
ByteArrayOutputStream baos;
DataInputStream dis;
DataOutputStream dos;
private int readBytes;
public FastStorage() {
setWritable();
}
public FastStorage(byte[] packet) {
// super(packet);
data = packet;
setReadable();
}
private void setWritable() {
readable = false;
baos = new ByteArrayOutputStream();
dos = new DataOutputStream(baos);
}
private void setReadable() {
readable = true;
bais = new ByteArrayInputStream(data);
dis = new DataInputStream(bais);
}
public FastStorage(short[] packet) {
this(packet, 0, packet.length);
}
public FastStorage(short[] packet, int offset, int length) {
data = new byte[length];
for(int i=0; i<length; i++)
data[i] = checkByteRange(packet[i+offset]);
readable = false;
setWritable();
}
private static byte checkByteRange(short value) {
if (value < -128 || value > 127)
throw new IllegalArgumentException("Byte value may only range from -128 to 127.");
return (byte) value;
}
@Override
public int position() {
if(readable)
return readBytes;
else
throw new NotReadableException();
}
@Override
public short readByte() throws IllegalStateException {
if(readable)
{
try {
readBytes++;
return dis.readByte();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public double readDouble() throws IllegalStateException {
if(readable)
{
try {
readBytes += 8;
return dis.readDouble();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public float readFloat() throws IllegalStateException {
if(readable)
{
try {
readBytes += 4;
return dis.readFloat();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public int readInt() throws IllegalStateException {
if(readable)
{
try {
readBytes += 4;
return dis.readInt();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public int readShort() throws IllegalStateException {
if(readable)
{
try {
readBytes += 2;
return dis.readShort();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
private String readString(String charset) throws IllegalStateException {
if(readable)
{
try {
int length = dis.readInt();
byte[] buf = new byte[length];
dis.read(buf);
readBytes += 4 + length;
return new String(buf, charset);
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public String readStringUTF8() throws IllegalArgumentException
{
return readString("UTF-8");
}
@Override
public String readStringASCII() throws IllegalArgumentException
{
return readString("US-ASCII");
}
@Override
public String readStringISOLATIN1() throws IllegalArgumentException
{
return readString("ISO-8859-1");
}
@Override
public String readStringUTF16BE() throws IllegalArgumentException
{
return readString("UTF-16BE");
}
@Override
public String readStringUTF16LE() throws IllegalArgumentException
{
return readString("UTF-16LE");
}
@Override
public short readUnsignedByte() throws IllegalStateException {
if(readable)
{
try {
readBytes++;
return (short) dis.readUnsignedByte();
}
catch (EOFException ee) { throw new IllegalStateException(ee); }
catch (IOException e) { throw new RuntimeException(e); }
}
throw new NotReadableException();
}
@Override
public void reset() {
throw new UnsupportedOperationException("TBD");
}
@Override
public int size() {
if(readable)
return data.length;
else
throw new NotReadableException();
}
@Override
public boolean validPos() {
return true;
}
@Override
public void writeByte(int value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeByte(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeByte(short value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeByte(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeDouble(double value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeDouble(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeFloat(float value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeFloat(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeInt(int value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeInt(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeShort(int value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeShort(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeStringASCII(String value) throws IllegalArgumentException {
throw new UnsupportedOperationException("TBD");
}
@Override
public void writeStringISOLATIN1(String value)
throws IllegalArgumentException {
throw new UnsupportedOperationException("TBD");
}
/* (non-Javadoc)
* @see de.uniluebeck.itm.tcpip.Storage#writeStringUTF16BE(java.lang.String)
*/
@Override
public void writeStringUTF16BE(String value)
throws IllegalArgumentException {
throw new UnsupportedOperationException("TBD");
}
/* (non-Javadoc)
* @see de.uniluebeck.itm.tcpip.Storage#writeStringUTF16LE(java.lang.String)
*/
@Override
public void writeStringUTF16LE(String value)
throws IllegalArgumentException {
throw new UnsupportedOperationException("TBD");
}
@Override
public void writeStringUTF8(String value) throws IllegalArgumentException {
if(!readable)
try {
dos.writeUTF(value);
} catch (IOException e) { throw new RuntimeException(e); }
else
throw new NotWritableException();
}
@Override
public void writeUnsignedByte(int value) throws IllegalArgumentException {
writeByte(value);
}
@Override
public void writeUnsignedByte(short value) throws IllegalArgumentException {
writeByte(value);
}
public byte[] getBytes() {
if(!readable)
return baos.toByteArray();
else
throw new NotWritableException();
}
}