Skip to content

Commit

Permalink
Refactoring: ByteInputStream little/big endian reading
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejlach committed Nov 16, 2015
1 parent 8997c3b commit f67447a
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 19 deletions.
95 changes: 84 additions & 11 deletions src/main/java/com/exxeleron/qjava/ByteInputStream.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,35 @@

import java.io.UnsupportedEncodingException;
import java.nio.ByteOrder;
import java.util.UUID;

/**
* Convenience class for converting wrapped byte buffer to primitive types.
*/
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);
}

/**
Expand Down Expand Up @@ -67,8 +74,7 @@ public byte get() {
* @return the <code>short</code>
*/
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();
}

/**
Expand All @@ -77,8 +83,7 @@ public short getShort() {
* @return the <code>int</code>
*/
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();
}

/**
Expand All @@ -87,8 +92,7 @@ public int getInt() {
* @return the <code>long</code>
*/
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();
}

/**
Expand Down Expand Up @@ -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();
}

/**
Expand All @@ -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;
}

}

}
8 changes: 1 addition & 7 deletions src/main/java/com/exxeleron/qjava/DefaultQReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/exxeleron/qjava/QReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit f67447a

Please sign in to comment.