// **********************************************************************
//
// <copyright>
//
// BBN Technologies
// 10 Moulton Street
// Cambridge, MA 02138
// (617) 873-8000
//
// Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/dataAccess/shape/input/LittleEndianInputStream.java,v $
// $RCSfile: LittleEndianInputStream.java,v $
// $Revision: 1.6 $
// $Date: 2006/08/25 15:36:15 $
// $Author: dietrick $
//
// **********************************************************************
package com.bbn.openmap.dataAccess.shape.input;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UTFDataFormatException;
/**
* Provides methods for reading data streams in Little Endian and Big Endian.
* Adapted from the book, Java IO, Elliotte Rusty Harold, Ch. 7.
*
* @author Doug Van Auken
*/
public class LittleEndianInputStream
extends DataInputStream {
DataInputStream in;
/**
* Constructor
*
* @param in An input stream that this is chained to.
*/
public LittleEndianInputStream(InputStream in) {
super(in);
this.in = new DataInputStream(in);
}
/**
* Constructs a string from the underlying input stream
*
* @param length The length of bytes to read
*/
public String readString(int length)
throws IOException {
byte[] array = new byte[length];
readFully(array);
String s = new String(array);
return s.trim();
}
/**
* Translates little endian short to big endian short
*
* @return short A big endian short
*/
public short readLEShort()
throws IOException {
int byte1 = in.read();
int byte2 = in.read();
if (byte2 == -1)
throw new EOFException();
return (short) ((byte2 << 8) + byte1);
}
/**
* Translates a little endian unsigned short to big endian int
*
* @return int A big endian short
*/
public int readLEUnsignedShort()
throws IOException {
int byte1 = in.read();
int byte2 = in.read();
if (byte2 == -1)
throw new EOFException();
return (byte2 << 8) + byte1;
}
/**
* Translates a little endian char into a big endian char
*
* @return char A big endian char
*/
public char readLEChar()
throws IOException {
int byte1 = in.read();
int byte2 = in.read();
if (byte2 == -1)
throw new EOFException();
return (char) ((byte2 << 8) + byte1);
}
/**
* Translates a little endian int into a big endian int
*
* @return int A big endian int
*/
public int readLEInt()
throws IOException {
int byte1, byte2, byte3, byte4;
synchronized (this) {
byte1 = in.read();
byte2 = in.read();
byte3 = in.read();
byte4 = in.read();
}
if (byte4 == -1) {
throw new EOFException();
}
return (byte4 << 24) + (byte3 << 16) + (byte2 << 8) + byte1;
}
/**
* Translates a little endian long into a big endian long
*
* @return long A big endian long
*/
public long readLELong()
throws IOException {
long byte1 = in.read();
long byte2 = in.read();
long byte3 = in.read();
long byte4 = in.read();
long byte5 = in.read();
long byte6 = in.read();
long byte7 = in.read();
long byte8 = in.read();
if (byte8 == -1) {
throw new EOFException();
}
return (byte8 << 56) + (byte7 << 48) + (byte6 << 40) + (byte5 << 32) + (byte4 << 24) + (byte3 << 16) + (byte2 << 8) + byte1;
}
public String readLEUTF()
throws IOException {
int byte1 = in.read();
int byte2 = in.read();
if (byte2 == -1)
throw new EOFException();
int numbytes = (byte1 << 8) + byte2;
char result[] = new char[numbytes];
int numread = 0;
int numchars = 0;
while (numread < numbytes) {
int c1 = readUnsignedByte();
int c2, c3;
// look at the first four bits of c1 to determine how many
// bytes in this char
int test = c1 >> 4;
if (test < 8) { // one byte
numread++;
result[numchars++] = (char) c1;
} else if (test == 12 || test == 13) { // two bytes
numread += 2;
if (numread > numbytes)
throw new UTFDataFormatException();
c2 = readUnsignedByte();
if ((c2 & 0xC0) != 0x80)
throw new UTFDataFormatException();
result[numchars++] = (char) (((c1 & 0x1F) << 6) | (c2 & 0x3F));
} else if (test == 14) { // three bytes
numread += 3;
if (numread > numbytes)
throw new UTFDataFormatException();
c2 = readUnsignedByte();
c3 = readUnsignedByte();
if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80)) {
throw new UTFDataFormatException();
}
result[numchars++] = (char) (((c1 & 0x0F) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
} else { // malformed
throw new UTFDataFormatException();
}
} // end while
return new String(result, 0, numchars);
}
/**
* Reads a little endian double into a big endian double
*
* @return double A big endian double
*/
public final double readLEDouble()
throws IOException {
return Double.longBitsToDouble(this.readLELong());
}
/**
* Reads a little endian float into a big endian float
*
* @return float A big endian float
*/
public final float readLEFloat()
throws IOException {
return Float.intBitsToFloat(this.readLEInt());
}
}