Previous: Bindat Functions, Up: Byte Packing [Contents][Index]
以下の2つはbindat.elを使用した完全な例です。1つ目は単純なバイトパッキングを示します:
(require 'bindat) (defun rfc868-payload () (bindat-pack '((now-hi u16) (now-lo u16)) ;; EmacsはUnixエポックを使用する ;; RFC868エポックは1900-01-01 00:00:00なので ;; Unixエポックより2208988800秒(#x83aa7e80秒)大きい (let ((now (time-add nil '(#x83aa #x7e80)))) `((now-hi . ,(car now)) (now-lo . ,(cadr now)))))) (let ((s (rfc868-payload))) (list (multibyte-string-p s) (mapconcat (lambda (byte) (format "%02x" byte)) s " ") (current-time-string))) ⇒ (nil "dc 6d 17 01" "Fri Mar 10 13:13:53 2017")
以下は複雑な構造体を定義してunpackする例です。以下のようなCの構造体があるものとします:
struct header { unsigned long dest_ip; unsigned long src_ip; unsigned short dest_port; unsigned short src_port; }; struct data { unsigned char type; unsigned char opcode; unsigned short length; /* ネットワークバイトオーダー */ unsigned char id[8]; /* NUL終端文字列 */ unsigned char data[/* (length + 3) & ~3 */]; }; struct packet { struct header header; unsigned long counters[2]; /* リトルエンディアンオーダー */ unsigned char items; unsigned char filler[3]; struct data item[/* items */]; };
対応するデータレイアウト仕様が以下です:
(setq header-spec '((dest-ip ip) (src-ip ip) (dest-port u16) (src-port u16))) (setq data-spec '((type u8) (opcode u8) (length u16) ; ネットワークバイトオーダー (id strz 8) (data vec (length)) (align 4))) (setq packet-spec '((header struct header-spec) (counters vec 2 u32r) ; リトルエンディアンオーダー (items u8) (fill 3) (item repeat (items) (struct data-spec))))
バイナリーデータによる表現は:
(setq binary-data [ 192 168 1 100 192 168 1 101 01 28 21 32 160 134 1 0 5 1 0 0 2 0 0 0 2 3 0 5 ?A ?B ?C ?D ?E ?F 0 0 1 2 3 4 5 0 0 0 1 4 0 7 ?B ?C ?D ?E ?F ?G 0 0 6 7 8 9 10 11 12 0 ])
対応するデコードされた構造体は:
(setq decoded (bindat-unpack packet-spec binary-data)) ⇒ ((header (dest-ip . [192 168 1 100]) (src-ip . [192 168 1 101]) (dest-port . 284) (src-port . 5408)) (counters . [100000 261]) (items . 2) (item ((data . [1 2 3 4 5]) (id . "ABCDEF") (length . 5) (opcode . 3) (type . 2)) ((data . [6 7 8 9 10 11 12]) (id . "BCDEFG") (length . 7) (opcode . 4) (type . 1))))
以下はこの構造体からデータを取得する例です:
(bindat-get-field decoded 'item 1 'id) ⇒ "BCDEFG"
Previous: Bindat Functions, Up: Byte Packing [Contents][Index]