【Android】TVL数据流解析

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

猜你喜欢

转载自blog.csdn.net/u013372185/article/details/80252557