Add additional array I/O methods, add ByteBuffer-backed NetInput and NetOutput implementations.

This commit is contained in:
Steven Smith 2015-08-22 21:43:32 -07:00
parent 494805306f
commit 62d5509768
8 changed files with 834 additions and 0 deletions

View file

@ -132,6 +132,93 @@ public interface NetInput {
*/
public int readBytes(byte b[], int offset, int length) throws IOException;
/**
* Reads the next short array.
*
* @param length The length of the short array.
* @return The next short array.
* @throws java.io.IOException If an I/O error occurs.
*/
public short[] readShorts(int length) throws IOException;
/**
* Reads as much data as possible into the given short array.
*
* @param s Short array to read to.
* @return The amount of shorts read, or -1 if no shorts could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readShorts(short s[]) throws IOException;
/**
* Reads the given amount of shorts into the given array at the given offset.
*
* @param s Short array to read to.
* @param offset Offset of the array to read to.
* @param length Length of bytes to read.
* @return The amount of shorts read, or -1 if no shorts could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readShorts(short s[], int offset, int length) throws IOException;
/**
* Reads the next int array.
*
* @param length The length of the int array.
* @return The next int array.
* @throws java.io.IOException If an I/O error occurs.
*/
public int[] readInts(int length) throws IOException;
/**
* Reads as much data as possible into the given int array.
*
* @param i Int array to read to.
* @return The amount of ints read, or -1 if no ints could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readInts(int i[]) throws IOException;
/**
* Reads the given amount of ints into the given array at the given offset.
*
* @param i Int array to read to.
* @param offset Offset of the array to read to.
* @param length Length of bytes to read.
* @return The amount of ints read, or -1 if no ints could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readInts(int i[], int offset, int length) throws IOException;
/**
* Reads the next long array.
*
* @param length The length of the long array.
* @return The next long array.
* @throws java.io.IOException If an I/O error occurs.
*/
public long[] readLongs(int length) throws IOException;
/**
* Reads as much data as possible into the given long array.
*
* @param l Long array to read to.
* @return The amount of longs read, or -1 if no longs could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readLongs(long l[]) throws IOException;
/**
* Reads the given amount of longs into the given array at the given offset.
*
* @param l Long array to read to.
* @param offset Offset of the array to read to.
* @param length Length of bytes to read.
* @return The amount of longs read, or -1 if no longs could be read.
* @throws java.io.IOException If an I/O error occurs.
*/
public int readLongs(long l[], int offset, int length) throws IOException;
/**
* Reads the next string.
*

View file

@ -104,6 +104,57 @@ public interface NetOutput {
*/
public void writeBytes(byte b[], int length) throws IOException;
/**
* Writes a short array.
*
* @param s Short array to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeShorts(short s[]) throws IOException;
/**
* Writes a short array, using the given amount of bytes.
*
* @param s Short array to write.
* @param length Shorts to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeShorts(short s[], int length) throws IOException;
/**
* Writes an int array.
*
* @param i Int array to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeInts(int i[]) throws IOException;
/**
* Writes an int array, using the given amount of bytes.
*
* @param i Int array to write.
* @param length Ints to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeInts(int i[], int length) throws IOException;
/**
* Writes a long array.
*
* @param l Long array to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeLongs(long l[]) throws IOException;
/**
* Writes a long array, using the given amount of bytes.
*
* @param l Long array to write.
* @param length Longs to write.
* @throws java.io.IOException If an I/O error occurs.
*/
public void writeLongs(long l[], int length) throws IOException;
/**
* Writes a string.
*

View file

@ -0,0 +1,261 @@
package org.spacehq.packetlib.io.buffer;
import org.spacehq.packetlib.io.NetInput;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.UUID;
/**
* A NetInput implementation using a ByteBuffer as a backend.
*/
public class ByteBufferNetInput implements NetInput {
private ByteBuffer buffer;
public ByteBufferNetInput(ByteBuffer buffer) {
this.buffer = buffer;
}
public ByteBuffer getByteBuffer() {
return this.buffer;
}
@Override
public boolean readBoolean() throws IOException {
return this.buffer.get() == 1;
}
@Override
public byte readByte() throws IOException {
return this.buffer.get();
}
@Override
public int readUnsignedByte() throws IOException {
return this.buffer.get() & 0xFF;
}
@Override
public short readShort() throws IOException {
return this.buffer.getShort();
}
@Override
public int readUnsignedShort() throws IOException {
return this.buffer.getShort() & 0xFFFF;
}
@Override
public char readChar() throws IOException {
return this.buffer.getChar();
}
@Override
public int readInt() throws IOException {
return this.buffer.getInt();
}
@Override
public int readVarInt() throws IOException {
int value = 0;
int size = 0;
int b;
while(((b = this.readByte()) & 0x80) == 0x80) {
value |= (b & 0x7F) << (size++ * 7);
if(size > 5) {
throw new IOException("VarInt too long (length must be <= 5)");
}
}
return value | ((b & 0x7F) << (size * 7));
}
@Override
public long readLong() throws IOException {
return this.buffer.getLong();
}
@Override
public long readVarLong() throws IOException {
int value = 0;
int size = 0;
int b;
while(((b = this.readByte()) & 0x80) == 0x80) {
value |= (b & 0x7F) << (size++ * 7);
if(size > 10) {
throw new IOException("VarLong too long (length must be <= 10)");
}
}
return value | ((b & 0x7F) << (size * 7));
}
@Override
public float readFloat() throws IOException {
return this.buffer.getFloat();
}
@Override
public double readDouble() throws IOException {
return this.buffer.getDouble();
}
@Override
public byte[] readBytes(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
byte b[] = new byte[length];
this.buffer.get(b);
return b;
}
@Override
public int readBytes(byte[] b) throws IOException {
return this.readBytes(b, 0, b.length);
}
@Override
public int readBytes(byte[] b, int offset, int length) throws IOException {
int readable = this.buffer.remaining();
if(readable <= 0) {
return -1;
}
if(readable < length) {
length = readable;
}
this.buffer.get(b, offset, length);
return length;
}
@Override
public short[] readShorts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
short s[] = new short[length];
for(int index = 0; index < length; index++) {
s[index] = this.readShort();
}
return s;
}
@Override
public int readShorts(short[] s) throws IOException {
return this.readShorts(s, 0, s.length);
}
@Override
public int readShorts(short[] s, int offset, int length) throws IOException {
int readable = this.buffer.remaining();
if(readable <= 0) {
return -1;
}
if(readable < length * 2) {
length = readable / 2;
}
for(int index = offset; index < offset + length; index++) {
s[index] = this.readShort();
}
return length;
}
@Override
public int[] readInts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
int i[] = new int[length];
for(int index = 0; index < length; index++) {
i[index] = this.readInt();
}
return i;
}
@Override
public int readInts(int[] i) throws IOException {
return this.readInts(i, 0, i.length);
}
@Override
public int readInts(int[] i, int offset, int length) throws IOException {
int readable = this.buffer.remaining();
if(readable <= 0) {
return -1;
}
if(readable < length * 4) {
length = readable / 4;
}
for(int index = offset; index < offset + length; index++) {
i[index] = this.readInt();
}
return length;
}
@Override
public long[] readLongs(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
long l[] = new long[length];
for(int index = 0; index < length; index++) {
l[index] = this.readLong();
}
return l;
}
@Override
public int readLongs(long[] l) throws IOException {
return this.readLongs(l, 0, l.length);
}
@Override
public int readLongs(long[] l, int offset, int length) throws IOException {
int readable = this.buffer.remaining();
if(readable <= 0) {
return -1;
}
if(readable < length * 2) {
length = readable / 2;
}
for(int index = offset; index < offset + length; index++) {
l[index] = this.readLong();
}
return length;
}
@Override
public String readString() throws IOException {
int length = this.readVarInt();
byte bytes[] = this.readBytes(length);
return new String(bytes, "UTF-8");
}
@Override
public UUID readUUID() throws IOException {
return new UUID(this.readLong(), this.readLong());
}
@Override
public int available() throws IOException {
return this.buffer.remaining();
}
}

