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
になるでしょう。以下は可能なタイプの値です:
u8
byte
長さ1の符号なしタイプ。
u16
word
short
長さ2のネットワークバイトオーダーによる符号なし整数。
u24
長さ3のネットワークバイトオーダーによる符号なし整数。
u32
dword
long
長さ4のネットワークバイトオーダーによる符号なし整数。注意: これらの値はEmacsの整数実装により制限され得る。
u16r
u24r
u32r
それぞれ長さ2、3、4のネットワークバイトオーダーによる符号なし整数。リトルエンディアンオーダーによる符号なし整数。
str len
長さlenの文字列。
strz len
NUL終端された文字列。長さlenの固定長フィールド内。
vec len [type]
タイプtype
(デフォルトはbyte)のlen要素のベクター。typeは上述した単純なタイプのいずれか、あるいは(vec
len [type])
という形式のリストによる別ベクターの指定。
ip
インターネットアドレスを表す4つのbyteのベクター。たとえばlocalhostは[127 0 0 1]
。
bits len
lenバイト内のセットされたビット位置のリスト。バイトはビッグエンディアンでビット位置は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 len
lenバイトをスキップする。pack時には未変更のままとなり、それは通常は0のままであることを、unpack時には無視されることを意味する。
align len
lenバイトの次の倍数にスキップする。
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-idx
unpack化/pack化にたいする、(bindat-raw
での)カレントインデックス。
struct
これまでにunpackされた構造化データ、またはpackされた構造体全体を含むalist。この構造体の特定のフィールドにアクセスするためにbindat-get-field
を使用できる。
count
index
repeat
ブロック内部では、これらは(countパラメーターで指定された)繰り返しの最大回数、および(0から数えた)カレント繰り返し回数を含む。count
を0にセットすることにより、カレントの繰り返し終了後に最内繰り返しブロックを終了する。