一、处理器接口
public interface IFrameDecoder {
void decode(byte[] srcBytes, int size, IFrameReadyListener listener);
}
二、数据回调接口
public interface IFrameReadyListener {
void onFrameReady(byte[] frame);
}
三、处理器类
public class DelimiterBasedFrameDecoder implements IFrameDecoder {
private final byte[] delimiterBytes;
private final byte[] destBytes;
private int writeIndex;
public DelimiterBasedFrameDecoder(int maxFrameLength, String delimiter) {
delimiterBytes = delimiter.getBytes();
destBytes = new byte[maxFrameLength];
}
@Override
public void decode(byte[] srcBytes, int size, IFrameReadyListener listener) {
if (srcBytes == null) return;
int maxFrameLength = destBytes.length;
int count = (int) Math.ceil((size + writeIndex) * 1.0 / maxFrameLength);
int srcPos = 0;
for (int i = 0; i < count; ++i) {
int maxWriteLen = maxFrameLength - writeIndex;
int writeLen = Math.min(maxWriteLen, size);
System.arraycopy(srcBytes, srcPos, destBytes, writeIndex, writeLen);
srcPos += writeLen;
size -= writeLen;
writeIndex += writeLen;
checkFrame(listener);
}
}
private void checkFrame(IFrameReadyListener listener) {
int delimiterLen = delimiterBytes.length;
if (writeIndex < delimiterLen) return;
for (int i = 0; i <= writeIndex - delimiterLen; ++i) {
int tempI = i;
int j = 0;
for (; j < delimiterLen; ++j, ++tempI) {
if (destBytes[tempI] != delimiterBytes[j]) {
break;
}
}
if (j == delimiterLen) {
backFrame(i, listener);
}
}
}
private void backFrame(int index, IFrameReadyListener listener) {
int delimiterLen = delimiterBytes.length;
int frameLen = index + delimiterLen;
if (listener != null) {
byte[] result = new byte[frameLen];
for (int i = 0; i < frameLen; ++i) {
result[i] = destBytes[i];
destBytes[i] = 0;
}
listener.onFrameReady(result);
}
//数据前移
for (int i = frameLen, j = 0; i < writeIndex; ++i, ++j) {
destBytes[j] = destBytes[i];
destBytes[i] = 0;
}
writeIndex -= frameLen;
}
}