View file

@ -0,0 +1,153 @@
package org.spacehq.packetlib.io.buffer;
import org.spacehq.packetlib.io.NetOutput;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.UUID;
/**
* A NetOutput implementation using a ByteBuf as a backend.
*/
public class ByteBufferNetOutput implements NetOutput {
private ByteBuffer buffer;
public ByteBufferNetOutput(ByteBuffer buffer) {
this.buffer = buffer;
}
public ByteBuffer getByteBuffer() {
return this.buffer;
}
@Override
public void writeBoolean(boolean b) throws IOException {
this.buffer.put(b ? (byte) 1 : 0);
}
@Override
public void writeByte(int b) throws IOException {
this.buffer.put((byte) b);
}
@Override
public void writeShort(int s) throws IOException {
this.buffer.putShort((short) s);
}
@Override
public void writeChar(int c) throws IOException {
this.buffer.putChar((char) c);
}
@Override
public void writeInt(int i) throws IOException {
this.buffer.putInt(i);
}
@Override
public void writeVarInt(int i) throws IOException {
while((i & ~0x7F) != 0) {
this.writeByte((i & 0x7F) | 0x80);
i >>>= 7;
}
this.writeByte(i);
}
@Override
public void writeLong(long l) throws IOException {
this.buffer.putLong(l);
}
@Override
public void writeVarLong(long l) throws IOException {
while((l & ~0x7F) != 0) {
this.writeByte((int) (l & 0x7F) | 0x80);
l >>>= 7;
}
this.writeByte((int) l);
}
@Override
public void writeFloat(float f) throws IOException {
this.buffer.putFloat(f);
}
@Override
public void writeDouble(double d) throws IOException {
this.buffer.putDouble(d);
}
@Override
public void writeBytes(byte b[]) throws IOException {
this.buffer.put(b);
}
@Override
public void writeBytes(byte b[], int length) throws IOException {
this.buffer.put(b, 0, length);
}
@Override
public void writeShorts(short[] s) throws IOException {
this.writeShorts(s, s.length);
}
@Override
public void writeShorts(short[] s, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeShort(s[index]);
}
}
@Override
public void writeInts(int[] i) throws IOException {
this.writeInts(i, i.length);
}
@Override
public void writeInts(int[] i, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeInt(i[index]);
}
}
@Override
public void writeLongs(long[] l) throws IOException {
this.writeLongs(l, l.length);
}
@Override
public void writeLongs(long[] l, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeLong(l[index]);
}
}
@Override
public void writeString(String s) throws IOException {
if(s == null) {
throw new IllegalArgumentException("String cannot be null!");
}
byte[] bytes = s.getBytes("UTF-8");
if(bytes.length > 32767) {
throw new IOException("String too big (was " + s.length() + " bytes encoded, max " + 32767 + ")");
} else {
this.writeVarInt(bytes.length);
this.writeBytes(bytes);
}
}
@Override
public void writeUUID(UUID uuid) throws IOException {
this.writeLong(uuid.getMostSignificantBits());
this.writeLong(uuid.getLeastSignificantBits());
}
@Override
public void flush() throws IOException {
}
}

