/**
* Copyright 2000-2009 DFKI GmbH.
* All Rights Reserved. Use is subject to license terms.
*
* This file is part of MARY TTS.
*
* MARY TTS 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, version 3 of the License.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package marytts.util.io;
/**
* LEDataInputStream.java
* copyright (c) 1998-2007 Roedy Green, Canadian Mind* Products
* Very similar to DataInputStream except it reads
* little-endian instead of big-endian binary data. We can't extend
* DataInputStream directly since it has only final methods, though
* DataInputStream itself is not final. This forces us implement
* LEDataInputStream with a DataInputStream object, and use wrapper methods.
*/
import java.io.DataInput;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
/**
* reads little endian binary data .
*/
public class LEDataInputStream implements DataInput {
// ------------------------------ FIELDS ------------------------------
/**
* undisplayed copyright notice.
*
* @noinspection UnusedDeclaration
*/
private static final String EMBEDDEDCOPYRIGHT = "copyright (c) 1999-2007 Roedy Green, Canadian Mind Products, http://mindprod.com";
/**
* to get at the big-Endian methods of a basic DataInputStream
*
*
*/
protected final DataInputStream dis;
/**
* to get at the a basic readBytes method.
*
*
*/
protected final InputStream is;
/**
* work array for buffering input.
*
*
*/
protected final byte[] work;
// -------------------------- PUBLIC STATIC METHODS --------------------------
/**
* Note. This is a STATIC method!
*
* @param in
* stream to read UTF chars from (endian irrelevant)
*
* @return string from stream
*
* @throws IOException
* if read fails.
*/
public static String readUTF(DataInput in) throws IOException {
return DataInputStream.readUTF(in);
}
// -------------------------- PUBLIC INSTANCE METHODS --------------------------
/**
* constructor.
*
* @param in
* binary inputstream of little-endian data.
*/
public LEDataInputStream(InputStream in) {
this.is = in;
this.dis = new DataInputStream(in);
work = new byte[8];
}
public LEDataInputStream(String filename) throws FileNotFoundException {
this(new FileInputStream(filename));
}
/**
* close.
*
* @throws IOException
* if close fails.
*/
public final void close() throws IOException {
dis.close();
}
/**
* Read bytes. Watch out, read may return fewer bytes than requested.
*
* @param ba
* where the bytes go.
* @param off
* offset in buffer, not offset in file.
* @param len
* count of bytes to read.
*
* @return how many bytes read.
*
* @throws IOException
* if read fails.
*/
public final int read(byte ba[], int off, int len) throws IOException {
// For efficiency, we avoid one layer of wrapper
return is.read(ba, off, len);
}
/**
* read only a one-byte boolean.
*
* @return true or false.
*
* @throws IOException
* if read fails.
* @see java.io.DataInput#readBoolean()
*/
public final boolean readBoolean() throws IOException {
return dis.readBoolean();
}
public final boolean[] readBoolean(int len) throws IOException {
boolean[] ret = new boolean[len];
for (int i = 0; i < len; i++)
ret[i] = readBoolean();
return ret;
}
/**
* read byte.
*
* @return the byte read.
*
* @throws IOException
* if read fails.
* @see java.io.DataInput#readByte()
*/
public final byte readByte() throws IOException {
return dis.readByte();
}
public final byte[] readByte(int len) throws IOException {
byte[] ret = new byte[len];
for (int i = 0; i < len; i++)
ret[i] = readByte();
return ret;
}
/**
* Read on char. like DataInputStream.readChar except little endian.
*
* @return little endian 16-bit unicode char from the stream.
*
* @throws IOException
* if read fails.
*/
public final char readChar() throws IOException {
dis.readFully(work, 0, 2);
return (char) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
}
public final char[] readChar(int len) throws IOException {
char[] ret = new char[len];
for (int i = 0; i < len; i++)
ret[i] = readChar();
return ret;
}
/**
* Read a double. like DataInputStream.readDouble except little endian.
*
* @return little endian IEEE double from the datastream.
* @throws IOException
* IOException
*/
public final double readDouble() throws IOException {
return Double.longBitsToDouble(readLong());
}
public final double[] readDouble(int len) throws IOException {
double[] ret = new double[len];
for (int i = 0; i < len; i++)
ret[i] = readDouble();
return ret;
}
public final int[] readDoubleToInt(int len) throws IOException {
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = (int) readDouble();
return ret;
}
/**
* Read one float. Like DataInputStream.readFloat except little endian.
*
* @return little endian IEEE float from the datastream.
*
* @throws IOException
* if read fails.
*/
public final float readFloat() throws IOException {
return Float.intBitsToFloat(readInt());
}
public final float[] readFloat(int len) throws IOException {
float[] ret = new float[len];
for (int i = 0; i < len; i++)
ret[i] = readFloat();
return ret;
}
/**
* Read bytes until the array is filled.
*
* @see java.io.DataInput#readFully(byte[])
*/
public final void readFully(byte ba[]) throws IOException {
dis.readFully(ba, 0, ba.length);
}
/**
* Read bytes until the count is satisfied.
*
* @throws IOException
* if read fails.
* @see java.io.DataInput#readFully(byte[],int,int)
*/
public final void readFully(byte ba[], int off, int len) throws IOException {
dis.readFully(ba, off, len);
}
/**
* Read an int, 32-bits. Like DataInputStream.readInt except little endian.
*
* @return little-endian binary int from the datastream
*
* @throws IOException
* if read fails.
*/
public final int readInt() throws IOException {
dis.readFully(work, 0, 4);
return (work[3]) << 24 | (work[2] & 0xff) << 16 | (work[1] & 0xff) << 8 | (work[0] & 0xff);
}
public final int[] readInt(int len) throws IOException {
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = readInt();
return ret;
}
/**
* Read a line.
*
* @return a rough approximation of the 8-bit stream as a 16-bit unicode string
* @throws IOException
* IOException
* @deprecated This method does not properly convert bytes to characters. Use a Reader instead with a little-endian encoding.
*/
public final String readLine() throws IOException {
return dis.readLine();
}
/**
* read a long, 64-bits. Like DataInputStream.readLong except little endian.
*
* @return little-endian binary long from the datastream.
* @throws IOException
* IOException
*/
public final long readLong() throws IOException {
dis.readFully(work, 0, 8);
return (long) (work[7]) << 56 |
/* long cast needed or shift done modulo 32 */
(long) (work[6] & 0xff) << 48 | (long) (work[5] & 0xff) << 40 | (long) (work[4] & 0xff) << 32
| (long) (work[3] & 0xff) << 24 | (long) (work[2] & 0xff) << 16 | (long) (work[1] & 0xff) << 8
| (long) (work[0] & 0xff);
}
public final long[] readLong(int len) throws IOException {
long[] ret = new long[len];
for (int i = 0; i < len; i++)
ret[i] = readLong();
return ret;
}
/**
* Read short, 16-bits. Like DataInputStream.readShort except little endian.
*
* @return little endian binary short from stream.
*
* @throws IOException
* if read fails.
*/
public final short readShort() throws IOException {
dis.readFully(work, 0, 2);
return (short) ((work[1] & 0xff) << 8 | (work[0] & 0xff));
}
public final short[] readShort(int len) throws IOException {
short[] ret = new short[len];
for (int i = 0; i < len; i++)
ret[i] = readShort();
return ret;
}
/**
* Read UTF counted string.
*
* @return String read.
*/
public final String readUTF() throws IOException {
return dis.readUTF();
}
/**
* Read an unsigned byte. Note: returns an int, even though says Byte (non-Javadoc)
*
* @throws IOException
* if read fails.
* @see java.io.DataInput#readUnsignedByte()
*/
public final int readUnsignedByte() throws IOException {
return dis.readUnsignedByte();
}
public final int[] readUnsignedByte(int len) throws IOException {
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = readUnsignedByte();
return ret;
}
/**
* Read an unsigned short, 16 bits. Like DataInputStream.readUnsignedShort except little endian. Note, returns int even though
* it reads a short.
*
* @return little-endian int from the stream.
*
* @throws IOException
* if read fails.
*/
public final int readUnsignedShort() throws IOException {
dis.readFully(work, 0, 2);
return ((work[1] & 0xff) << 8 | (work[0] & 0xff));
}
public final int[] readUnsignedShort(int len) throws IOException {
int[] ret = new int[len];
for (int i = 0; i < len; i++)
ret[i] = readUnsignedShort();
return ret;
}
/**
* <p>
* Skip over bytes in the stream. See the general contract of the <code>skipBytes</code> method of <code>DataInput</code>.
* </p>
* Bytes for this operation are read from the contained input stream.
*
* @param n
* the number of bytes to be skipped.
*
* @return the actual number of bytes skipped.
*
* @throws IOException
* if an I/O error occurs.
*/
public final int skipBytes(int n) throws IOException {
return dis.skipBytes(n);
}
}// end class LEDataInputStream