ステート保存用変数を把握しよう

http://d.hatena.ne.jp/studiokingyo/20050905の続き
C言語でのライブラリ作りで不満が出てくるのが抽象的なインターフェイスを関数のポインタやswitch分岐でしか統一できないところは前に書いた。
そしてもうひとつ。いちいちステート保存用構造体の変数*1を関数の第一引数*2に宣言しなければならない。

例えばC言語での配列処理をするとしよう*3


///注意:擬似コードです
void crypt_process(CRYPT_OBJ *crypt_obj,uint8 *dest,
 const uint8 *src,size_t destsize)
{
size_t offset = 0;
uint8 buff[512];
size_t count = destsize / 512;
for(int i=0;i<count;i++){
memcpy(buff,&src[offset],512);
crypt512(crypt_obj,buff);
memcpy(&dest[offset],buff,512);
offset+=512;
}
}
のような処理だ。
さて、ここで配列処理に使っているステート保存用変数はどれだろうか?
私は専門家ではないので責任はもてないが経験上offsetとdestsizeである。
destバッファのオフセットを処理したら処理した分*4バッファを進めている。
また、destバッファが有効な領域からはみ出さないようにdestsizeは有効な領域を示している。
これがdestに対するステートだ。
まだ使っていないバッファを指定分使ったら指定分バッファのオフセットを進めて空いているバッファ領域を使いたい。
この要望に答えたのがdkutil_cのdkcMemoryStream.hに宣言されている関数郡だ。*5
そして、このdkcMemoryStream.hのインターフェイスを見て何かに似ていると思った方。正解である。
cstd*6のfopen()fclose()fwrite()fread()等のファイルストリームのインターフェイスに似ているではないか。
そう、これはcstdのファイルに入出力機能をメモリ領域に入出力の機能に変えただけのライブラリなのだ。
なんか、それだけのためにこれだけ文字打って、新しい名前の関数作って、構造体作って、定義作って大げさじゃない?
と思った方!そう!そこなのだ!C言語でライブラリを作るめんどくささは!
そんなめんどくさい事をしっかり行ったのがdkcStream.cおよびdkcStream.hである。
これは前述のメモリストリームとファイルストリームのどちらを使うかを初期化時に選択できるラッパー関数郡である。
これを組むのに良くがんばったと思う。本当に単純な作業でこれを仕事でやったら気が狂うのではないかと思った。(笑)*7

さて、これらのソースコードを見終わってC++でどのようにしてObjectiveでスマートなライブラリを組むかが分かる人は次回は見なくてもOKである。
ぶっちゃけC++でのクラスの作り方の極意はクラス内にステート用の変数だけをもたせるという事を念頭において組めばよいのですから。*8後は次回である。

追伸:ステートって情報処理やプログラミングで実際どういう意味なのかは分かりません。(爆)

*1:または構造体

*2:私は第一引数に統一しているのでここではそのようにする

*3:srcのサイズはdestと同等とする

*4:ここでは512byte

*5:dkutil_cはhttp://sourceforge.jp/projects/dkingyoutility/files/?release_id=7410#7410等からダウンロードしてください

*6:C言語標準関数郡ということにしてくれ

*7:ちなみにこのソースをデバッグしていた時の日記がhttp://d.hatena.ne.jp/studiokingyo/20050822http://d.hatena.ne.jp/studiokingyo/20050823である

*8:他にも把握しなければならないことは多少はあるが・・・