myio_bio.c

最終更新:2009/11/9

myio_bio.c

001: /*
002:  * ストリームの抽象化の試み
003:  * ・BIO へのラッパー
004:  */
005:  
006: #include <stdio.h>
007: #include <string.h>
008: #include "openssl/bio.h"
009: #include "myio_bio.h"
010: 
011: #define MYIO_METHOD_NAME_BIO "_BIO_"
012: 
013: typedef struct myio_bio_ctx_st {
014:   BIO *bio;
015: } myio_bio_ctx;
016: 
017: /*
018:  * size バイト分のデータを読み出す関数。
019:  * 返り値は buf に読み出したバイト数。
020:  * エラー時には -1 が返る。
021:  */
022: 
023: int myio_read_bio (
024:   MYIO *in
025:   , char *buf
026:   , int size
027: ) {
028:   myio_bio_ctx *ctx = (myio_bio_ctx*)(in->ptr);
029:   if (! ctx->bio) {
030:     return -1;
031:   }
032:   return BIO_read(ctx->bio, buf, size);
033: }
034: 
035: /*
036:  * buf に格納された size バイト分のデータを書き込む関数。
037:  * 返り値は書き出したバイト数。
038:  * エラー時には -1 が返る。
039:  */
040: 
041: int myio_write_bio (
042:   MYIO *out
043:   , const char *buf
044:   , int size
045: ) {
046:   myio_bio_ctx *ctx = (myio_bio_ctx*)(out->ptr);
047:   if (!ctx || ! ctx->bio) {
048:     return -1;
049:   }
050:   return BIO_write(ctx->bio, buf, size);
051: }
052: 
053: /* BIO ストリームで必ず puts/gets メソッドが実装されているとは限らない */
054: #if 0
055: /*
056:  * 文字列 str (ヌル文字で終端されたデータ)を書き込む関数。
057:  * 返り値は書き出した文字列の長さ。
058:  * エラー時には -1 が返る。
059:  */
060: 
061: int myio_puts_bio (
062:   MYIO *out
063:   , const char *str
064: ) {
065:   myio_bio_ctx *ctx = (myio_bio_ctx*)(out->ptr);
066:   if (!ctx || ! ctx->bio) {
067:     return -1;
068:   }
069:   return BIO_puts(ctx->bio, str);
070: }
071: 
072: /*
073:  * size-1 バイトまでの文字列をストリームから読み出し、buf に保存する。
074:  * EOF または LF を読み込んだところで停止する。
075:  * LF または CRLF は '\0' に書き換えられる。
076:  * 返り値は最後のヌル文字を含まない読み出した文字列の長さ。
077:  * エラー時には -1 が返る。
078:  */
079: int myio_gets_bio (
080:   MYIO *in
081:   , char *buf
082:   , int size
083: ) {
084:   myio_bio_ctx *ctx = (myio_bio_ctx*)(in->ptr);
085:   if (! ctx->bio) {
086:     return -1;
087:   }
088:   if (BIO_gets(ctx->bio, buf, size) < 0) {
089:     return -1;
090:   }
091:   {
092:     int i=0;
093:     int len = strlen(buf);
094:     for (i=len-1; i>=0; i--) {
095:       if (buf[i] == MYIO_CHAR_LF || buf[i] == MYIO_CHAR_CR) {
096:         buf[i] = '\0';
097:       } else {
098:         break;
099:       }
100:     }
101:   }
102:   return strlen(buf);
103: 
104: }
105: #endif
106: 
107: MYIO_METHOD myio_method_bio = {
108:   MYIO_METHOD_NAME_BIO
109:   , myio_write_bio
110:   , myio_read_bio
111:   , NULL
112:   , NULL
113: };
114: 
115: MYIO* MYIO_bio_new(
116:   BIO *bio
117:   , int flag_in
118:   , int flag_out
119: ) {
120:   MYIO *myio = NULL;
121:   myio_bio_ctx *ctx = NULL;
122:   
123:   if (!bio) {
124:     return NULL;
125:   }
126:   ctx = (myio_bio_ctx*)malloc(sizeof(myio_bio_ctx));
127:   ctx->bio = bio;
128:   myio = (MYIO*)malloc(sizeof(MYIO));
129:   return MYIO_make(myio, &myio_method_bio, (flag_in)?1:0, (flag_out)?1:0, ctx);
130: }
131: 
132: BIO *MYIO_bio_get_BIO(
133:   MYIO *myio
134: ) {
135:   if (myio) {
136:     if (myio->method) {
137:       if (!strcmp(myio->method->name, MYIO_METHOD_NAME_BIO)) {
138:         myio_bio_ctx *ctx = (myio_bio_ctx *)(myio->ptr);
139:         return ctx->bio;
140:       }
141:     }
142:   }
143:   return NULL;
144: }
145: 
146: /*
147:  * MYIO 構造体・BIO 用コンテクストデータの解放
148:  * BIO 構造体の解放は行わない。
149:  */
150: 
151: void MYIO_bio_close(
152:   MYIO *myio
153: ) {
154:   if (myio) {
155:     if (myio->method) {
156:       if (!strcmp(myio->method->name, MYIO_METHOD_NAME_BIO)) {
157:         myio_bio_ctx *ctx = (myio_bio_ctx *)(myio->ptr);
158:         if (ctx) {
159:           if (ctx->bio) {
160:             /* BIO_free(ctx->bio); */
161:             ctx->bio = NULL;
162:           }
163:           free(ctx);
164:           myio->ptr = NULL;
165:         }
166:         free(myio);
167:       }
168:     }
169:   }
170: }
Copyright (C) KAKU PROJECT (2009)KAKU PROJECT (2009)