デコード済のバイナリデータのsplitや、splitされた状態からのjoin(復元)

  • 概要

    ここでは、Ls11Mod APIのAPIとなる「split」と「join」を解説しています。

    LS11のファイルをデコードしたとしても、そのままでは、まだ使いにくいデータ形式です。
    例えば、message.n6pをデコードしたとしても、それぞれのファイルはなおも、プログラムでは扱いにくいとわかるでしょう。
    また、迂闊にデータの長さが変わるような変更をすると、データ表示の際にずれ込むことも分かります。

    これらの問題を解決するため、splitとjoinの2つの関数が存在します。

  • 分解と結合

        // 1つの扱い難いバイナリデータを、意味単位で分解する
        void ls11_SplitData(vector<byte> &vSrcJoinedData, vector<vector<byte>> *vDstSplittedData);
    
        // 分解したものを1つに結合し、元へと戻す。
        void ls11_JoinData(vector<vector<byte>> &vSrcSplittedData, vector<byte> *vDstJoinedData);
        
  • 分解~結合の具体例

    message.n6pをデコードしたが、そのままでは扱いにくいので、message.005をさらに分解して、vSplittedDataへと格納する。
    そして、4番目(index的には3)のデータの塊の要素を見る。
    又、vSplittedDataしたものを、元の状態(message.003として扱える状態)へと戻す。

    
        vector<vector<byte>> vBufDecodedData;
        ls11_DecodePack("message.nb6", NULL, &vBufDecodedData );
    
        vector<vector<byte>> vSplittedData;
        ls11_SplitData( vBufDecodedData[5], &vSplittedData );
    
        char *test = (char *)&vSplittedData[3][0];
        // └ ここをデバッガで張ればよい。何が得られるかわかるだろう。
    
        // 特定部分を変更をする際には、一度該当要素をコピーした後、該当要素の部分のvector要素をクリアした方が良い。
        // vectorは一度要素を確保してしまうと、小さな方向にsize()が変化しにくいので、必ず適切なsize()となるように、意識すること。
    
        vector<byte> vBufJointedData;
        ls11_JoinData( vSplittedData, &vBufJointedData );
    
        
  • LS11の分解と結合のフォーマットデータの詳細

    LS11 Archieveで分解して、たとえば、bfile.001となったデータを見てみると、

    • ファイルの先頭から、2バイトずつ、
      各メッセージの格納開始アドレス(位置)が、指定されていて、並んでいる。
    • それが終わるとデータ本体が配列のように並ぶ。

    よって、

    • 先頭から最初の2バイトのアドレスが、一番最初のデータ本体のアドレス、
    • 先頭から次の2バイトのアドレスが、2番目のデータ本体の開始アドレス

    という感じ。

    これは、途中のデータの長さを伸ばすと、先頭のこれらアドレス群を修正する必要があることを意味する。

    今回紹介した、splitやjoinの関数は、

    • ls11_SplitDataは、この各々のアドレス情報に基づいて、データを分割する。
    • ls11_JoinData は、vectorのsize()から計算して、各々のアドレス位置を割り出し、全てを連結して1つにしてくれる。

    というわけである。