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

com.weicoder.common.binary.Buffer Maven / Gradle / Ivy

package com.weicoder.common.binary;

import java.util.Arrays;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import com.weicoder.common.constants.StringConstants;
import com.weicoder.common.lang.Bytes;
import com.weicoder.common.params.CommonParams;
import com.weicoder.common.util.EmptyUtil;
import com.weicoder.common.util.StringUtil;

/**
 * 类说明:数据包类 ,字节缓存类,字节操作高位在前,低位在后
 * @author WD
 * @since JDK7
 * @version 1.0 2014-2-13
 */
public final class Buffer implements ByteArray {
	// 字节数组
	private byte[]	data;
	// 写数据的偏移量,每写一次增加
	private int		top;
	// 读数据的偏移量,每读一次增加
	private int		offset;
	// 是否线程安全
	private boolean	sync;
	// 线程锁
	private Lock	lock;

	/**
	 * 按默认的大小构造一个字节缓存对象
	 */
	public Buffer() {
		this(CommonParams.IO_BUFFERSIZE, false);
	}

	/**
	 * 按默认的大小构造一个字节缓存对象
	 * @param sync 是否线程安全
	 */
	public Buffer(boolean sync) {
		this(CommonParams.IO_BUFFERSIZE, false);
	}

	/**
	 * 按指定的大小构造一个字节缓存对象
	 * @param capacity 初始容量
	 * @param sync 是否线程安全
	 */
	public Buffer(int capacity, boolean sync) {
		this(new byte[capacity], 0, 0, sync);
	}

	/**
	 * 按指定的字节数组构造一个字节缓存对象
	 * @param data 初始化数组
	 * @param sync 是否线程安全
	 */
	public Buffer(byte[] data) {
		this(data, 0, data.length, false);
	}

	/**
	 * 按指定的字节数组构造一个字节缓存对象
	 * @param data 初始化数组
	 * @param sync 是否线程安全
	 */
	public Buffer(byte[] data, boolean sync) {
		this(data, 0, data.length, sync);
	}

	/**
	 * 按指定的字节数组构造一个字节缓存对象
	 * @param data 初始化数组
	 * @param index 读索引
	 * @param length 写索引
	 * @param sync 是否线程安全
	 */
	public Buffer(byte[] data, int index, int length, boolean sync) {
		this.data = data;
		top = index + length;
		offset = index;
		this.sync = sync;
		// 线程安全 初始化锁
		if (sync) {
			lock = new ReentrantLock(true);
		}
	}

	/**
	 * 设置字节缓存的容积,只能扩大容积
	 */
	public void capacity(int len) {
		// 要扩展的容量小于原长度 放弃修改
		if (len <= data.length) {
			return;
		}
		// 如果同步 加锁
		if (sync) {
			lock.lock();
		}
		// 声明个新长度临时数组
		byte[] temp = new byte[len < CommonParams.IO_BUFFERSIZE ? CommonParams.IO_BUFFERSIZE : len];
		// 读取原有数据
		System.arraycopy(data, 0, temp, 0, top);
		// 复制到新数组
		data = temp;
		// 如果同步 解锁
		if (sync) {
			lock.unlock();
		}
	}

	/**
	 * 得到写字节的偏移量
	 */
	public int top() {
		return top;
	}

	/**
	 * 设置写字节的偏移量
	 */
	public void top(int top) {
		if (top < offset)
			return;
		if (top > length())
			capacity(top);
		this.top = top;
	}

	/**
	 * 得到读数据的偏移量
	 */
	public int offset() {
		return offset;
	}

	/**
	 * 设置读数据的偏移量
	 */
	public void offset(int offset) {
		if (offset < 0 || offset > top)
			return;
		this.offset = offset;
	}

	/**
	 * 剩余多少可读字节==写偏移量-读偏移量得差值
	 */
	public int remaining() {
		return top - offset;
	}

	/**
	 * 是否还有任何一个可读字节
	 */
	public boolean hasRemaining() {
		return remaining() > 0;
	}

	/**
	 * 得到字节数组的长度
	 */
	public int length() {
		return data.length;
	}

	/**
	 * 按当前偏移位置读入指定的长度的字节数组
	 * @param len
	 */
	public byte[] read(int len) {
		return read(new byte[len]);
	}

	/**
	 * 按当前偏移位置读入指定的字节数组
	 * @param data 指定的字节数组
	 * @param pos 指定的字节数组的起始位置
	 * @param len 读入的长度
	 */
	public byte[] read(byte[] data) {
		return read(data, 0, data.length);
	}

	/**
	 * 按当前偏移位置读入指定的字节数组
	 * @param data 指定的字节数组
	 * @param pos 指定的字节数组的起始位置
	 * @param len 读入的长度
	 */
	public byte[] read(byte[] data, int pos, int len) {
		// // 如果数组长度小于读取长度
		// if (data.length < pos + len) {
		// // 返回空数组
		// return ArrayConstants.BYTES_EMPTY;
		// }
		// 如果同步 加锁
		if (sync) {
			lock.lock();
		}
		// 复制原数组
		System.arraycopy(this.data, offset, data, pos, len);
		offset += len;
		// 如果同步 解锁
		if (sync) {
			lock.unlock();
		}
		// 返回数据
		return data;
	}

	/**
	 * 读出一个布尔值
	 */
	public boolean readBoolean() {
		return readByte() != 0;
	}

