ByteHolder.java 3.15 KB
package com.genersoft.iot.vmp.jtt1078.util;

import java.util.Arrays;

/**
 * 字节缓冲区工具类
 * Created by matrixy on 2018-06-15.
 */
public class ByteHolder {
    int offset = 0;
    int size = 0;
    byte[] buffer = null;

    public ByteHolder(int bufferSize) {
        this.buffer = new byte[bufferSize];
    }

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

    public void write(byte[] data) {
        write(data, 0, data.length);
    }

    public void write(byte[] data, int offset, int length) {
        // 防止溢出,简单的扩容策略或抛异常
        if (this.offset + length > buffer.length) {
            // 简单扩容策略:如果空间不够,扩大两倍 (可选)
            // byte[] newBuffer = new byte[Math.max(buffer.length * 2, this.offset + length)];
            // System.arraycopy(buffer, 0, newBuffer, 0, this.offset);
            // this.buffer = newBuffer;

            // 原有逻辑:直接抛异常
            throw new RuntimeException(String.format("exceed the max buffer size, max length: %d, data length: %d", buffer.length, length));
        }

        System.arraycopy(data, offset, buffer, this.offset, length);
        this.offset += length;
        this.size += length;
    }

    public byte[] array() {
        return array(this.size);
    }

    public byte[] array(int length) {
        return Arrays.copyOf(this.buffer, length);
    }

    public void write(byte b) {
        if (this.offset >= buffer.length) {
            throw new RuntimeException("Buffer overflow");
        }
        this.buffer[offset++] = b;
        this.size += 1;
    }

    /**
     * 将数据读入 dest 数组,并从缓冲区移除这些数据
     */
    public void sliceInto(byte[] dest, int length) {
        if (length > this.size) {
            throw new RuntimeException("Buffer underflow: not enough bytes to read");
        }
        System.arraycopy(this.buffer, 0, dest, 0, length);
        // 往前挪 length 个位 (移除已读数据)
        System.arraycopy(this.buffer, length, this.buffer, 0, this.size - length);
        this.offset -= length;
        this.size -= length;
    }

    /**
     * 【新增】读取字节到数组中,并从缓冲区移除
     * 配合 Decoder 的搜寻包头逻辑使用
     */
    public void read(byte[] dest) {
        sliceInto(dest, dest.length);
    }

    /**
     * 丢弃前 length 个字节
     */
    public void slice(int length) {
        if (length > this.size) {
            length = this.size; // 容错处理,最多丢弃所有
        }
        System.arraycopy(this.buffer, length, this.buffer, 0, this.size - length);
        this.offset -= length;
        this.size -= length;
    }

    public byte get(int position) {
        return this.buffer[position];
    }

    public void clear() {
        this.offset = 0;
        this.size = 0;
    }

    public int getInt(int offset) {
        // 需保证 ByteUtils 存在且逻辑正确
        return ByteUtils.getInt(this.buffer, offset, 4);
    }

    public int getShort(int position) {
        int h = this.buffer[position] & 0xff;
        int l = this.buffer[position + 1] & 0xff;
        return ((h << 8) | l) & 0xffff;
    }
}