ObjectEndianInputStream.java
package nl.tudelft.simulation.dsol.animation.gis.io;
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
/**
* This class enables the object inputstream to be switched from big endian (default in Java) to little endian. The class works
* exactly like an ObjectInputStream.
* <p>
* Copyright (c) 2020-2024 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
* for project information <a href="https://simulation.tudelft.nl/dsol/manual/" target="_blank">DSOL Manual</a>. The DSOL
* project is distributed under a three-clause BSD-style license, which can be found at
* <a href="https://https://simulation.tudelft.nl/dsol/docs/latest/license.html" target="_blank">DSOL License</a>.
* </p>
* @author <a href="https://www.tudelft.nl/averbraeck">Alexander Verbraeck</a>
*/
public class ObjectEndianInputStream implements DataInput
{
/** the datainput stream. */
private DataInputStream dataInputStream;
/** the inputStream. */
private InputStream inputStream;
/** an 8byte buffer. */
private byte[] buffer = new byte[8];
/** the code. */
private Endianness endianness = Endianness.BIG_ENDIAN;
/**
* constructs a new ObjectEndianInputStream.
* @param inputStream InputStream; the inputStream to use
*/
public ObjectEndianInputStream(final InputStream inputStream)
{
this.inputStream = inputStream;
this.dataInputStream = new DataInputStream(inputStream);
}
/** {@inheritDoc} */
@Override
public short readShort() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readShort();
}
this.dataInputStream.readFully(this.buffer, 0, 2);
return (short) ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
}
/** {@inheritDoc} */
@Override
public int readUnsignedShort() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readUnsignedShort();
}
this.dataInputStream.readFully(this.buffer, 0, 2);
return ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
}
/** {@inheritDoc} */
@Override
public char readChar() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readChar();
}
this.dataInputStream.readFully(this.buffer, 0, 2);
return (char) ((this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff));
}
/** {@inheritDoc} */
@Override
public int readInt() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readInt();
}
this.dataInputStream.readFully(this.buffer, 0, 4);
return (this.buffer[3]) << 24 | (this.buffer[2] & 0xff) << 16 | (this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff);
}
/** {@inheritDoc} */
@Override
public long readLong() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readLong();
}
this.dataInputStream.readFully(this.buffer, 0, 8);
return (long) (this.buffer[7]) << 56 | (long) (this.buffer[6] & 0xff) << 48 | (long) (this.buffer[5] & 0xff) << 40
| (long) (this.buffer[4] & 0xff) << 32 | (long) (this.buffer[3] & 0xff) << 24
| (long) (this.buffer[2] & 0xff) << 16 | (long) (this.buffer[1] & 0xff) << 8 | (this.buffer[0] & 0xff);
}
/** {@inheritDoc} */
@Override
public float readFloat() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readFloat();
}
return Float.intBitsToFloat(readInt());
}
/** {@inheritDoc} */
@Override
public double readDouble() throws IOException
{
if (this.endianness.equals(Endianness.BIG_ENDIAN))
{
return this.dataInputStream.readDouble();
}
return Double.longBitsToDouble(readLong());
}
/**
* reads b from the stream.
* @param b byte[]; byte
* @return in the value
* @throws IOException on failure
*/
public int read(final byte[] b) throws IOException
{
return this.inputStream.read(b);
}
/**
* reads b from the stream.
* @param b byte[]; byte
* @param off int; offset
* @param len int; length
* @return in the value
* @throws IOException on failure
*/
public int read(final byte[] b, final int off, final int len) throws IOException
{
return this.inputStream.read(b, off, len);
}
/** {@inheritDoc} */
@Override
public void readFully(final byte[] b) throws IOException
{
this.dataInputStream.readFully(b, 0, b.length);
}
/** {@inheritDoc} */
@Override
public void readFully(final byte[] b, final int off, final int len) throws IOException
{
this.dataInputStream.readFully(b, off, len);
}
/** {@inheritDoc} */
@Override
public int skipBytes(final int n) throws IOException
{
return this.dataInputStream.skipBytes(n);
}
/** {@inheritDoc} */
@Override
public boolean readBoolean() throws IOException
{
return this.dataInputStream.readBoolean();
}
/** {@inheritDoc} */
@Override
public byte readByte() throws IOException
{
return this.dataInputStream.readByte();
}
/** {@inheritDoc} */
@Override
public int readUnsignedByte() throws IOException
{
return this.dataInputStream.readUnsignedByte();
}
/** {@inheritDoc} */
@Override
public String readUTF() throws IOException
{
return this.dataInputStream.readUTF();
}
/** {@inheritDoc} */
@Override
public String readLine()
{
throw new UnsupportedOperationException("Binary reading does not support readLine method");
}
/**
* reads UTF from the stream.
* @param dataInput DataInput; data input
* @return String the value
* @throws IOException on read failure
*/
public static final String readUTF(final DataInput dataInput) throws IOException
{
return DataInputStream.readUTF(dataInput);
}
/**
* @throws IOException on close failure
*/
public void close() throws IOException
{
this.dataInputStream.close();
}
/**
* Return the Endianness, i.e., big endian or little endian encoding.
* @return Endianness; big endian or little endian encoding
*/
public Endianness getEndianness()
{
return this.endianness;
}
/**
* Set the Endianness, i.e., big endian or little endian encoding.
* @param endianness Endianness; big endian or little endian encoding
*/
public void setEndianness(final Endianness endianness)
{
this.endianness = endianness;
}
}