	/**
	 * 读出一个字节
	 */
	public byte readByte() {
		return read(1)[0];
	}

	/**
	 * 读出一个字符
	 */
	public char readChar() {
		return (char) readShort();
	}

	/**
	 * 读出一个短整型数值
	 */
	public short readShort() {
		return Bytes.toShort(read(2));
	}

	/**
	 * 读出一个整型数值
	 */
	public int readInt() {
		return Bytes.toInt(read(4));
	}

	/**
	 * 读出一个浮点数值
	 */
	public float readFloat() {
		return Bytes.toFloat(read(4));
	}

	/**
	 * 读出一个长整型数值
	 */
	public long readLong() {
		return Bytes.toLong(read(8));
	}

	/**
	 * 读出一个双浮点数值
	 */
	public double readDouble() {
		return Bytes.toDouble(read(8));
	}

	/**
	 * 读出一个指定长度的字符串
	 */
	public String readString(int len) {
		if (len == 0)
			return StringConstants.EMPTY;
		return new String(read(new byte[len], 0, len));
	}

	/**
	 * 读出一个字符串,长度不超过65534
	 */
	public String readString() {
		return readString(readShort());
	}

	/**
	 * 写入指定字节数组
	 * @param data 指定的字节数组
	 * @param pos 指定的字节数组的起始位置
	 * @param len 写入的长度
	 */
	public byte[] write(byte[] data) {
		return write(data, 0, data.length);
	}

	/**
	 * 写入指定字节数组
	 * @param data 指定的字节数组
	 * @param pos 指定的字节数组的起始位置
	 * @param len 写入的长度
	 */
	public byte[] write(byte[] data, int pos, int len) {
		// 容量不足扩容
		if (data.length < top + len) {
			capacity(top + len);
		}
		// 如果同步 加锁
		if (sync) {
			lock.lock();
		}
		// 复制原数组
		System.arraycopy(data, pos, this.data, top, len);
		top += len;
		// 如果同步 解锁
		if (sync) {
			lock.unlock();
		}
		// 返回数组
		return data;
	}

	/**
	 * 写入一个布尔值
	 */
	public void writeBoolean(boolean b) {
		writeByte((byte) (b ? 1 : 0));
	}

	/**
	 * 写入一个字节
	 */
	public void writeByte(byte b) {
		write(new byte[] { b });
	}

	/**
	 * 写入一个字符
	 */
	public void writeChar(char c) {
		write(Bytes.toBytes(c), 0, 2);
	}

	/**
	 * 写入一个短整型数值
	 */
	public void writeShort(int i) {
		writeShort((short) i);
	}

	/**
	 * 写入一个短整型数值
	 */
	public void writeShort(short s) {
		writeShort(s, 0);
	}

	/**
	 * 在指定位置写入一个短整型数值,length不变
	 */
	public void writeShort(short s, int pos) {
		write(Bytes.toBytes(s), pos, pos + 2);
	}

	/**
	 * 写入一个整型数值
	 */
	public void writeInt(int i) {
		writeInt(i, 0);
	}

	/**
	 * 在指定位置写入一个整型数值,length不变
	 */
	public void writeInt(int i, int pos) {
		write(Bytes.toBytes(i), pos, pos + 4);
	}

	/**
	 * 写入一个浮点数值
	 */
	public void writeFloat(float f) {
		writeInt(Float.floatToIntBits(f));
	}

	/**
	 * 写入一个长整型数值
	 */
	public void writeLong(long l) {
		writeLong(l, 0);
	}

	/**
	 * 写入一个长整型数值
	 */
	public void writeLong(long l, int pos) {
		write(Bytes.toBytes(l), pos, pos + 8);
	}

	/**
	 * 写入一个双浮点数值
	 */
	public void writeDouble(double d) {
		writeLong(Double.doubleToLongBits(d));
	}

	/**
	 * 写入一个字符串,可以为null
	 */
	public void writeString(String s) {
		if (EmptyUtil.isEmpty(s)) {
			writeShort(0);
		} else {
			byte[] temp = StringUtil.toBytes(s);
			writeShort(temp.length);
			write(temp, 0, temp.length);
		}
	}

	/**
	 * 压缩缓冲区 抛弃以读数据 并把容量截取到写坐标
	 */
	public void compact() {
		// 读位置不为0时才需要压缩
		if (offset > 0) {
			// 如果同步 加锁
			if (sync) {
				lock.lock();
			}
			// 移动数据
			System.arraycopy(data, offset, data, 0, remaining());
			// 重置下标
			top -= offset;
			offset = 0;
			// 如果同步 解锁
			if (sync) {
				lock.unlock();
			}
		}
	}

	// /**
	// * 重置读坐标为0
	// */
	// public void rewind() {
	// this.offset = 0;
	// }

	/**
	 * 获得有效数据
	 */
	public byte[] array() {
		return Bytes.copy(data, 0, top);
	}

	/**
	 * 清除字节缓存对象
	 */
	public void clear() {
		// 如果数组长度小于默认缓存长度 重新生成数组
		if (length() < CommonParams.IO_BUFFERSIZE) {
			data = new byte[CommonParams.IO_BUFFERSIZE];
		}
		top = 0;
		offset = 0;
	}

	@Override
	public ByteArray array(byte[] b) {
		clear();
		write(b);
		return this;
	}

	@Override
	public String toString() {
		return "(top=" + top + ",offset=" + offset + ")=" + Arrays.toString(array());
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy