鮭とばとコーヒー

四度目の正直ブログ

ab1ファイルを読み込みたい(2)

早くも飽き始めているけれど、書いていきます。
誰も読んでいないかも知れないけど、自分のモチベーションを保つためにも一応。

確か前回は、ヘッダについて書いたように記憶している。
今回はディレクトリのお話。


ディレクトリの構成

恐らく全てのディレクトリは、以下の形式で保存されている。 C-likeな擬似?コードが仕様書にあるので、転載。

struct DirEntry{  
  SInt32 name; //tag name  
  SInt32 number; //tag number  
  SInt16 elementtype; //element type code  
  SInt16 elementsize; //size in bytes of one element  
  SInt32 numelements; //number of elements in item  
  SInt32 datasize; //size in bytes of item  
  SInt32 dataoffset; //item's data, or offset in file  
  SInt32 datahandle; //reserved  
}

SInt16, SInt32はそれぞれ16byte, 32byteの符号付き整数を表す。
それぞれの変数の意味する所を、簡単に書いていこうと思う。

name

ディレクトリの名前。そのままですね。仕様書にはtag nameとある。
またしても公式のドキュメントの最後の方に、nameとデータの内容についてのまとめが乗っているので、見ておいて頂きたい。

number

tag numberだそうだが、何と説明すればよいものかよく分からない。
というか、僕があまり理解していない。 少なくとも、name属性と対応付けて考えなければならないということは分かる。

例えば、
name = "DATA"
の時、
number = 1
及び
number = 2
はそれぞれ、channel1, channel2の生データとのこと。パーサを書くときに必要になる筈。
因みに、signed intとなっているが、慣習的に値として1000より小さい正の数しか取らない。
故に、1から始まる。

elementtype

含まれるデータの型を表す番号。
例えば、19ならばC言語の(null文字が末尾についた)文字列を表す。
仕様書のp.13から対応表が載っている。

elementsize

データの要素のサイズ(byte)。elementtypeによって規定されるので、これはredundantな情報だと思うのだが。
念の為にelementtypeとのconsistencyが取れているか確認するコードくらい書いてやってもいいかな。
先ほど例に上げたC言語の文字列なら、elementsizeは1であることに注意して欲しい。
データのサイズを表すものではない。

numelements

配列の長さといった所だろうか。
elementtype = 19
なら、文字列の長さ+1(null文字分)となる筈だ。

datasize

データ全体のサイズ(byte)。
原理的にelementsize * numelementsとなるはずで、コレもredundantだと思う。

dataoffset

データの開始位置をbyteで表す数。先頭からx byte目からこれこれのデータが格納されていますよ、という値。5以上になるはず。先頭4byteは"ABIF"だもんね。

datahandle

多分どうでもいい。予備の領域で、nullがギッシリ詰まっているはず。無視しよう。


注意すべき点が1つある。
基本的には上に書いた通りだが、datasizeが4以下の時には、そのディレクトリ専用の領域は確保されず、dataoffsetの中身がそのままデータになっている。
例えば、
elementtype = 19
の時、データ型はC言語での文字列であるので、中身が文字列"AB" であるならば、
dataoffset = 0x41420000
となっている筈だ。

実際にアプリケーションを開発するときは、

fseek(fp, dataoffset, SEEK_SET);
if (datasize > 4){
    fread(buf, elementsize, numelement, fp);
} else {
    buf = dataoffset;
}

的な感じで。やればいいのかな。
その後でnameやnumberを見て、何のデータなのか判別しようと思っている。

tdirについても書きたかったんだけど、長いから次にします。