/*
OrpheusMS: MapleStory Private Server based on OdinMS
Copyright (C) 2012 Aaron Weiss <aaron@deviant-core.net>
Patrick Huy <patrick.huy@frz.cc>
Matthias Butz <matze@odinms.de>
Jan Christian Meyer <vimes@odinms.de>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
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 Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package tools.data.input;
import java.awt.Point;
import java.io.ByteArrayOutputStream;
/**
* Provides a generic interface to a Little Endian stream of bytes.
*
* @version 1.0
* @author Frz
* @since Revision 323
*/
public class GenericLittleEndianAccessor implements LittleEndianAccessor {
private ByteInputStream bs;
/**
* Class constructor - Wraps the accessor around a stream of bytes.
*
* @param bs
* The byte stream to wrap the accessor around.
*/
public GenericLittleEndianAccessor(ByteInputStream bs) {
this.bs = bs;
}
/**
* Read a single byte from the stream.
*
* @return The byte read.
* @see tools.data.input.ByteInputStream#readByte
*/
@Override
public byte readByte() {
return (byte) bs.readByte();
}
/**
* Reads an integer from the stream.
*
* @return The integer read.
*/
@Override
public int readInt() {
return bs.readByte() + (bs.readByte() << 8) + (bs.readByte() << 16) + (bs.readByte() << 24);
}
/**
* Reads a short integer from the stream.
*
* @return The short read.
*/
@Override
public short readShort() {
return (short) (bs.readByte() + (bs.readByte() << 8));
}
/**
* Reads a single character from the stream.
*
* @return The character read.
*/
@Override
public char readChar() {
return (char) readShort();
}
/**
* Reads a long integer from the stream.
*
* @return The long integer read.
*/
@Override
public long readLong() {
long byte1 = bs.readByte();
long byte2 = bs.readByte();
long byte3 = bs.readByte();
long byte4 = bs.readByte();
long byte5 = bs.readByte();
long byte6 = bs.readByte();
long byte7 = bs.readByte();
long byte8 = bs.readByte();
return (byte8 << 56) + (byte7 << 48) + (byte6 << 40) + (byte5 << 32) + (byte4 << 24) + (byte3 << 16) + (byte2 << 8) + byte1;
}
/**
* Reads a floating point integer from the stream.
*
* @return The float-type integer read.
*/
@Override
public float readFloat() {
return Float.intBitsToFloat(readInt());
}
/**
* Reads a double-precision integer from the stream.
*
* @return The double-type integer read.
*/
@Override
public double readDouble() {
return Double.longBitsToDouble(readLong());
}
/**
* Reads an ASCII string from the stream with length <code>n</code>.
*
* @param n
* Number of characters to read.
* @return The string read.
*/
public final String readAsciiString(int n) {
char ret[] = new char[n];
for (int x = 0; x < n; x++) {
ret[x] = (char) readByte();
}
return String.valueOf(ret);
}
/**
* Reads a null-terminated string from the stream.
*
* @return The string read.
*/
public final String readNullTerminatedAsciiString() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte b;
while (true) {
b = readByte();
if (b == 0) {
break;
}
baos.write(b);
}
byte[] buf = baos.toByteArray();
char[] chrBuf = new char[buf.length];
for (int x = 0; x < buf.length; x++) {
chrBuf[x] = (char) buf[x];
}
return String.valueOf(chrBuf);
}
/**
* Gets the number of bytes read from the stream so far.
*
* @return A long integer representing the number of bytes read.
* @see tools.data.input.ByteInputStream#getBytesRead()
*/
public long getBytesRead() {
return bs.getBytesRead();
}
/**
* Reads a MapleStory convention lengthed ASCII string. This consists of a
* short integer telling the length of the string, then the string itself.
*
* @return The string read.
*/
@Override
public String readMapleAsciiString() {
return readAsciiString(readShort());
}
/**
* Reads <code>num</code> bytes off the stream.
*
* @param num
* The number of bytes to read.
* @return An array of bytes with the length of <code>num</code>
*/
@Override
public byte[] read(int num) {
byte[] ret = new byte[num];
for (int x = 0; x < num; x++) {
ret[x] = readByte();
}
return ret;
}
/**
* Reads a MapleStory Position information. This consists of 2 short
* integer.
*
* @return The Position read.
*/
@Override
public final Point readPos() {
final int x = readShort();
final int y = readShort();
return new Point(x, y);
}
/**
* Skips the current position of the stream <code>num</code> bytes ahead.
*
* @param num
* Number of bytes to skip.
*/
@Override
public void skip(int num) {
for (int x = 0; x < num; x++) {
readByte();
}
}
/**
* @see tools.data.input.ByteInputStream#available
*/
@Override
public long available() {
return bs.available();
}
/**
* @see java.lang.Object#toString
*/
@Override
public String toString() {
return bs.toString();
}
}