package org.theonefx.wcframework.utils; import java.nio.charset.Charset; /** * @File : ByteStringBuilder.java * @ClassName : ByteStringBuilder * @Author : 陈曦 * @Date : 2012-6-18 上午11:20:29 * @Version : v1.0 * @Description : 类似StringBuffer的东西,线程安全,不同的就是这个添加的是byte */ public class ByteStringBuilder { private byte[] bytes; private int dataLength = 0; private final Object locker = new Object(); private int offset; public ByteStringBuilder() { this(100); } public ByteStringBuilder(int length) { bytes = new byte[length]; } /** * @Description : 回退一定的长度 * @author : 陈曦 * @date : 2012-6-19 上午09:36:20 * @param i * 回退的长度 */ public void rollback(int i) { synchronized (locker) { if (i > dataLength) { throw new IllegalArgumentException("回退的长度超过原始数据长度"); } dataLength -= i; } } public ByteStringBuilder append(byte[] src) { return append(src, 0, src.length); } public ByteStringBuilder append(byte[] src, int length) { return append(src, 0, length); } public ByteStringBuilder append(byte[] src, int srcOffset, int length) { synchronized (locker) { while (length + offset + dataLength > bytes.length) { byte[] old = bytes; int oldLength = old.length; bytes = new byte[oldLength * 2]; // 扩容的时候,直接抛弃offset的内容 System.arraycopy(old, offset, bytes, 0, oldLength - offset); offset = 0; } System.arraycopy(src, srcOffset, bytes, offset + dataLength, length); dataLength += length; } return this; } @Override public String toString() { return toString(offset, dataLength, Charset.defaultCharset().name()); } public String toString(String charsetName) { return toString(offset, dataLength, charsetName); } public String toString(int length) { return toString(offset, length, Charset.defaultCharset().name()); } public String toString(int length, String charsetName) { return toString(offset, length, charsetName); } public String toString(int start, int length, String charsetName) { synchronized (locker) { return new String(bytes, start, length, Charset.forName(charsetName)); } } public int length() { return dataLength; } public byte[] getBytes() { byte[] result = new byte[dataLength]; System.arraycopy(bytes, offset, result, 0, dataLength); return result; } public void clear() { dataLength = 0; offset = 0; } public boolean isEntWith(byte[] end) { if (end.length == 0) { return true; } if (dataLength < end.length) { return false; } return ArrayUtils.isEndWith(bytes, end, dataLength - end.length); } public boolean isStartWith(byte[] start) { if (start.length == 0) { return true; } if (dataLength < start.length) { return false; } return ArrayUtils.isEndWith(bytes, start, 0); } /** * 从offset开始抛掉length个字符。这是不可恢复的 */ public void jump(int length) { offset += length; dataLength -= length; } public int indexOf(byte[] split) { return indexOf(split, 0); } public int indexOf(byte[] split, int fromIndex) { return indexOf(bytes, offset, dataLength, split, 0, split.length, fromIndex); } private static int indexOf(byte[] source, int sourceOffset, int sourceCount, byte[] target, int targetOffset, int targetCount, int fromIndex) { if (fromIndex >= sourceCount) { return (targetCount == 0 ? sourceCount : -1); } if (fromIndex < 0) { fromIndex = 0; } if (targetCount == 0) { return fromIndex; } byte first = target[targetOffset]; int max = sourceOffset + (sourceCount - targetCount); for (int i = sourceOffset + fromIndex; i <= max; i++) { if (source[i] != first) { while (++i <= max && source[i] != first) ; } if (i <= max) { int j = i + 1; int end = j + targetCount - 1; for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++) ; if (j == end) { return i - sourceOffset; } } } return -1; } public byte getByteAt(int i) { return bytes[offset + i]; } }