Next: Bindat Functions, Up: Byte Packing [Contents][Index]
unpackとpackを制御するためには、fieldsの名前とタイプを記述するデータレイアウト仕様(data layout
specification)というネストされた特別なリストを記述します。この仕様は処理される各フィールドの長さ、packおよびunpackする方法を制御します。わたしたちはbindat仕様の値を、通常は-bindat-specで終わる名前の変数に保持しています。このような種類の名前は、自動的に危険(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 lenNUL終端された文字列。長さlenの固定長フィールド内。
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にセットすることにより、カレントの繰り返し終了後に最内繰り返しブロックを終了する。