C#解析VBF文件并分包

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Text.RegularExpressions;

namespace AutomativeLightDetection.Structs
{
public class VbfSetting
{
public string description { get; set; }
public string sw_part_number { get; set; }
public string sw_version { get; set; }
public string sw_part_type { get; set; }
public string data_format_identifier { get; set; }
public string ecu_address { get; set; }
public string verification_block_root_hash { get; set; }
public string verification_block_start { get; set; }
public string verification_block_length { get; set; }
public byte[] sw_signature_dev { get; set; }
public string file_checksum { get; set; }
public byte[] callAddress { get; set; }
public byte[] eraseAddr { get; set; }
public int Index { get; set; }
public List<DataSegment> SegmentList { get; set; }

    public static VbfSetting ReadVbfFile(string vbfFileName)
    {
        try
        {
            VbfSetting myVbfSetting = new VbfSetting();

            //read all data from vbf file
            FileStream fs = new FileStream(vbfFileName, FileMode.Open);
            byte[] allDataArray = new byte[fs.Length];
            int resInt = fs.Read(allDataArray, 0, (int)(fs.Length));
            //BinaryReader br = new BinaryReader(fs);
            fs.Close();

            //find srart index of data
            string tempHeaderStr = Encoding.ASCII.GetString(allDataArray.Skip(0).Take(8192).ToArray());
            int sCount = 0;
            int leftIndex = 0;
            int rightIndex = 0;
            int dataStartIndex = 0;
            for (int i = 0; i < 32; i++)
            {
                leftIndex = tempHeaderStr.IndexOf("{");
                rightIndex = tempHeaderStr.IndexOf("}");
                if (leftIndex >= 0 || rightIndex >= 0)
                {
                    if (leftIndex < rightIndex)
                    {
                        sCount++;
                        tempHeaderStr = tempHeaderStr.Substring(leftIndex + 1);
                        dataStartIndex += leftIndex + 1;
                    }
                    else
                    {
                        sCount--;
                        tempHeaderStr = tempHeaderStr.Substring(rightIndex + 1);
                        dataStartIndex += rightIndex + 1;
                    }
                }

                if (sCount <= 0)
                {
                    break;
                }
            }

            //get header String
            byte[] headerArray = allDataArray.Skip(0).Take(dataStartIndex).ToArray();
            string headerString = Encoding.ASCII.GetString(headerArray);

            myVbfSetting.description = ReadParameter("description", headerString);
            myVbfSetting.sw_part_number = ReadParameter("sw_part_number", headerString);
            myVbfSetting.sw_version = ReadParameter("sw_version", headerString);
            myVbfSetting.sw_part_type = ReadParameter("sw_part_type ", headerString);
           if(ReadParameter("sw_part_type ", headerString)=="SBL")
            {
                myVbfSetting.Index = 0;
            }
            if (ReadParameter("sw_part_type ", headerString) == "EXE")
            {
                myVbfSetting.Index = 2;
            }
            if (ReadParameter("sw_part_type ", headerString) == "DATA")
            {
                myVbfSetting.Index = 1;
            }
            myVbfSetting.data_format_identifier = ReadParameter("data_format_identifier", headerString);
            myVbfSetting.ecu_address = ReadParameter("ecu_address", headerString);
            myVbfSetting.verification_block_root_hash = ReadParameter("verification_block_root_hash", headerString);
            myVbfSetting.verification_block_start = ReadParameter("verification_block_start", headerString);
            myVbfSetting.verification_block_length = ReadParameter("verification_block_length", headerString);
            myVbfSetting.sw_signature_dev = stringToHex(ReadParameter("sw_signature_dev", headerString));
            myVbfSetting.file_checksum = ReadParameter("file_checksum", headerString);
            myVbfSetting.callAddress = stringToHex(ReadParameter("call", headerString));

            myVbfSetting.eraseAddr = stringToHex(ReadEraseParameter(headerString));


            byte[] dataArray = allDataArray.Skip(dataStartIndex).ToArray();
            MemoryStream stream = new MemoryStream(dataArray);
            StreamReader reader = new StreamReader(stream);

            List<DataSegment> dataSegmentList = new List<DataSegment>();

            int segIndex = 0;
            while (segIndex < dataArray.Length)
            {
                DataSegment dataSegment = new DataSegment();

                dataSegment.Length = Convert.ToInt32(dataArray[segIndex + 4].ToString("X2") + dataArray[segIndex + 5].ToString("X2") + dataArray[segIndex + 6].ToString("X2") + dataArray[segIndex + 7].ToString("X2"), 16);
                dataSegment.StartAddr = dataArray.Skip(segIndex).Take(4).ToArray();
                byte[] data= dataArray.Skip(segIndex + 8).Take(dataSegment.Length).ToArray();
                dataSegment.SegData= splitPacket(data);
                dataSegmentList.Add(dataSegment);

                //len + addrlen + crc
                segIndex += dataSegment.Length + 8 + 2;
            }
            myVbfSetting.SegmentList = dataSegmentList;
            return myVbfSetting;
        }
        catch (Exception)
        {

            throw;
        }

    }
    public  static byte[] stringToHex(string value)
    {
        value=value.Replace("0x", "");
        value = value.Replace(",", "");
        return Split(value,2);

    }
    static byte[] Split(string str, int count)
    {
        var list = new List<byte>();
        int length = (int)Math.Ceiling((double)str.Length / count);

        for (int i = 0; i < length; i++)
        {
            int start = count * i;
            if (str.Length <= start)
            {
                break;
            }
            if (str.Length < start + count)
            {
                list.Add(Convert.ToByte(str.Substring(start),16));
            }
            else
            {
                list.Add(Convert.ToByte(str.Substring(start, count),16));
            }
        }

        return list.ToArray();
    }
    public static string SubstringSingle(string source, string startStr, string endStr)
    {

        Regex rg = new Regex("(?<=(" + startStr + "))[.\\s\\S]*?(?=(" + endStr + "))", RegexOptions.Multiline | RegexOptions.Singleline);
        return rg.Match(source).Value;
    }

