tlv資料格式:type(1位元組)+length(2位元組)+value(有效資料);
長度規定(雙方規定的):{低位、高位} ,例:{(byte)0x5A,(byte)0x00} 轉成int = 0x005A = 90 ;
package com.example.util;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
/**
* @author alan
* Created by Administrator on 2018/4/8 0008.
*/
public class TLVUtil {
public interface CallBack {
void getValue(String valueData);
}
;
/**
* 從TLV格式資料流解析出中的value
*
* @param inputStream
*/
public void parseValueFromTLVInputStream(InputStream inputStream, CallBack callBack) throws Exception {
try {
boolean isOnce = true;//開始一次tlv資料讀取
StringBuilder builder = new StringBuilder();
int leftPartSize = 0;//剩餘長度
while (true) {
Thread.sleep(50);
if (inputStream == null) return;
if (inputStream.available() > 0) {//收到一次推送的資料
byte[] valueArray;
int available = inputStream.available();
//繼續讀取value(上次tlv不完整)
if (!isOnce) {
// byte[] buf = new byte[leftPartSize];
// int len = inputStream.read(buf);
// String part = new String(buf, 0, len);
// builder.append(part);
if (leftPartSize > available) {//剩下已知的 > 讀取的,還需要繼續讀取
leftPartSize = leftPartSize - available;
//取vaule資料
valueArray = new byte[available];
int read = inputStream.read(valueArray);
String valueStr = new String(valueArray, 0, read);
builder.append(valueStr);
continue;
} else {//剩下已知的 =< 讀取的
//拆分出最後已知的
valueArray = new byte[leftPartSize];
int read = inputStream.read(valueArray);
String valueStr = new String(valueArray, 0, read);
// 組成完整value
builder.append(valueStr);
String allValue = builder.toString();
builder = new StringBuilder();//清空
//<處理>
callBack.getValue(allValue);
//開始下次tlv處理
isOnce = true;
available = available - leftPartSize;
leftPartSize = 0;
builder = new StringBuilder();//清空
if (available == 0) {//沒資料了,重新讀流
continue;
}
Log.e("TAG", "下次tlv處理-available->" + available);
}
}
//tlv處理
while (isOnce) {
//取type
byte[] typeArray = new byte[1];
inputStream.read(typeArray);
int type = (typeArray[0] & 0xff);//第一個位元組表示type(byte轉int)
//取length(2位元組)
byte[] lengthArray = new byte[2];
inputStream.read(lengthArray);
int length = bytesTolength(lengthArray);
Log.e("TAG", "tlv-length->" + length);
//判斷
if (available > (length + 3)) {//推過來的 》已知的 ,繼續讀剩下新的tlv
isOnce = true;
leftPartSize = available - (length + 3);
available = leftPartSize;
//取vaule資料(完整)
valueArray = new byte[length];
int read = inputStream.read(valueArray);
String valueStr = new String(valueArray, 0, read);
// builder.append(valueStr);
//<處理>
callBack.getValue(valueStr);
} else if (available == (length + 3)) {
isOnce = true;
//取vaule資料(完整)
valueArray = new byte[length];
int read = inputStream.read(valueArray);
String valueStr = new String(valueArray, 0, read);
// builder.append(valueStr);
//<處理>
callBack.getValue(valueStr);
break;
} else {//available < (length + 3) 讀取不完整,需要繼續讀取
isOnce = false;
leftPartSize = (length + 3) - available;
//取vaule資料(不完整)
valueArray = new byte[available - 3];
int read = inputStream.read(valueArray);
String valueStr = new String(valueArray, 0, read);
builder.append(valueStr);
break;
}
}//end while-isOnce
}
}
} catch (IOException e) {
e.printStackTrace();
Log.e("TAG", "client connected name--->" + Thread.currentThread().getName() + " e-->" + e.getMessage());
// Log.e("TAG", "異常-tlv解析->" + e.getMessage());
}
}
/**
* byte數組轉長度值 {低位,高位} [參照文檔規定]
*
* @param array
* @return
*/
public int bytesTolength(byte[] array) {
int length = 0;
if (array != null) {
length = ((array[0] & 0xff))
| ((array[1] & 0xff) << 8);
}
return length;
}
}