myio_apr.c
最終更新:2009/11/14
001: /* 002: * ストリームの抽象化の試み 003: * ・apr_file_t へのラッパー 004: * ・apr_socket_t へのラッパー 005: */ 006: 007: #include "myio_apr.h" 008: 009: /* 010: * apr_file_t へのラッパーメソッド定義 011: */ 012: 013: #define MYIO_METHOD_NAME_FILE "APR_FILE_STREAM" 014: 015: typedef struct myio_fp_ctx { 016: apr_file_t *fp; 017: apr_pool_t *pool; 018: } myio_fp_ctx; 019: 020: /* 021: * size バイト分のデータを読み出す関数。 022: * 返り値は buf に読み出したバイト数。 023: * エラー時には -1 が返る。 024: */ 025: 026: int myio_read_fp( 027: MYIO *in 028: , char *buf 029: , int size 030: ) { 031: apr_status_t rv = APR_SUCCESS; 032: apr_size_t nbytes = size; 033: myio_fp_ctx *ctx = (myio_fp_ctx*)(in->ptr); 034: if (!ctx || ! ctx->fp) { 035: return -1; 036: } 037: rv = apr_file_read(ctx->fp, buf, &nbytes); 038: if (rv != APR_SUCCESS) { 039: return -1; 040: } 041: return nbytes; 042: } 043: 044: /* 045: * buf に格納された size バイト分のデータを書き込む関数。 046: * 返り値は書き出したバイト数。 047: * エラー時には -1 が返る。 048: */ 049: 050: int myio_write_fp ( 051: MYIO *out 052: , const char *buf 053: , int size 054: ) { 055: apr_status_t rv = APR_SUCCESS; 056: apr_size_t nbytes = size; 057: myio_fp_ctx *ctx = (myio_fp_ctx*)(out->ptr); 058: if (!ctx || ! ctx->fp) { 059: return -1; 060: } 061: rv = apr_file_write(ctx->fp, buf, &nbytes); 062: if (rv != APR_SUCCESS) { 063: return -1; 064: } 065: return nbytes; 066: } 067: 068: /* 069: * 文字列 str (ヌル文字で終端されたデータ)を書き込む関数。 070: * 返り値は書き出した文字列の長さ。 071: * エラー時には -1 が返る。 072: */ 073: 074: int myio_puts_fp ( 075: MYIO *out 076: , const char *str 077: ) { 078: apr_status_t rv = APR_SUCCESS; 079: myio_fp_ctx *ctx = (myio_fp_ctx*)(out->ptr); 080: if(0)printf("myio_puts_fp\n"); 081: if (!ctx || ! ctx->fp) { 082: return -1; 083: } 084: rv = apr_file_puts(str, ctx->fp); 085: if (rv != APR_SUCCESS) { 086: return -1; 087: } 088: return strlen(str); 089: } 090: 091: /* 092: * size-1 バイトまでの文字列をストリームから読み出し、buf に保存する。 093: * EOF または LF を読み込んだところで停止する。 094: * LF または CRLF は '\0' に書き換えられる。 095: * 返り値は最後のヌル文字を含まない読み出した文字列の長さ。 096: * エラー時には -1 が返る。 097: */ 098: int myio_gets_fp ( 099: MYIO *in 100: , char *buf 101: , int size 102: ) { 103: apr_status_t rv = APR_SUCCESS; 104: int len = 0; 105: myio_fp_ctx *ctx = (myio_fp_ctx*)(in->ptr); 106: if(0)printf("myio_gets_fp\n"); 107: if (!ctx || ! ctx->fp) { 108: return -1; 109: } 110: rv = apr_file_gets(buf, size, ctx->fp); 111: if (rv != APR_SUCCESS) { 112: return -1; 113: } 114: { 115: int i=0; 116: len = strlen(buf); 117: for (i=len-1; i>=0; i--) { 118: if (buf[i] == MYIO_CHAR_LF || buf[i] == MYIO_CHAR_CR) { 119: buf[i] = '\0'; 120: } else { 121: break; 122: } 123: } 124: } 125: return strlen(buf); 126: } 127: 128: MYIO_METHOD myio_method_fp = { 129: MYIO_METHOD_NAME_FILE 130: , myio_write_fp 131: , myio_read_fp 132: , myio_puts_fp 133: , myio_gets_fp 134: }; 135: 136: apr_file_t *MYIO_fp_get_fp ( 137: MYIO *myio 138: ) { 139: if (myio) { 140: if (myio->method) { 141: if (!strcmp(myio->method->name, MYIO_METHOD_NAME_FILE)) { 142: myio_fp_ctx *ctx = (myio_fp_ctx *)(myio->ptr); 143: return ctx->fp; 144: } 145: } 146: } 147: return NULL; 148: } 149: 150: MYIO *MYIO_fp_new ( 151: apr_file_t *fp 152: , int flag /* フラグ。0:入力ストリーム、1:出力ストリーム*/ 153: , apr_pool_t *pool 154: ) { 155: myio_fp_ctx *ctx = NULL; 156: MYIO *myio = NULL; 157: if (!fp || !pool) { 158: return NULL; 159: } 160: ctx = (myio_fp_ctx*)apr_palloc(pool, sizeof(myio_fp_ctx)); 161: if (!ctx) { 162: return NULL; 163: } 164: ctx->fp = fp; 165: ctx->pool = pool; 166: myio = (MYIO*)apr_palloc(pool, sizeof(MYIO)); 167: if (!myio) { 168: return NULL; 169: } 170: 171: return MYIO_make(myio, &myio_method_fp, (flag)?0:1, (flag)?1:0, ctx); 172: } 173: 174: MYIO *MYIO_fp_open ( 175: const char * fname 176: , apr_int32_t flag 177: , apr_fileperms_t perm 178: , apr_pool_t *pool 179: ) { 180: apr_status_t rv = APR_SUCCESS; 181: apr_file_t *fp = NULL; 182: if (!fname || !pool) { 183: return NULL; 184: } 185: rv = apr_file_open(&fp, fname, flag, perm, pool); 186: if (rv != APR_SUCCESS) { 187: return NULL; 188: } 189: 190: return MYIO_fp_new(fp, (flag & APR_FOPEN_READ)?0:1, pool); 191: } 192: 193: void MYIO_fp_close ( 194: MYIO *myio 195: ) { 196: if (myio) { 197: if (myio->method) { 198: if (!strcmp(myio->method->name, MYIO_METHOD_NAME_FILE)) { 199: myio_fp_ctx *ctx = (myio_fp_ctx *)(myio->ptr); 200: if (ctx) { 201: if (ctx->fp) { 202: apr_file_close(ctx->fp); 203: ctx->fp = NULL; 204: } 205: } 206: myio->ptr = NULL; 207: } 208: } 209: } 210: } 211: 212: /* 213: * apr_socket_t へのラッパーメソッド定義 214: */ 215: 216: #define MYIO_METHOD_NAME_SOCKET "APR_SOCKET_STREAM" 217: 218: typedef struct myio_sock_ctx_st { 219: apr_socket_t *sock; 220: apr_pool_t *pool; 221: } myio_sock_ctx; 222: 223: /* 224: * size バイト分のデータを読み出す関数。 225: * 返り値は buf に読み出したバイト数。 226: * エラー時には -1 が返る。 227: */ 228: 229: int myio_read_sock ( 230: MYIO *in 231: , char *buf 232: , int size 233: ) { 234: apr_status_t rv = APR_SUCCESS; 235: apr_size_t nbytes = size; 236: myio_sock_ctx *ctx = (myio_sock_ctx*)(in->ptr); 237: if (!ctx || ! ctx->sock) { 238: return -1; 239: } 240: rv = apr_socket_recv(ctx->sock, buf, &nbytes); 241: if (rv != APR_SUCCESS) { 242: return -1; 243: } 244: return nbytes; 245: } 246: 247: /* 248: * buf に格納された size バイト分のデータを書き込む関数。 249: * 返り値は書き出したバイト数。 250: * エラー時には -1 が返る。 251: */ 252: 253: int myio_write_sock ( 254: MYIO *out 255: , const char *buf 256: , int size 257: ) { 258: apr_status_t rv = APR_SUCCESS; 259: apr_size_t nbytes = size; 260: myio_sock_ctx *ctx = (myio_sock_ctx*)(out->ptr); 261: if (!ctx || ! ctx->sock) { 262: return -1; 263: } 264: rv = apr_socket_send(ctx->sock, buf, &nbytes); 265: if (rv != APR_SUCCESS) { 266: return -1; 267: } 268: return nbytes; 269: } 270: 271: /* 272: * 文字列 str (ヌル文字で終端されたデータ)を書き込む関数。 273: * 返り値は書き出した文字列の長さ。 274: * エラー時には -1 が返る。 275: */ 276: 277: int myio_puts_sock ( 278: MYIO *out 279: , const char *str 280: ) { 281: apr_status_t rv = APR_SUCCESS; 282: myio_sock_ctx *ctx = (myio_sock_ctx*)(out->ptr); 283: int size = 0; 284: 285: if (!ctx || ! ctx->sock) { 286: return -1; 287: } 288: 289: size = strlen(str); 290: 291: { 292: int o=0; 293: while (o<size) { 294: apr_size_t len = size-o; 295: rv = apr_socket_send(ctx->sock, str+o, &len); 296: if (rv != APR_SUCCESS) { 297: return -1; 298: } 299: o += len; 300: } 301: } 302: return size; 303: } 304: 305: MYIO_METHOD myio_method_sock = { 306: MYIO_METHOD_NAME_SOCKET 307: , myio_write_sock 308: , myio_read_sock 309: , myio_puts_sock 310: , NULL /* 実装なし*/ 311: }; 312: 313: apr_socket_t *MYIO_sock_get_sock ( 314: MYIO *myio 315: ) { 316: if (myio) { 317: if (myio->method) { 318: if (!strcmp(myio->method->name, MYIO_METHOD_NAME_SOCKET)) { 319: myio_sock_ctx *ctx = (myio_sock_ctx *)(myio->ptr); 320: return ctx->sock; 321: } 322: } 323: } 324: return NULL; 325: } 326: 327: MYIO *MYIO_sock_new ( 328: apr_socket_t *sock 329: , apr_pool_t *pool 330: ) { 331: myio_sock_ctx *ctx = NULL; 332: MYIO *myio = NULL; 333: if (!sock || !pool) { 334: return NULL; 335: } 336: ctx = (myio_sock_ctx*)apr_palloc(pool, sizeof(myio_sock_ctx)); 337: if (!ctx) { 338: return NULL; 339: } 340: ctx->sock = sock; 341: ctx->pool = pool; 342: myio = (MYIO*)apr_palloc(pool, sizeof(MYIO)); 343: if (!myio) { 344: return NULL; 345: } 346: 347: return MYIO_make(myio, &myio_method_sock, 1, 1, ctx); /* 双方向 */ 348: } 349: /* 350: * 簡易ソケット接続関数 351: */ 352: apr_socket_t *my_connect ( 353: char *hostname 354: , int port 355: , apr_pool_t * pool 356: ) { 357: 358: apr_socket_t *s = NULL; 359: 360: if (! pool || ! hostname || port<=0) { 361: 362: return NULL; 363: 364: } else { 365: 366: apr_status_t rv = APR_SUCCESS; 367: apr_sockaddr_t *sa=NULL; 368: 369: rv = apr_sockaddr_info_get(&sa, hostname, APR_UNSPEC, port, 0, pool); 370: if (APR_SUCCESS != rv) { 371: return NULL; 372: } 373: 374: for (; sa!=NULL; sa=sa->next) 375: { 376: rv = apr_socket_create(&s, sa->family, 377: SOCK_STREAM, APR_PROTO_TCP, pool); 378: if (APR_SUCCESS != rv) { 379: continue; 380: } 381: 382: rv = apr_socket_connect(s, sa); 383: if (APR_SUCCESS == rv) { 384: break; 385: } 386: } 387: 388: if (!sa) { 389: return NULL; 390: } 391: } 392: 393: return s; 394: } 395: 396: /* 397: * ソケット接続し、MYIO オブジェクトを生成する関数 398: * 返り値: 399: * 失敗時:ヌル 400: * メモ: 401: * ソケットオプションはデフォルト設定。 402: */ 403: 404: MYIO *MYIO_sock_connect( 405: char *hostname /* 接続先ホスト名 */ 406: , int port /* 接続先ポート番号 */ 407: , apr_pool_t * pool 408: ) { 409: apr_socket_t *sock = my_connect (hostname, port, pool); 410: if (!sock) { 411: return NULL; 412: } 413: 414: return MYIO_sock_new(sock, pool); 415: } 416: 417: void MYIO_sock_close(MYIO *myio) { 418: if (myio) { 419: if (myio->method) { 420: if (!strcmp(myio->method->name, MYIO_METHOD_NAME_SOCKET)) { 421: myio_sock_ctx *ctx = (myio_sock_ctx *)(myio->ptr); 422: if (ctx) { 423: if (ctx->sock) { 424: apr_socket_close(ctx->sock); 425: ctx->sock = NULL; 426: } 427: myio->ptr = NULL; 428: } 429: } 430: } 431: } 432: } 433: 434: int MYIO_apr_printf(MYIO *myio, const char *fmt, ...) { 435: apr_pool_t *pool = NULL; 436: if (myio) { 437: if (myio->method) { 438: if (!strcmp(myio->method->name, MYIO_METHOD_NAME_SOCKET)) { 439: myio_sock_ctx *ctx = (myio_sock_ctx *)(myio->ptr); 440: if (ctx) { 441: if (ctx->pool) { 442: pool = ctx->pool; 443: } 444: } 445: } else if (!strcmp(myio->method->name, MYIO_METHOD_NAME_FILE)) { 446: myio_fp_ctx *ctx = (myio_fp_ctx *)(myio->ptr); 447: if (ctx) { 448: if (ctx->pool) { 449: pool = ctx->pool; 450: } 451: } 452: } 453: if (pool) { 454: char *buf = NULL; 455: va_list args; 456: va_start(args, fmt); 457: buf = apr_pvsprintf (pool, fmt, args); 458: if (buf) { 459: return myio->method->write(myio, buf, strlen(buf)); 460: } 461: } 462: } 463: } 464: return -1; 465: }
KAKU PROJECT (2009) |