From f67447a73ab0f8449ad63a76e679cd5cd0c198c8 Mon Sep 17 00:00:00 2001 From: Maciej Lach Date: Mon, 16 Nov 2015 09:05:21 +0100 Subject: [PATCH] Refactoring: ByteInputStream little/big endian reading --- .../com/exxeleron/qjava/ByteInputStream.java | 95 ++++++++++++++++--- .../com/exxeleron/qjava/DefaultQReader.java | 8 +- .../java/com/exxeleron/qjava/QReader.java | 1 - 3 files changed, 85 insertions(+), 19 deletions(-) diff --git a/src/main/java/com/exxeleron/qjava/ByteInputStream.java b/src/main/java/com/exxeleron/qjava/ByteInputStream.java index c2006bc..53c56a5 100644 --- a/src/main/java/com/exxeleron/qjava/ByteInputStream.java +++ b/src/main/java/com/exxeleron/qjava/ByteInputStream.java @@ -2,6 +2,7 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteOrder; +import java.util.UUID; /** * Convenience class for converting wrapped byte buffer to primitive types. @@ -9,21 +10,27 @@ public final class ByteInputStream { private byte[] buffer; - private ByteOrder endianess; private int position; private String encoding; + private ByteInputStreamReader reader; + private ByteInputStreamReader readerLittleEndian; + private ByteInputStreamReader readerBigEndian; + /** * Creates new {@link ByteInputStream}. * * @param encoding - * encoding for symbols convertion + * encoding for symbols conversion * @param endianess * byte order of the input stream */ public ByteInputStream(final String encoding, final ByteOrder endianess) { this.encoding = encoding; - this.endianess = endianess; + this.readerLittleEndian = new ByteLittleEndianInputStream(); + this.readerBigEndian = new ByteBigEndianInputStream(); + + setOrder(endianess); } /** @@ -67,8 +74,7 @@ public byte get() { * @return the short */ public short getShort() { - final int x = buffer[position++], y = buffer[position++]; - return (short) (endianess == ByteOrder.LITTLE_ENDIAN ? x & 0xff | y << 8 : x << 8 | y & 0xff); + return reader.getShort(); } /** @@ -77,8 +83,7 @@ public short getShort() { * @return the int */ public int getInt() { - final int x = getShort(), y = getShort(); - return endianess == ByteOrder.LITTLE_ENDIAN ? x & 0xffff | y << 16 : x << 16 | y & 0xffff; + return reader.getInt(); } /** @@ -87,8 +92,7 @@ public int getInt() { * @return the long */ public long getLong() { - final int x = getInt(), y = getInt(); - return endianess == ByteOrder.LITTLE_ENDIAN ? x & 0xffffffffL | (long) y << 32 : (long) x << 32 | y & 0xffffffffL; + return reader.getLong(); } /** @@ -125,13 +129,24 @@ public String getSymbol() throws UnsupportedEncodingException { return (p == position - 1) ? "" : new String(buffer, p, position - 1 - p, encoding); } + /** + * Retrieves single {@link UUID} from the byte buffer. + * + * @return {@link UUID} + */ + public UUID getUUID() { + final long l1 = readerBigEndian.getLong(); + final long l2 = readerBigEndian.getLong(); + return new UUID(l1, l2); + } + /** * Retrieves byte order for the wrapped buffer. * * @return {@link ByteOrder} */ public ByteOrder getOrder() { - return endianess; + return reader.getOrder(); } /** @@ -141,7 +156,65 @@ public ByteOrder getOrder() { * byte order */ public void setOrder( final ByteOrder endianess ) { - this.endianess = endianess; + this.reader = endianess.equals(ByteOrder.LITTLE_ENDIAN) ? readerLittleEndian : readerBigEndian; + } + + private interface ByteInputStreamReader { + + public abstract short getShort(); + + public abstract int getInt(); + + public abstract long getLong(); + + public abstract ByteOrder getOrder(); + + } + + private class ByteBigEndianInputStream implements ByteInputStreamReader { + + public short getShort() { + final int x = buffer[position++], y = buffer[position++]; + return (short) (x << 8 | y & 0xff); + } + + public int getInt() { + final int x = getShort(), y = getShort(); + return x << 16 | y & 0xffff; + } + + public long getLong() { + final int x = getInt(), y = getInt(); + return (long) x << 32 | y & 0xffffffffL; + } + + public ByteOrder getOrder() { + return ByteOrder.BIG_ENDIAN; + } + + } + + private class ByteLittleEndianInputStream implements ByteInputStreamReader { + + public short getShort() { + final int x = buffer[position++], y = buffer[position++]; + return (short) (x & 0xff | y << 8); + } + + public int getInt() { + final int x = getShort(), y = getShort(); + return (x & 0xffff | y << 16); + } + + public long getLong() { + final int x = getInt(), y = getInt(); + return (x & 0xffffffffL | (long) y << 32); + } + + public ByteOrder getOrder() { + return ByteOrder.BIG_ENDIAN; + } + } } \ No newline at end of file diff --git a/src/main/java/com/exxeleron/qjava/DefaultQReader.java b/src/main/java/com/exxeleron/qjava/DefaultQReader.java index 64f3009..162370c 100644 --- a/src/main/java/com/exxeleron/qjava/DefaultQReader.java +++ b/src/main/java/com/exxeleron/qjava/DefaultQReader.java @@ -17,7 +17,6 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; -import java.nio.ByteOrder; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -235,12 +234,7 @@ protected Object readList( final QType qtype ) throws QException, UnsupportedEnc } protected UUID readGuid() { - final ByteOrder currentOrder = reader.getOrder(); - reader.setOrder(ByteOrder.BIG_ENDIAN); - final long l1 = reader.getLong(); - final long l2 = reader.getLong(); - reader.setOrder(currentOrder); - return new UUID(l1, l2); + return reader.getUUID(); } protected Object[] readGeneralList() throws QException, IOException { diff --git a/src/main/java/com/exxeleron/qjava/QReader.java b/src/main/java/com/exxeleron/qjava/QReader.java index 3c39830..1db65be 100644 --- a/src/main/java/com/exxeleron/qjava/QReader.java +++ b/src/main/java/com/exxeleron/qjava/QReader.java @@ -84,7 +84,6 @@ public QMessage read( final boolean raw ) throws IOException, QException { stream.readFully(header, 0, 8); reader.wrap(header); - // TODO: create 2 instances per each endian and select one based on a flag final ByteOrder endianess = reader.get() == 0 ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; final QConnection.MessageType messageType = QConnection.MessageType.getMessageType(reader.get()); final boolean compressed = reader.get() == 1;