= libpack =
libpackはCのデータをバイナリ列としてシリアライズするためのライブラリです。
== 必要性 ==
Cで書かれたプログラム同士がデータをやり取りする場合、もっとも普通には構造体を用います。同じプログラム内では関数の引数として構造体やそのポインタを渡しますし、同じ計算機上で動くプログラム同士なら構造体を伝送路(ソケットや共有メモリを使うでしょう)経由でコピーするだけでほとんどの場合、事足ります。
しかし、異なるアーキテクチャの計算機同士の通信の場合、Cで同じように定義した構造体であっても、そのバイナリの構造が異なる場合があります。たとえば構造体にはパディング(32ビット境界にメンバ変数がそろうようにコンパイラが勝手にする詰め物)があります。また計算機ごとにバイトオーダー(主にはリトルエンディアンやビッグエンディアン)の違いがあります。
一つのアイデアとして、sprintfのように書式文字列と可変引数により、データをパッケージします。書式文字列がデータの型を表し、その型の引数を(いくつでも並べて)与えることで、構造体のようなパディングのない、連続的な(シリアライズされた)一つのデータ領域とします。また、バイトオーダーを変換する機能も持たせることができます。
「プログラミング作法(The Practice of Programming) Brian Kernighan, Rob Pike」にまさにこのアイデアが説明されています。本の中では、たとえば下のようなコードです:
----
{{{
char buff[100];
char cv;
short hv;
long lv;
/* シリアライズ */
pack (buff, "c h l", cv, hv, lv);
/* デシリアライズ */
unpack (buff, "c h l", &cv, &hv, &lv);
}}}
これを拡張して、配列などを扱えるようにせよ、という演習問題も含まれています。libpackはそれに対する一つの回答です。
== 特徴 ==
とにかくシンプルな構成にとどめます。パワフルな計算機での使用だけでなく、ロボットや組み込み機器のようなマイコンでの利用も想定しているからです。ANSI-Cの機能のみで実現することとしています。
== 他の言語 ==
このアイデアは、いくつかのスクリプト言語でバイナリデータを作成するために使われています。
* Perlのpack/unpack
* Pythonのstruct
* Ruby struct
== 他のライブラリ ==
プロジェクトを作成してから知りましたが、同様の機能を実現する同名のライブラリを公開している方が居ました。なんてこった。名前まで同じとは。改名が必要?
しかし見てみると、機能的にはちょっと不便と思われる部分があります。
* libpack [http://www.leonerd.org.uk/code/libpack/]
* 書式文字列の仕様 FormatDoc