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

com.github.xphsc.io.ByteBuffer Maven / Gradle / Ivy

There is a newer version: 1.2.3
Show newest version
package com.github.xphsc.io;

/**
 * Created by ${huipei.x} on 2017-5-25.
 */
public class ByteBuffer {
    private byte[][] buffers = new byte[16][];
    private int buffersCount;
    private int currentBufferIndex = -1;
    private byte[] currentBuffer;
    private int offset;
    private int size;
    private final int minChunkLen;

    public ByteBuffer() {
        this.minChunkLen = 1024;
    }

    public ByteBuffer(int size) {
        this.minChunkLen = Math.abs(size);
    }

    private void needNewBuffer(int newSize) {
        int delta = newSize - this.size;
        int newBufferSize = Math.max(this.minChunkLen, delta);
        ++this.currentBufferIndex;
        this.currentBuffer = new byte[newBufferSize];
        this.offset = 0;
        if(this.currentBufferIndex >= this.buffers.length) {
            int newLen = this.buffers.length << 1;
            byte[][] newBuffers = new byte[newLen][];
            System.arraycopy(this.buffers, 0, newBuffers, 0, this.buffers.length);
            this.buffers = newBuffers;
        }

        this.buffers[this.currentBufferIndex] = this.currentBuffer;
        ++this.buffersCount;
    }

    public ByteBuffer append(byte[] array, int off, int len) {
        int end = off + len;
        if(off >= 0 && len >= 0 && end <= array.length) {
            if(len == 0) {
                return this;
            } else {
                int newSize = this.size + len;
                int remaining = len;
                int part;
                if(this.currentBuffer != null) {
                    part = Math.min(len, this.currentBuffer.length - this.offset);
                    System.arraycopy(array, end - len, this.currentBuffer, this.offset, part);
                    remaining = len - part;
                    this.offset += part;
                    this.size += part;
                }

                if(remaining > 0) {
                    this.needNewBuffer(newSize);
                    part = Math.min(remaining, this.currentBuffer.length - this.offset);
                    System.arraycopy(array, end - remaining, this.currentBuffer, this.offset, part);
                    this.offset += part;
                    this.size += part;
                }

                return this;
            }
        } else {
            throw new IndexOutOfBoundsException();
        }
    }

    public ByteBuffer append(byte[] array) {
        return this.append(array, 0, array.length);
    }

    public ByteBuffer append(byte element) {
        if(this.currentBuffer == null || this.offset == this.currentBuffer.length) {
            this.needNewBuffer(this.size + 1);
        }

        this.currentBuffer[this.offset] = element;
        ++this.offset;
        ++this.size;
        return this;
    }

    public ByteBuffer append(ByteBuffer buff) {
        if(buff.size == 0) {
            return this;
        } else {
            for(int i = 0; i < buff.currentBufferIndex; ++i) {
                this.append(buff.buffers[i]);
            }

            this.append(buff.currentBuffer, 0, buff.offset);
            return this;
        }
    }

    public int size() {
        return this.size;
    }

    public boolean isEmpty() {
        return this.size == 0;
    }

    public int index() {
        return this.currentBufferIndex;
    }

    public int offset() {
        return this.offset;
    }

    public byte[] array(int index) {
        return this.buffers[index];
    }

    public void reset() {
        this.size = 0;
        this.offset = 0;
        this.currentBufferIndex = -1;
        this.currentBuffer = null;
        this.buffersCount = 0;
    }

    public byte[] toArray() {
        int pos = 0;
        byte[] array = new byte[this.size];
        if(this.currentBufferIndex == -1) {
            return array;
        } else {
            for(int i = 0; i < this.currentBufferIndex; ++i) {
                int len = this.buffers[i].length;
                System.arraycopy(this.buffers[i], 0, array, pos, len);
                pos += len;
            }

            System.arraycopy(this.buffers[this.currentBufferIndex], 0, array, pos, this.offset);
            return array;
        }
    }

    public byte[] toArray(int start, int len) {
        int remaining = len;
        int pos = 0;
        byte[] array = new byte[len];
        if(len == 0) {
            return array;
        } else {
            int i;
            for(i = 0; start >= this.buffers[i].length; ++i) {
                start -= this.buffers[i].length;
            }

            while(i < this.buffersCount) {
                byte[] buf = this.buffers[i];
                int c = Math.min(buf.length - start, remaining);
                System.arraycopy(buf, start, array, pos, c);
                pos += c;
                remaining -= c;
                if(remaining == 0) {
                    break;
                }

                start = 0;
                ++i;
            }

            return array;
        }
    }

    public byte get(int index) {
        if(index < this.size && index >= 0) {
            int ndx = 0;

            while(true) {
                byte[] b = this.buffers[ndx];
                if(index < b.length) {
                    return b[index];
                }

                ++ndx;
                index -= b.length;
            }
        } else {
            throw new IndexOutOfBoundsException();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy