AMF0
AMF(ActionScript Message Format) とは Flash などでデータのやりとりに用いられているフォーマットらしく、 AMF0 と AMF3 のバージョンがあります。
ここでは AMF0 の仕様について、英文を適当に読んでにそれっぽく解釈したものを記述していきます。
基本的なデータ単位
- U8
- 符号なし 8 ビットのデータ
- U16
- 符号なし 16 ビット(ビッグエンディアン)のデータ
- U32
- 符号なし 32 ビット(ビッグエンディアン)のデータ
- DOUBLE
- IEEE 754 の倍精度浮動小数点数(ビッグエンディアン)のデータ
- UTF8-char
- UTF-8 でエンコードされた 1 文字のデータ。 1 バイトとは限らない
- UTF-8 = U16 *(UTF8-char)
- UTF-8 でエンコードされた文字列。文字列部分のバイト数を U16 で指定する
- UTF-8-empty = U16
- 長さ 0x0000 の空文字列
- UTF-8-long = U32 *(UTF8-char)
- 長くても大丈夫なようにした文字列
- value-type
- データ(後述)
パケットの構造
AMF0 のデータ単位であるパケットは以下の構造になっています。
amf-packet = version header-count *(header-type) message-count *(message-type) header-type = header-name must-understand header-length value-type message-type = target-uri response-uri message-length value-type
省略した version = U16 などと一緒に整理すると、
value-type
value-type には数値や配列など任意のデータを記述できるものです。
value-type = number-type | boolean-type | string-type | object-type | null-type | undefined-type | reference-type | ecma-array-type | strict-array-type | date-type | long-string-type | xml-document-type | typed-object-type number-type = 0x00 DOUBLE boolean-type = 0x01 U8 string-type = 0x02 UTF-8 object-type = 0x03 *(object-property) null-type = 0x05 undefined-type = 0x06 ecma-array-type = 0x08 array-count *(object-property) strict-array-type = 0x0A array-count *(value-type)
value-type は number-type や string-type など各記法の集合ですが、共通して 1 バイト目に識別用のマーカが存在しています。このマーカをもとに場合分けしてデータを読み取ります。
null-type と undefined-type はマーカ以外にデータを持ちません。 number-type はマーカの後ろに 8 バイトの倍精度浮動小数点数である DOUBLE をとります。 boolean-type は U8 をとり、 0x00 なら false 、 0x00 以外なら true となります。 string-type は UTF-8 ですので、文字列のバイト数 U16 と文字列部分 *(UTF8-char) がマーカの後に続きます。
次に複合型として
object-type = 0x03 *(object-property) ecma-array-type = 0x08 array-count *(object-property) strict-array-type = 0x0A array-count *(value-type) object-property = (UTF-8 value-type) | (UTF-8-empty 0x09) array-count = U32
ActionScript におけるオブジェクトおよび ECMAScript の配列は連想配列のように扱うことができます。これらのデータは object-type ないしは ecma-array-type として記述されます。 ecma-array-type の場合、 array-count = U32 で key-value ペアの数が記述されます。
AMF0 では、キーは数値であっても UTF-8 としてコードされます。そしてそれに対応する値は value-type で記述されます。 key-value ペア列挙の末端には 0x0000 0x09 (UTF-8-empty object-end-marker) が存在します。
一方で添字が数値の一般的な配列は strict-array-type の記法が用いられます。末端コードがないので、要素数を array-count から取得する必要があります。
ともに値は value-type ですので、オブジェクトをネストすることも可能です。
仕様書
- AMF0
- AMF3
付随する説明や省略したデータ型などの情報は直接読んでください。10 ページちょっとの文書ですので。
ただし typo (というよりコピペミス?)と思われる箇所がいくつかみられます。
- AMF0 仕様書
- 5 ページ目
- anonymous-object-type ではなく object-type
- 6 ページ目 ecma-array-type の定義内
- マーカがない
- 7 ページ目 strict-array-type の定義内
- マーカがない
- 8 ページ目 object-type の定義内
- object-type ではなく typed-object-type 。同様に typed-object-marker
- ヘッダ
- AMF 3 になってる
- 5 ページ目
まあ typo じゃなくて正しい情報なのかもしれませんが、うーん。