#include #include #include #include "input-method.h" #include "stream.h" IIIMF_status iiimf_create_stream( IIIMF_stream_proc_read proc_read, IIIMF_stream_proc_write proc_write, IIIMF_stream_private private_data, int timeout, IIIMF_stream ** stream_ret) { IIIMF_stream * stream; stream = (IIIMF_stream *)malloc(sizeof (IIIMF_stream)); if (NULL == stream) { free(stream); return IIIMF_STATUS_MALLOC; } stream->timeout = timeout; stream->private_data = private_data; stream->proc_read = proc_read; stream->proc_write = proc_write; *stream_ret = stream; return IIIMF_STATUS_SUCCESS; } void iiimf_stream_delete( IIIMF_stream * stream) { if (NULL == stream) return; free(stream); return; } IIIMF_status iiimf_stream_send( IIIMF_stream * stream, IIIMP_data_s * data_s, IIIMP_message * message) { IIIMF_status status; uchar_t * ptr; size_t nbyte; if (!stream->proc_write) return IIIMF_STATUS_STREAM; status = IIIMF_STATUS_SUCCESS; ptr = iiimp_message_pack(data_s, message, &nbyte); if (NULL == ptr) { switch (iiimp_data_status(data_s)) { case IIIMP_DATA_MALLOC_ERROR: status = IIIMF_STATUS_MALLOC; break; case IIIMP_DATA_INVALID: status = IIIMF_STATUS_PACKET; break; case IIIMP_DATA_PROTOCOL_VERSION_ERROR: status = IIIMF_STATUS_PROTOCOL_VERSION; break; default: status = IIIMF_STATUS_FAIL; break; } return status; } status = (*stream->proc_write)(stream->private_data, ptr, nbyte); free(ptr); return status; } IIIMF_status iiimf_stream_receive( IIIMF_stream * stream, IIIMP_data_s * data_s, IIIMP_message ** message_ret) { IIIMF_status status; const uchar_t * ptr; uchar_t * p; size_t nbyte; IIIMP_message * message; uchar_t header[8]; int header_len; int length; int opcode; uchar_t * buf; if (!stream->proc_read) return IIIMF_STATUS_STREAM; status = (*stream->proc_read)(stream->private_data, header, 8); if (IIIMF_STATUS_SUCCESS != status) return status; opcode = header[0]; if (0x80 & opcode) { if ((0xe0 & header[4]) || (0x00 == header[4])) { return IIIMF_STATUS_PACKET; } length = (((header[4] << 24) + (header[5] << 16) + (header[6] << 8) + (header[7] << 0)) << 2); header_len = 8; } else { length = (((header[1] << 16) + (header[2] << 8) + (header[3] << 0)) << 2); header_len = 4; } if (length < 4) return IIIMF_STATUS_PACKET; if (4 == length) { buf = (header + 4); } else { buf = (uchar_t *)malloc(length); if (NULL == buf) return IIIMF_STATUS_MALLOC; p = buf; if (8 != header_len) { (void)memcpy(buf, header + 4, 4); p += 4; } status = (*stream->proc_read)(stream->private_data, p, length - (8 - header_len)); if (IIIMF_STATUS_SUCCESS != status) { free(buf); return status; } } ptr = buf; nbyte = length; message = iiimp_message_unpack(data_s, header[0], &nbyte, &ptr); if ((header + 4) != buf) { free(buf); } if (NULL == message) return IIIMF_STATUS_FAIL; *message_ret = message; return status; } /* Local Variables: */ /* c-file-style: "iiim-project" */ /* End: */