    private static string ReadEraseParameter(string sourceString)
    {
        string valueStr = SubstringSingle(sourceString, "erase = {{", "}\\};");
        valueStr = valueStr.Trim();
        return valueStr;
    }

    private static string ReadParameter(string parameterName, string sourceString)
    {
        //Regex regex = new Regex(parameterName + " = (.+);", RegexOptions.Multiline | RegexOptions.Singleline);
        //Match match = regex.Match(sourceString);
        //string value = match.Groups[1].Value;

        string value = SubstringSingle(sourceString, parameterName + " = ", ";");

        //remove """"
        Regex regex = new Regex("\"*\"");
        if (regex.IsMatch(value))
        {
            value = value.Replace("\"", "");
        }

        //remove "0x"
        regex = new Regex("0x*");
        if (regex.IsMatch(value))
        {
            value = value.Replace("0x", "");
        }

        return value;
    }

    /// <summary>
    /// 分割数据包
    /// </summary>
    /// <param name="hexchar">要分割的数据</param>
    /// <returns></returns>
   static List<MessagePacket> splitPacket(byte[] hexchar)
    {
        int total = (hexchar.Length / 2048) + 1;//总共的包数
        int remainder = hexchar.Length % 2048;//发送最后一个包剩余的数据量
        int count = 1;
        int k = 1;
        List<MessagePacket> packets = new List<MessagePacket>();
        for (int index = 1; index <= total; index++)
        {
            MessagePacket messagePacket = new MessagePacket();
            messagePacket.Index = index;

            messagePacket.sequence = k;
            if (k == 255)
            {
                k = 0;
            }
            else
            {
                k++;
            }
            int dataIndex = (index - 1) * 2048;//数据所在位置
            int TrueLength = (index) * 2048;//传输数据字节位置
            byte[] data;
            if (index != total)
            {

                byte[] chunk = new byte[2048];
                Buffer.BlockCopy(hexchar, (index - 1) * 2048, chunk, 0, 2048);
                messagePacket.DataList = chunk;
            }
            else
            {

                byte[] chunk = new byte[remainder];
                Buffer.BlockCopy(hexchar, (index - 1) * 2048, chunk, 0, remainder);
                messagePacket.DataList = chunk;
            }
            packets.Add(messagePacket);

        }
        return packets;
    }

}

public class MessagePacket
{
    public int sequence { get; set; }//数据包所持有的序号
    public int Index { get; set; }//第几个包
    public int total { get; set; }//总共数据包的数量
    public byte[] DataList { get; set; } //分包的数据


    public MessagePacket()
    {
    }

    public MessagePacket(int sequence, int total, int Index, byte[] dataList, int chunkLength)
    {
        this.sequence = sequence;
        this.total = total;
        DataList = dataList;
    }
}
public class DataSegment
{
    public int Length { get; set; }

    public byte[] StartAddr { get; set; }

    public List<MessagePacket> SegData { get; set; }
}

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343