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];
}
}