/*
* Copyright (C) 2007, 2009, 2010 IsmAvatar <IsmAvatar@gmail.com>
* Copyright (C) 2006, 2007 Clam <clamisgood@gmail.com>
*
* This file is part of LibMaker.
* LibMaker is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.libmaker.file;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.lateralgm.libmaker.Messages;
public class StreamDecoder extends InputStream
{
protected InputStream in;
protected int pos = 0;
protected int markPos = 0;
/**
* This allows extending classes to override the
* stream wrapping behaviour.
*/
protected StreamDecoder()
{
}
public StreamDecoder(InputStream in)
{
if (in instanceof BufferedInputStream)
this.in = in;
else
this.in = new BufferedInputStream(in);
}
public StreamDecoder(String path) throws FileNotFoundException
{
in = new BufferedInputStream(new FileInputStream(path));
}
public StreamDecoder(File f) throws FileNotFoundException
{
in = new BufferedInputStream(new FileInputStream(f));
}
public int read(byte b[]) throws IOException
{
return read(b,0,b.length);
}
public int read(byte b[], int off, int len) throws IOException
{
int read = in.read(b,off,len);
if (read != len)
{
String error = Messages.format("StreamDecoder.UNEXPECTED_EOF",getPosString()); //$NON-NLS-1$
throw new IOException(error);
}
pos += len;
return read;
}
public int read() throws IOException
{
int t = in.read();
if (t == -1)
{
String error = Messages.format("StreamDecoder.UNEXPECTED_EOF",getPosString()); //$NON-NLS-1$
throw new IOException(error);
}
pos++;
return t;
}
public int read2() throws IOException
{
int a = read();
int b = read();
return (a | (b << 8));
}
public int read3() throws IOException
{
int a = read();
int b = read();
int c = read();
return (a | (b << 8) | (c << 16));
}
public int read4() throws IOException
{
int a = read();
int b = read();
int c = read();
int d = read();
return (a | (b << 8) | (c << 16) | (d << 24));
}
public double readD() throws IOException
{
byte[] b = new byte[8];
read(b);
long r = b[0] & 0xFF;
for (int i = 1; i < 8; i++)
r |= (b[i] & 0xFFL) << (8 * i);
return Double.longBitsToDouble(r);
}
public void close() throws IOException
{
in.close();
}
public long skip(long length) throws IOException
{
long total = in.skip(length);
while (total < length)
{
total += in.skip(length - total);
}
pos += (int) length;
return total;
}
public InputStream getInputStream()
{
return in;
}
public boolean markSupported()
{
return in.markSupported();
}
public synchronized void mark(int readlimit)
{
in.mark(readlimit);
markPos = pos;
}
public synchronized void reset() throws IOException
{
in.reset();
pos = markPos;
}
public long getPos()
{
return this.pos;
}
public void seek(final long pBytes) throws IOException
{
final long toSkip = pBytes - getPos();
if (toSkip >= 0)
{
final long lBytesSkipped = skip(toSkip);
if (lBytesSkipped != toSkip)
{
throw new IOException(Messages.format("StreamDecoder.SEEK_SHORT",toSkip,lBytesSkipped)); //$NON-NLS-1$
}
}
else
{
throw new IllegalArgumentException(Messages.format("StreamDecoder.SEEK_PASSED",pBytes, //$NON-NLS-1$
getPosString(),toSkip));
}
}
protected String getPosString()
{
return Integer.toString(pos);
}
}