Next: Bindat Functions, Up: Byte Packing [Contents][Index]
unpackとpackを制御するためには、データレイアウト仕様(data layout specification)を記述します。これは名前付きで、かつタイプ付けされたフィールド(field)を記述する、特別なネスト化リストです。これは、処理する各フィールドの長さ、およびそれをpackおよびunpackする方法を制御します。わたしたちは、名前が‘-bindat-spec’で終わる変数では、bindatの仕様を遵守します。この類の変数名は、自動的に“risky(危険)”だと認識されます。
フィールドのタイプ(type)は、そのフィールドが表すオブジェクトのサイズ(バイト単位)、およびそれがマルチバイトフィールドなら、そのフィールがバイトオーダーされる方法を記述します。可能なオーダーは“ビッグエンディアン(big
endian。ネットワークバイトオーダーとも呼ばれる)”、および“リトルエンディアン(little
endian)”の2つです。たとえば数字#x23cd(10進の9165)のビッグエンディアンは#x23
#xcdの2バイト、リトルエンディアンは#xcd #x23になるでしょう。以下は可能なタイプの値です:
u8byte長さ1の符号なしタイプ。
u16wordshort長さ2のネットワークバイトオーダーによる符号なし整数。
u24長さ3のネットワークバイトオーダーによる符号なし整数。
u32dwordlong長さ4のネットワークバイトオーダーによる符号なし整数。注意: これらの値はEmacsの整数の実装に制限されるだろう。
u16ru24ru32rそれぞれ長さ2、3、4のリトルエンディアンオーダーによる符号なし整数。
str len長さlenの文字列。
strz len長さlenの固定長フィールド内のNUL終端された文字列。
vec len [type]タイプtype
(デフォルトはbyte)のlen要素のベクター。typeは上述した単純なタイプのいずれか、あるいは(vec
len [type])という形式のリストによる別ベクターの指定。
ipインターネットアドレスを表す4つのbyteのベクター。たとえばlocalhostは[127 0 0 1]。
bits lenlenバイト内のセットされたビット位置のリスト。バイトはビッグエンディアンでビット位置は8 * len
- 1で始まり0で終わるよう番号が付与される。たとえばbits 2では、#x28
#x1cは(2 3 4 11 13)、#x1c #x28は(3 5 10 11
12)にunpackされる。
(eval form)formはフィールドがpackやunpackされた瞬間に評価されるLisp式。評価した結果は上記にリストしたタイプ使用のいずれかであること。
固定長フィールドでは長さlenがフィールド内のバイト数を指定する整数として与えられます。
フィールド長が固定でなければ通常は先行するフィールドの値に依存します。この場合には長さlenは後述のbindat-get-fieldのフォーマット指定によりフィールド名(field
name)を指定するリスト(name ...)、または式(eval form)
(formはフィールド長を指定する整数に評価されること)のいずれかで与えることもできます。
フィールド仕様は一般的に([name]
handler)という形式をもち、nameはオプションです。紛らわしくなるのでタイプ仕様(上述)やハンドラー仕様(後述)で意味をもつシンボルの名前は使用しないでください。nameはシンボルまたは式(eval
form)でもよく、この場合にはformはシンボルに評価される必要があります。
handlerはそのフィールドがpackやunpackされる方法を記述して、以下のいずれかを指定できます:
typeタイプ仕様typeに応じてこのフィールドのunpack/packを行う。
eval form副作用のためだけにLisp式formを評価する。フィールド名が指定されたら値はそのフィールド名にバインドされる。
fill lenlenバイトをスキップする。pack化ではそれらを未変更のままとして、通常それらは0のままとなることを意味する。unpack化ではそれらが無視されることを意味する。
align lenlenバイトの次の倍数にスキップする。
struct spec-name副仕様(sub-specification)としてspec-nameを処理する。これは別の構造体内にネストされる構造体を記述する。
union form (tag spec)…Lisp式formを評価、それにマッチする最初のtagを探して、それに関連付けられたレイアウト仕様specを処理する。マッチングは以下の3つのいずれかで発生し得る:
(eval
expr)という形式をもつ場合には、変数tagを動的にformの値にバインドしてexprを評価する。結果が非nilならマッチを示す。
equalならマッチ。
tなら無条件にマッチ。
repeat count field-specs…field-specsを再帰的に順次処理した後に、最初のものから繰り返して、すべての仕様全体をcount回処理する。countはフィールド長と同じフォーマットを使用して与えられる。evalフォームが使用された場合には1回だけ評価される。正しく処理されるためには、field-specs内の各仕様が名前を含まなければならない。
bindat仕様内で仕様される(eval
form)フォームでは、評価の間にformはこれらの動的にバインドされた変数へのアクセスと更新が可能である。
last最後に処理されたフィールドの値。
bindat-rawバイト配列のデータ。
bindat-idxunpack化/pack化にたいする、(bindat-rawでの)カレントインデックス。
structこれまでにunpackされた構造化データ、またはpackされた構造体全体を含むalist。この構造体の特定のフィールドにアクセスするためにbindat-get-fieldを使用できる。
countindexrepeatブロック内部では、これらは(countパラメーターで指定された)繰り返しの最大回数、および(0から数えた)カレント繰り返し回数を含む。countを0にセットすることにより、カレントの繰り返し終了後に最内繰り返しブロックを終了する。