/* This file is part of the OdinMS Maple Story Server Copyright (C) 2008 ~ 2010 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 version 3 as published by the Free Software Foundation. You may not use, modify or distribute this program under any other version of the GNU Affero General Public 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 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 final ByteInputStream bs; /** * Class constructor - Wraps the accessor around a stream of bytes. * * @param bs The byte stream to wrap the accessor around. */ public GenericLittleEndianAccessor(final ByteInputStream bs) { this.bs = bs; } @Override public final int readByteAsInt() { return bs.readByte(); } /** * Read a single byte from the stream. * * @return The byte read. * @see ByteInputStream#readByte */ @Override public final byte readByte() { return (byte) bs.readByte(); } /** * Reads an integer from the stream. * * @return The integer read. */ @Override public final int readInt() { final int byte1 = bs.readByte(); final int byte2 = bs.readByte(); final int byte3 = bs.readByte(); final int byte4 = bs.readByte(); return (byte4 << 24) + (byte3 << 16) + (byte2 << 8) + byte1; } /** * Reads a short integer from the stream. * * @return The short read. */ @Override public final short readShort() { final int byte1 = bs.readByte(); final int byte2 = bs.readByte(); return (short) ((byte2 << 8) + byte1); } /** * Reads a single character from the stream. * * @return The character read. */ @Override public final char readChar() { return (char) readShort(); } /** * Reads a long integer from the stream. * * @return The long integer read. */ @Override public final long readLong() { final int byte1 = bs.readByte(); final int byte2 = bs.readByte(); final int byte3 = bs.readByte(); final int byte4 = bs.readByte(); final long byte5 = bs.readByte(); final long byte6 = bs.readByte(); final long byte7 = bs.readByte(); final long byte8 = bs.readByte(); return (long) ((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 final float readFloat() { return Float.intBitsToFloat(readInt()); } /** * Reads a double-precision integer from the stream. * * @return The double-type integer read. */ @Override public final 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. */ @Override public final String readAsciiString(final int n) { final char ret[] = new char[n]; for (int x = 0; x < n; x++) { ret[x] = (char) readByte(); } return new String(ret); } /** * Reads a null-terminated string from the stream. * * @return The string read. */ @Override 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 ByteInputStream#getBytesRead() */ @Override public final 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 final String readMapleAsciiString() { return readAsciiString(readShort()); } /** * 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); } /** * 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 final byte[] read(final int num) { byte[] ret = new byte[num]; for (int x = 0; x < num; x++) { ret[x] = readByte(); } return ret; } /** * Skips the current position of the stream <code>num</code> bytes ahead. * * @param num Number of bytes to skip. */ @Override public void skip(final int num) { for (int x = 0; x < num; x++) { readByte(); } } /** * @see ByteInputStream#available */ @Override public final long available() { return bs.available(); } /** * @see java.lang.Object#toString */ @Override public final String toString() { return bs.toString(); } @Override public final String toString(final boolean b) { return bs.toString(b); } }