All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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