org.appconn.channel.ReadHeapByteBuffer Maven / Gradle / Ivy
package org.appconn.channel;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* appconn ReadBuffer Heap implementation.
*/
final class ReadHeapByteBuffer implements ReadBuffer {
private final ReadableByteChannel channel;
private final byte[] buffer;
private final ByteBuffer byteBuffer;
ReadHeapByteBuffer(ReadableByteChannel channel, int length) {
this.channel = channel;
buffer = new byte[length];
byteBuffer = ByteBuffer.wrap(buffer);
byteBuffer.flip();
}
@Override
public byte get() throws IOException {
while (true) {
if (byteBuffer.hasRemaining()) {
byteBuffer.position(byteBuffer.position() + 1);
return buffer[byteBuffer.position() - 1];
}
read();
}
}
private byte[] getBytes(int length) throws IOException {
byte[] bytes = new byte[length];
int index = 0;
for (int remaining = byteBuffer.remaining(); index < length; remaining = byteBuffer.remaining()) {
if (remaining > 0) {
if (remaining >= (length - index)) {
System.arraycopy(buffer, byteBuffer.position(), bytes, index, length - index);
byteBuffer.position(byteBuffer.position() + length - index);
break;
}
System.arraycopy(buffer, byteBuffer.position(), bytes, index, remaining);
byteBuffer.position(byteBuffer.limit());
index += remaining;
}
read();
}
return bytes;
}
@Override
public byte[] getBytes() throws IOException {
return getBytes(getInt());
}
@Override
public char getChar() throws IOException {
while (true) {
if (byteBuffer.remaining() >= 2) {
byteBuffer.position(byteBuffer.position() + 2);
return (char) ((buffer[byteBuffer.position() - 2] & 0xff) | (buffer[byteBuffer.position() - 1] << 8));
}
read();
}
}
@Override
public double getDouble() throws IOException {
while (true) {
if (byteBuffer.remaining() >= 8) {
byteBuffer.position(byteBuffer.position() + 8);
return Double.longBitsToDouble((buffer[byteBuffer.position() - 8] & 0xff) |
((buffer[byteBuffer.position() - 7] & 0xff) << 8) |
((buffer[byteBuffer.position() - 6] & 0xff) << 16) |
((buffer[byteBuffer.position() - 5] & 0xff) << 24) |
(((long) buffer[byteBuffer.position() - 4] & 0xff) << 32) |
(((long) buffer[byteBuffer.position() - 3] & 0xff) << 40) |
(((long) buffer[byteBuffer.position() - 2] & 0xff) << 48) |
((long) buffer[byteBuffer.position() - 1] << 56));
}
read();
}
}
@Override
public float getFloat() throws IOException {
while (true) {
if (byteBuffer.remaining() >= 4) {
byteBuffer.position(byteBuffer.position() + 4);
return Float.intBitsToFloat((buffer[byteBuffer.position() - 4] & 0xff) |
((buffer[byteBuffer.position() - 3] & 0xff) << 8) |
((buffer[byteBuffer.position() - 2] & 0xff) << 16) |
(buffer[byteBuffer.position() - 1] << 24));
}
read();
}
}
@Override
public int getInt() throws IOException {
while (true) {
if (byteBuffer.hasRemaining()) {
if ((buffer[byteBuffer.position()] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 1);
return buffer[byteBuffer.position() - 1];
} else if (byteBuffer.position() + 1 < byteBuffer.limit() && (buffer[byteBuffer.position() + 1] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 2);
return (buffer[byteBuffer.position() - 2] & 0x7f) |
(buffer[byteBuffer.position() - 1] << 7);
} else if (byteBuffer.position() + 2 < byteBuffer.limit() && (buffer[byteBuffer.position() + 2] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 3);
return (buffer[byteBuffer.position() - 3] & 0x7f) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 7) |
(buffer[byteBuffer.position() - 1] << 14);
} else if (byteBuffer.position() + 3 < byteBuffer.limit() && (buffer[byteBuffer.position() + 3] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 4);
return (buffer[byteBuffer.position() - 4] & 0x7f) |
((buffer[byteBuffer.position() - 3] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 14) |
(buffer[byteBuffer.position() - 1] << 21);
} else if (byteBuffer.position() + 4 < byteBuffer.limit() && (buffer[byteBuffer.position() + 4] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 5);
return (buffer[byteBuffer.position() - 5] & 0x7f) |
((buffer[byteBuffer.position() - 4] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 3] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 21) |
(buffer[byteBuffer.position() - 1] << 28);
} else throw new RuntimeException(new ChannelException("malformed int"));
}
read();
}
}
@Override
public long getLong() throws IOException {
while (true) {
if (byteBuffer.hasRemaining()) {
if ((buffer[byteBuffer.position()] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 1);
return buffer[byteBuffer.position() - 1];
} else if (byteBuffer.position() + 1 < byteBuffer.limit() && (buffer[byteBuffer.position() + 1] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 2);
return (buffer[byteBuffer.position() - 2] & 0x7f) |
(buffer[byteBuffer.position() - 1] << 7);
} else if (byteBuffer.position() + 2 < byteBuffer.limit() && (buffer[byteBuffer.position() + 2] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 3);
return (buffer[byteBuffer.position() - 3] & 0x7f) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 7) |
(buffer[byteBuffer.position() - 1] << 14);
} else if (byteBuffer.position() + 3 < byteBuffer.limit() && (buffer[byteBuffer.position() + 3] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 4);
return (buffer[byteBuffer.position() - 4] & 0x7f) |
((buffer[byteBuffer.position() - 3] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 14) |
(buffer[byteBuffer.position() - 1] << 21);
} else if (byteBuffer.position() + 4 < byteBuffer.limit() && (buffer[byteBuffer.position() + 4] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 5);
return (buffer[byteBuffer.position() - 5] & 0x7f) |
((buffer[byteBuffer.position() - 4] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 3] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 2] & 0x7f) << 21) |
((long) buffer[byteBuffer.position() - 1] << 28);
} else if (byteBuffer.position() + 5 < byteBuffer.limit() && (buffer[byteBuffer.position() + 5] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 6);
return (buffer[byteBuffer.position() - 6] & 0x7f) |
((buffer[byteBuffer.position() - 5] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 4] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 3] & 0x7f) << 21) |
(((long) buffer[byteBuffer.position() - 2] & 0x7f) << 28) |
((long) buffer[byteBuffer.position() - 1] << 35);
} else if (byteBuffer.position() + 6 < byteBuffer.limit() && (buffer[byteBuffer.position() + 6] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 7);
return (buffer[byteBuffer.position() - 7] & 0x7f) |
((buffer[byteBuffer.position() - 6] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 5] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 4] & 0x7f) << 21) |
(((long) buffer[byteBuffer.position() - 3] & 0x7f) << 28) |
(((long) buffer[byteBuffer.position() - 2] & 0x7f) << 35) |
((long) buffer[byteBuffer.position() - 1] << 42);
} else if (byteBuffer.position() + 7 < byteBuffer.limit() && (buffer[byteBuffer.position() + 7] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 8);
return (buffer[byteBuffer.position() - 8] & 0x7f) |
((buffer[byteBuffer.position() - 7] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 6] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 5] & 0x7f) << 21) |
(((long) buffer[byteBuffer.position() - 4] & 0x7f) << 28) |
(((long) buffer[byteBuffer.position() - 3] & 0x7f) << 35) |
(((long) buffer[byteBuffer.position() - 2] & 0x7f) << 42) |
((long) buffer[byteBuffer.position() - 1] << 49);
} else if (byteBuffer.position() + 8 < byteBuffer.limit() && (buffer[byteBuffer.position() + 8] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 9);
return (buffer[byteBuffer.position() - 9] & 0x7f) |
((buffer[byteBuffer.position() - 8] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 7] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 6] & 0x7f) << 21) |
(((long) buffer[byteBuffer.position() - 5] & 0x7f) << 28) |
(((long) buffer[byteBuffer.position() - 4] & 0x7f) << 35) |
(((long) buffer[byteBuffer.position() - 3] & 0x7f) << 42) |
(((long) buffer[byteBuffer.position() - 2] & 0x7f) << 49) |
((long) buffer[byteBuffer.position() - 1] << 56);
} else if (byteBuffer.position() + 9 < byteBuffer.limit() && (buffer[byteBuffer.position() + 9] & 0x80) == 0) {
byteBuffer.position(byteBuffer.position() + 10);
return (buffer[byteBuffer.position() - 10] & 0x7f) |
((buffer[byteBuffer.position() - 9] & 0x7f) << 7) |
((buffer[byteBuffer.position() - 8] & 0x7f) << 14) |
((buffer[byteBuffer.position() - 7] & 0x7f) << 21) |
(((long) buffer[byteBuffer.position() - 6] & 0x7f) << 28) |
(((long) buffer[byteBuffer.position() - 5] & 0x7f) << 35) |
(((long) buffer[byteBuffer.position() - 4] & 0x7f) << 42) |
(((long) buffer[byteBuffer.position() - 3] & 0x7f) << 49) |
(((long) buffer[byteBuffer.position() - 2] & 0x7f) << 56) |
((long) buffer[byteBuffer.position() - 1] << 63);
} else throw new RuntimeException(new ChannelException("malformed long"));
}
read();
}
}
@Override
public short getShort() throws IOException {
while (true) {
if (byteBuffer.remaining() >= 2) {
byteBuffer.position(byteBuffer.position() + 2);
return (short) ((buffer[byteBuffer.position() - 2] & 0xff) | (buffer[byteBuffer.position() - 1] << 8));
}
read();
}
}
@Override
public String getString() throws IOException {
int length = getInt();
try {
if (byteBuffer.remaining() >= length) {
byteBuffer.position(byteBuffer.position() + length);
return new String(buffer, byteBuffer.position() - length, length, "UTF-8");
} else {
byte[] bytes = getBytes(length);
return new String(bytes, "UTF-8");
}
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(new ChannelException(e.getMessage(), e));
}
}
@Override
public boolean hasRemaining() {
return byteBuffer.hasRemaining();
}
@Override
public int read() throws IOException {
byteBuffer.compact();
int bytesRead = channel.read(byteBuffer);
byteBuffer.flip();
if (bytesRead < 0) {
Logger.getLogger("org.appconn").log(Level.FINE, "channel has reached end-of-stream");
channel.close();
}
return bytesRead;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy