Back to index

im-sdk  12.3.91
stream.c
Go to the documentation of this file.
00001 #include <stdlib.h>
00002 #include <string.h>
00003 
00004 #include <iiimp.h>
00005 
00006 #include "input-method.h"
00007 #include "stream.h"
00008 
00009 IIIMF_status
00010 iiimf_create_stream(
00011     IIIMF_stream_proc_read  proc_read,
00012     IIIMF_stream_proc_write proc_write,
00013     IIIMF_stream_private    private_data,
00014     int                     timeout,
00015     IIIMF_stream **         stream_ret)
00016 {
00017     IIIMF_stream *          stream;
00018 
00019     stream = (IIIMF_stream *)malloc(sizeof (IIIMF_stream));
00020     if (NULL == stream) {
00021        free(stream);
00022        return IIIMF_STATUS_MALLOC;
00023     }
00024     stream->timeout = timeout;
00025     stream->private_data = private_data;
00026     stream->proc_read = proc_read;
00027     stream->proc_write = proc_write;
00028 
00029     *stream_ret = stream;
00030 
00031     return IIIMF_STATUS_SUCCESS;
00032 }
00033 
00034 void
00035 iiimf_stream_delete(
00036     IIIMF_stream *   stream)
00037 {
00038     if (NULL == stream) return;
00039     free(stream);
00040 
00041     return;
00042 }
00043 
00044 IIIMF_status
00045 iiimf_stream_send(
00046     IIIMF_stream *   stream,
00047     IIIMP_data_s *   data_s,
00048     IIIMP_message *  message)
00049 {
00050     IIIMF_status     status;
00051     uchar_t *        ptr;
00052     size_t           nbyte;
00053 
00054     if (!stream->proc_write) return IIIMF_STATUS_STREAM;
00055 
00056     status = IIIMF_STATUS_SUCCESS;
00057 
00058     ptr = iiimp_message_pack(data_s, message, &nbyte);
00059     if (NULL == ptr) {
00060        switch (iiimp_data_status(data_s)) {
00061        case IIIMP_DATA_MALLOC_ERROR:
00062            status = IIIMF_STATUS_MALLOC;
00063            break;
00064        case IIIMP_DATA_INVALID:
00065            status = IIIMF_STATUS_PACKET;
00066            break;
00067        case IIIMP_DATA_PROTOCOL_VERSION_ERROR:
00068            status = IIIMF_STATUS_PROTOCOL_VERSION;
00069            break;
00070        default:
00071            status = IIIMF_STATUS_FAIL;
00072            break;
00073        }
00074        return status;
00075     }
00076 
00077     status = (*stream->proc_write)(stream->private_data, ptr, nbyte);
00078 
00079     free(ptr);
00080 
00081     return status;
00082 }
00083 
00084 
00085 IIIMF_status
00086 iiimf_stream_receive(
00087     IIIMF_stream *   stream,
00088     IIIMP_data_s *   data_s,
00089     IIIMP_message ** message_ret)
00090 {
00091     IIIMF_status     status;
00092     const uchar_t *  ptr;
00093     uchar_t *        p;
00094     size_t           nbyte;
00095     IIIMP_message *  message;
00096     uchar_t          header[8];
00097     int                     header_len;
00098     int                     length;
00099     int                     opcode;
00100     uchar_t *        buf;
00101 
00102     if (!stream->proc_read) return IIIMF_STATUS_STREAM;
00103     status = (*stream->proc_read)(stream->private_data, header, 8);
00104     if (IIIMF_STATUS_SUCCESS != status) return status;
00105 
00106     opcode = header[0];
00107     if (0x80 & opcode) {
00108        if ((0xe0 & header[4]) || (0x00 == header[4])) {
00109            return IIIMF_STATUS_PACKET;
00110        }
00111        length = (((header[4] << 24) +
00112                  (header[5] << 16) +
00113                  (header[6] << 8) +
00114                  (header[7] << 0)) << 2);
00115        header_len = 8;
00116     } else {
00117        length = (((header[1] << 16) +
00118                  (header[2] << 8) +
00119                  (header[3] << 0)) << 2);
00120        header_len = 4;
00121     }
00122     if (length < 4) return IIIMF_STATUS_PACKET;
00123 
00124     if (4 == length) {
00125        buf = (header + 4);
00126     } else {
00127        buf = (uchar_t *)malloc(length);
00128        if (NULL == buf) return IIIMF_STATUS_MALLOC;
00129        p = buf;
00130 
00131        if (8 != header_len) {
00132            (void)memcpy(buf, header + 4, 4);
00133            p += 4;
00134        }
00135 
00136        status = (*stream->proc_read)(stream->private_data, p,
00137                                   length - (8 - header_len));
00138        if (IIIMF_STATUS_SUCCESS != status) {
00139            free(buf);
00140            return status;
00141        }
00142     }
00143 
00144     ptr = buf;
00145     nbyte = length;
00146     message = iiimp_message_unpack(data_s, header[0], &nbyte, &ptr);
00147     if ((header + 4) != buf) {
00148        free(buf);
00149     }
00150     if (NULL == message) return IIIMF_STATUS_FAIL;
00151 
00152     *message_ret = message;
00153 
00154     return status;
00155 }
00156 
00157 
00158 /* Local Variables: */
00159 /* c-file-style: "iiim-project" */
00160 /* End: */