cn.tom.kit.IoBuffer Maven / Gradle / Ivy
The newest version!
package cn.tom.kit;
import java.nio.ByteBuffer;
import sun.misc.Cleaner;
import sun.nio.ch.DirectBuffer;
/**
* @author rushmore edit by panmg
* edit by panmg
*/
public final class IoBuffer {
private int limit = -1;
private int writeIndex = -1;
public ByteBuffer buf = null;
private IoBuffer(ByteBuffer buf) {
this.buf = buf;
}
public static IoBuffer wrap(ByteBuffer buf) {
return new IoBuffer(buf);
}
public static IoBuffer wrap(byte[] buf) {
return new IoBuffer(ByteBuffer.wrap(buf));
}
public static IoBuffer wrap(String str){
return wrap(str.getBytes());
}
public static IoBuffer allocate(int capacity) {
return new IoBuffer(ByteBuffer.allocate(capacity));
}
public static IoBuffer allocateDirect(int capacity) {
return new IoBuffer(ByteBuffer.allocateDirect(capacity));
}
/**
* DirectBuffer 没有 byte[] 抛出异常
* @return
*/
public byte[] array(){
return this.buf.array();
}
public byte readByte() {
return this.buf.get();
}
public IoBuffer readBytes(byte[] dst) {
this.buf.get(dst);
return this;
}
/**
* 向后读取 length长度的 bytes[]
* @param length
* @return
*/
public byte[] readBytes(int index, int length){
byte [] bb = new byte[length];
if(index != position()){
throw new RuntimeException("index != position");
}
System.arraycopy(this.array(), index, bb, 0 , length);
position(index + length);
return bb;
}
/**
* 向后读取 length长度的 bytes[]
* 同上, 默认 index = position
* @param length
* @return
*/
public byte[] readBytes(int length){
byte [] bb = new byte[length];
int index = position();
System.arraycopy(this.array(), index, bb, 0 , length);
position(index + length);
return bb;
}
/**
* 不产生 position 移动
* @param index
* @param length
* @return
*/
public byte[] getBytes(int index, int length){
byte [] bb = new byte[length];
System.arraycopy(this.array(), index , bb, 0, length);
return bb;
}
public short readShort() {
return this.buf.getShort();
}
public int readInt() {
return this.buf.getInt();
}
public long readLong() {
return this.buf.getLong();
}
public IoBuffer writeByte(byte value) {
return writeBytes(new byte[] { value });
}
public IoBuffer writeBytes(byte[] src) {
return writeBytes(src, 0, src.length);
}
public IoBuffer writeByte(int value) {
return writeBytes(new byte[] { (byte) value });
}
public IoBuffer writeBytes(byte[] src, int offset, int length) {
autoExpand(length);
int index = position();
System.arraycopy(src, offset, array(), index , length);
position(index + length);
return this;
}
public IoBuffer writeChar(char c) {
autoExpand(2);
this.buf.putChar(c);
return this;
}
public IoBuffer writeShort(short value) {
autoExpand(2);
this.buf.putShort(value);
return this;
}
public IoBuffer writeLong(long value) {
autoExpand(8);
this.buf.putLong(value);
return this;
}
public IoBuffer writeInt(int value) {
autoExpand(4);
this.buf.putInt(value);
return this;
}
public IoBuffer writeString(String value) {
this.writeBytes(value.getBytes());
return this;
}
public IoBuffer write(ByteBuffer value) {
autoExpand(value.limit());
this.buf.put(value);
return this;
}
public final IoBuffer flip() {
this.buf.flip();
return this;
}
public final byte get(int index) {
return this.buf.get(index);
}
public final IoBuffer unflip() {
buf.position(buf.limit());
if (buf.limit() != buf.capacity())
buf.limit(buf.capacity());
return this;
}
public final IoBuffer rewind() {
this.buf.rewind();
return this;
}
public final int remaining() {
return this.buf.remaining();
}
public final IoBuffer markReadIndex() {
this.buf.mark();
return this;
}
public final IoBuffer resetReadIndex() {
this.buf.reset();
return this;
}
public final IoBuffer markWriteIndex() {
this.limit = limit();
this.writeIndex = position();
return this;
}
public final IoBuffer resetWriteIndex() {
limit(this.limit);
position(this.writeIndex);
return this;
}
public final int position() {
return this.buf.position();
}
/**
* 如果position的索引到了mark前面就失效
* @param newPosition
* @return
*/
public final IoBuffer position(int newPosition) {
this.buf.position(newPosition);
return this;
}
public final int limit(){
return this.buf.limit();
}
/**
* 修改limit 可能导致mark失效
* 如果limit的索引到了mark前面就失效
* @param newLimit
* @return
*/
public final IoBuffer limit(int newLimit){
this.buf.limit(newLimit);
return this;
}
public final IoBuffer duplicate() {
return IoBuffer.wrap(this.buf.duplicate());
}
public final IoBuffer compact() {
this.buf.compact();
return this;
}
public final ByteBuffer buf() {
return this.buf;
}
/**
* DirectByteBuffer extends MappedByteBuffer implements DirectBuffer
* MappedByteBuffer extends ByteBuffer
* 堆外内存释放
* @param bb
*/
public void release() {
if (buf instanceof DirectBuffer) {
Cleaner cl = ((DirectBuffer) buf).cleaner();
if (cl != null) {
cl.clean();
}
}
}
private void autoExpand(int length) {
int newCapacity = buf.capacity();
int newSize = buf.position() + length;
ByteBuffer newBuffer = null;
while (newSize > newCapacity) {
newCapacity = newCapacity * 2;
}
// Auto expand capacity
if (newCapacity != buf.capacity()) {
if (buf.isDirect()) {
newBuffer = ByteBuffer.allocateDirect(newCapacity);
} else {
newBuffer = ByteBuffer.allocate(newCapacity);
}
System.arraycopy(array(), 0, newBuffer.array(), 0, buf.capacity());
// newBuffer.put(buf.array());
newBuffer.position(position());
this.buf = newBuffer;
}
}
@Override
public String toString() {
byte [] bytes = getBytes(position(), limit());
return bytes2HexString(bytes);
}
public static String bytes2HexString0(byte[] b) {
StringBuilder r = new StringBuilder(b.length);
for (int i = 0; i < b.length; i++) {
String hex = Integer.toHexString(b[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
r.append(hex.toUpperCase()) ;
}
return r.toString();
}
public static String bytes2HexString(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E','F' };
}