package NET.worlds.network; import java.io.EOFException; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UTFDataFormatException; public class ServerInputStream extends FilterInputStream { private int _packetSize; private int _version; public ServerInputStream(InputStream in) { super(in); assert in != null; this._packetSize = 0; this._version = 24; } public ServerInputStream(InputStream in, int vers) { super(in); assert in != null; this._packetSize = 0; this._version = vers; } public void setVersion(int vers) { this._version = vers; } public int getVersion() { return this._version; } public void readPacketSize() throws IOException { assert this._packetSize == 0; this._packetSize = 1; this._packetSize = this.readUnsignedByte() - 1; if ((this._packetSize & 128) != 0 && this.getVersion() > 24) { this._packetSize = (this._packetSize & 128) * 256 + this.readUnsignedByte() - 1; } } public boolean isEmpty() { return this._packetSize == 0; } public int bytesLeft() { return this._packetSize; } @Override public final int read(byte[] b) throws IOException { assert this._packetSize >= b.length; if (b.length == 0) { return 0; } else { int bytesRead = this.in.read(b, 0, b.length); if (bytesRead < 0) { throw new EOFException(); } else { this._packetSize -= bytesRead; return bytesRead; } } } @Override public final int read(byte[] b, int off, int len) throws IOException { assert this._packetSize >= len; int bytesRead = this.in.read(b, off, len); if (bytesRead < 0) { throw new EOFException(); } else { this._packetSize -= bytesRead; return bytesRead; } } public final void readFully(byte[] b) throws IOException { assert this._packetSize >= b.length; this.readFully(b, 0, b.length); } public final void readFully(byte[] b, int off, int len) throws IOException { assert this._packetSize >= len; this._packetSize -= len; InputStream in = this.in; while (len > 0) { int bytesRead = in.read(b, off, len); if (bytesRead < 0) { throw new EOFException(); } len -= bytesRead; off += bytesRead; } } public void skipBytes(int n) throws IOException { assert this._packetSize >= n; this._packetSize -= n; InputStream in = this.in; while (n > 0) { int bytesSkipped = (int)in.skip(n); if (bytesSkipped < 0) { throw new EOFException(); } n -= bytesSkipped; } } public final byte readByte() throws IOException { if (this._packetSize < 1) { throw new IOException(); } else { int ch = this.in.read(); if (ch < 0) { throw new EOFException(); } else { this._packetSize--; return (byte)ch; } } } public final int readUnsignedByte() throws IOException { if (this._packetSize < 1) { throw new IOException(); } else { int ch = this.in.read(); if (ch < 0) { throw new EOFException(); } else { this._packetSize--; return ch; } } } public final short readShort() throws IOException { assert this._packetSize >= 2; InputStream in = this.in; int ch1 = in.read(); int ch2 = in.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } else { this._packetSize -= 2; return (short)((ch1 << 8) + (ch2 << 0)); } } public final int readUnsignedShort() throws IOException { assert this._packetSize >= 2; InputStream in = this.in; int ch1 = in.read(); int ch2 = in.read(); if ((ch1 | ch2) < 0) { throw new EOFException(); } else { this._packetSize -= 2; return (ch1 << 8) + (ch2 << 0); } } public String readUTF() throws IOException { if (this._packetSize < 1) { throw new IOException(); } else { int utflen = this.readUnsignedByte(); if (this._packetSize < utflen) { throw new UTFDataFormatException(); } else { char[] str = new char[utflen]; int count = 0; int strlen = 0; while (count < utflen) { int c = this.readUnsignedByte(); switch (c >> 4) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: count++; str[strlen++] = (char)c; break; case 8: case 9: case 10: case 11: default: throw new UTFDataFormatException(); case 12: case 13: count += 2; if (count > utflen) { throw new UTFDataFormatException(); } int char2 = this.readUnsignedByte(); if ((char2 & 192) != 128) { throw new UTFDataFormatException(); } str[strlen++] = (char)((c & 31) << 6 | char2 & 63); break; case 14: count += 3; if (count > utflen) { throw new UTFDataFormatException(); } char2 = this.readUnsignedByte(); int char3 = this.readUnsignedByte(); if ((char2 & 192) != 128 || (char3 & 192) != 128) { throw new UTFDataFormatException(); } str[strlen++] = (char)((c & 15) << 12 | (char2 & 63) << 6 | (char3 & 63) << 0); } } return new String(str, 0, strlen); } } } }