View file

@ -146,6 +146,105 @@ public class StreamNetInput implements NetInput {
return this.in.read(b, offset, length);
}
@Override
public short[] readShorts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
short s[] = new short[length];
int read = this.readShorts(s);
if(read < length) {
throw new EOFException();
}
return s;
}
@Override
public int readShorts(short[] s) throws IOException {
return this.readShorts(s, 0, s.length);
}
@Override
public int readShorts(short[] s, int offset, int length) throws IOException {
for(int index = offset; index < offset + length; index++) {
try {
s[index] = this.readShort();
} catch(EOFException e) {
return index - offset;
}
}
return length;
}
@Override
public int[] readInts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
int i[] = new int[length];
int read = this.readInts(i);
if(read < length) {
throw new EOFException();
}
return i;
}
@Override
public int readInts(int[] i) throws IOException {
return this.readInts(i, 0, i.length);
}
@Override
public int readInts(int[] i, int offset, int length) throws IOException {
for(int index = offset; index < offset + length; index++) {
try {
i[index] = this.readInt();
} catch(EOFException e) {
return index - offset;
}
}
return length;
}
@Override
public long[] readLongs(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
long l[] = new long[length];
int read = this.readLongs(l);
if(read < length) {
throw new EOFException();
}
return l;
}
@Override
public int readLongs(long[] l) throws IOException {
return this.readLongs(l, 0, l.length);
}
@Override
public int readLongs(long[] l, int offset, int length) throws IOException {
for(int index = offset; index < offset + length; index++) {
try {
l[index] = this.readLong();
} catch(EOFException e) {
return index - offset;
}
}
return length;
}
@Override
public String readString() throws IOException {
int length = this.readVarInt();

View file

@ -103,6 +103,42 @@ public class StreamNetOutput implements NetOutput {
this.out.write(b, 0, length);
}
@Override
public void writeShorts(short[] s) throws IOException {
this.writeShorts(s, s.length);
}
@Override
public void writeShorts(short[] s, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeShort(s[index]);
}
}
@Override
public void writeInts(int[] i) throws IOException {
this.writeInts(i, i.length);
}
@Override
public void writeInts(int[] i, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeInt(i[index]);
}
}
@Override
public void writeLongs(long[] l) throws IOException {
this.writeLongs(l, l.length);
}
@Override
public void writeLongs(long[] l, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeLong(l[index]);
}
}
@Override
public void writeString(String s) throws IOException {
if(s == null) {

View file

@ -127,6 +127,117 @@ public class ByteBufNetInput implements NetInput {
return length;
}
@Override
public short[] readShorts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
short s[] = new short[length];
for(int index = 0; index < length; index++) {
s[index] = this.readShort();
}
return s;
}
@Override
public int readShorts(short[] s) throws IOException {
return this.readShorts(s, 0, s.length);
}
@Override
public int readShorts(short[] s, int offset, int length) throws IOException {
int readable = this.buf.readableBytes();
if(readable <= 0) {
return -1;
}
if(readable < length * 2) {
length = readable / 2;
}
for(int index = offset; index < offset + length; index++) {
s[index] = this.readShort();
}
return length;
}
@Override
public int[] readInts(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
int i[] = new int[length];
for(int index = 0; index < length; index++) {
i[index] = this.readInt();
}
return i;
}
@Override
public int readInts(int[] i) throws IOException {
return this.readInts(i, 0, i.length);
}
@Override
public int readInts(int[] i, int offset, int length) throws IOException {
int readable = this.buf.readableBytes();
if(readable <= 0) {
return -1;
}
if(readable < length * 4) {
length = readable / 4;
}
for(int index = offset; index < offset + length; index++) {
i[index] = this.readInt();
}
return length;
}
@Override
public long[] readLongs(int length) throws IOException {
if(length < 0) {
throw new IllegalArgumentException("Array cannot have length less than 0.");
}
long l[] = new long[length];
for(int index = 0; index < length; index++) {
l[index] = this.readLong();
}
return l;
}
@Override
public int readLongs(long[] l) throws IOException {
return this.readLongs(l, 0, l.length);
}
@Override
public int readLongs(long[] l, int offset, int length) throws IOException {
int readable = this.buf.readableBytes();
if(readable <= 0) {
return -1;
}
if(readable < length * 2) {
length = readable / 2;
}
for(int index = offset; index < offset + length; index++) {
l[index] = this.readLong();
}
return length;
}
@Override
public String readString() throws IOException {
int length = this.readVarInt();

View file

@ -86,6 +86,42 @@ public class ByteBufNetOutput implements NetOutput {
this.buf.writeBytes(b, 0, length);
}
@Override
public void writeShorts(short[] s) throws IOException {
this.writeShorts(s, s.length);
}
@Override
public void writeShorts(short[] s, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeShort(s[index]);
}
}
@Override
public void writeInts(int[] i) throws IOException {
this.writeInts(i, i.length);
}
@Override
public void writeInts(int[] i, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeInt(i[index]);
}
}
@Override
public void writeLongs(long[] l) throws IOException {
this.writeLongs(l, l.length);
}
@Override
public void writeLongs(long[] l, int length) throws IOException {
for(int index = 0; index < length; index++) {
this.writeLong(l[index]);
}
}
@Override
public void writeString(String s) throws IOException {
if(s == null) {