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についても書きたかったんだけど、長いから次にします。