/* * ストリームの抽象化の試み * ・BIO へのラッパー */ #include #include #include "openssl/bio.h" #include "myio_bio.h" #define MYIO_METHOD_NAME_BIO "_BIO_" typedef struct myio_bio_ctx_st { BIO *bio; } myio_bio_ctx; /* * size バイト分のデータを読み出す関数。 * 返り値は buf に読み出したバイト数。 * エラー時には -1 が返る。 */ int myio_read_bio ( MYIO *in , char *buf , int size ) { myio_bio_ctx *ctx = (myio_bio_ctx*)(in->ptr); if (! ctx->bio) { return -1; } return BIO_read(ctx->bio, buf, size); } /* * buf に格納された size バイト分のデータを書き込む関数。 * 返り値は書き出したバイト数。 * エラー時には -1 が返る。 */ int myio_write_bio ( MYIO *out , const char *buf , int size ) { myio_bio_ctx *ctx = (myio_bio_ctx*)(out->ptr); if (!ctx || ! ctx->bio) { return -1; } return BIO_write(ctx->bio, buf, size); } /* BIO ストリームで必ず puts/gets メソッドが実装されているとは限らない */ #if 0 /* * 文字列 str (ヌル文字で終端されたデータ)を書き込む関数。 * 返り値は書き出した文字列の長さ。 * エラー時には -1 が返る。 */ int myio_puts_bio ( MYIO *out , const char *str ) { myio_bio_ctx *ctx = (myio_bio_ctx*)(out->ptr); if (!ctx || ! ctx->bio) { return -1; } return BIO_puts(ctx->bio, str); } /* * size-1 バイトまでの文字列をストリームから読み出し、buf に保存する。 * EOF または LF を読み込んだところで停止する。 * LF または CRLF は '\0' に書き換えられる。 * 返り値は最後のヌル文字を含まない読み出した文字列の長さ。 * エラー時には -1 が返る。 */ int myio_gets_bio ( MYIO *in , char *buf , int size ) { myio_bio_ctx *ctx = (myio_bio_ctx*)(in->ptr); if (! ctx->bio) { return -1; } if (BIO_gets(ctx->bio, buf, size) < 0) { return -1; } { int i=0; int len = strlen(buf); for (i=len-1; i>=0; i--) { if (buf[i] == MYIO_CHAR_LF || buf[i] == MYIO_CHAR_CR) { buf[i] = '\0'; } else { break; } } } return strlen(buf); } #endif MYIO_METHOD myio_method_bio = { MYIO_METHOD_NAME_BIO , myio_write_bio , myio_read_bio , NULL , NULL }; MYIO* MYIO_bio_new( BIO *bio , int flag_in , int flag_out ) { MYIO *myio = NULL; myio_bio_ctx *ctx = NULL; if (!bio) { return NULL; } ctx = (myio_bio_ctx*)malloc(sizeof(myio_bio_ctx)); ctx->bio = bio; myio = (MYIO*)malloc(sizeof(MYIO)); return MYIO_make(myio, &myio_method_bio, (flag_in)?1:0, (flag_out)?1:0, ctx); } BIO *MYIO_bio_get_BIO( MYIO *myio ) { if (myio) { if (myio->method) { if (!strcmp(myio->method->name, MYIO_METHOD_NAME_BIO)) { myio_bio_ctx *ctx = (myio_bio_ctx *)(myio->ptr); return ctx->bio; } } } return NULL; } /* * MYIO 構造体・BIO 用コンテクストデータの解放 * BIO 構造体の解放は行わない。 */ void MYIO_bio_close( MYIO *myio ) { if (myio) { if (myio->method) { if (!strcmp(myio->method->name, MYIO_METHOD_NAME_BIO)) { myio_bio_ctx *ctx = (myio_bio_ctx *)(myio->ptr); if (ctx) { if (ctx->bio) { /* BIO_free(ctx->bio); */ ctx->bio = NULL; } free(ctx); myio->ptr = NULL; } free(myio); } } } }