00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifdef HAVE_CONFIG_H
00029 #include "config.h"
00030 #endif
00031 #include "visir_utils.h"
00032
00033 #include <cpl.h>
00034
00035 #include <string.h>
00036 #include <stddef.h>
00037 #include <stdint.h>
00038 #include <arpa/inet.h>
00039
00040 typedef struct {
00041 size_t size;
00042 char * base_buffer;
00043 char * pos;
00044 } visir_stream;
00045
00046 static visir_stream *
00047 visir_stream_new(char * block, size_t size)
00048 {
00049 visir_stream * stream = cpl_malloc(sizeof(visir_stream));
00050 stream->size = size;
00051 stream->base_buffer = block;
00052 stream->pos = stream->base_buffer;
00053 return stream;
00054 }
00055
00056 static size_t
00057 visir_stream_get_size(visir_stream * stream)
00058 {
00059 return stream->pos - stream->base_buffer;
00060 }
00061
00062 static void
00063 visir_stream_ensure_space(visir_stream * stream, size_t extra)
00064 {
00065 const size_t nused = visir_stream_get_size(stream);
00066
00067 if (stream->size < (nused + extra)) {
00068 stream->base_buffer = cpl_realloc(stream->base_buffer,
00069 stream->size * 2);
00070 stream->size *= 2;
00071 stream->pos = stream->base_buffer + nused;
00072 }
00073 }
00074
00075 static void
00076 serialize_uint32(visir_stream * stream, uint32_t v_)
00077 {
00078 uint32_t v = htonl(v_);
00079
00080 visir_stream_ensure_space(stream, sizeof(v));
00081 memcpy(stream->pos, &v, sizeof(v));
00082 stream->pos += sizeof(v);
00083 }
00084
00085 static void
00086 serialize_string(visir_stream * stream, const char * s)
00087 {
00088 size_t n = strlen(s);
00089 serialize_uint32(stream, n);
00090 visir_stream_ensure_space(stream, n);
00091 memcpy(stream->pos, s, n);
00092 stream->pos += n;
00093 }
00094
00095
00096 static uint32_t
00097 deserialize_uint32(visir_stream * stream)
00098 {
00099 uint32_t r;
00100 memcpy(&r, stream->pos, sizeof(r));
00101 stream->pos += sizeof(r);
00102 return ntohl(r);
00103 }
00104
00105 static char *
00106 deserialize_string(visir_stream * stream)
00107 {
00108 uint32_t n = deserialize_uint32(stream);
00109 char * s = cpl_malloc(n + 1);
00110 memcpy(s, stream->pos, n);
00111 s[n] = 0;
00112 stream->pos += n;
00113 return s;
00114 }
00115
00116 char *
00117 visir_frameset_serialize(const cpl_frameset * frames, size_t * size)
00118 {
00119 char * block = NULL;
00120 visir_stream * stream = NULL;
00121
00122 cpl_ensure(size != NULL, CPL_ERROR_NULL_INPUT, NULL);
00123 cpl_ensure(frames != NULL, CPL_ERROR_NULL_INPUT, NULL);
00124
00125 block = cpl_malloc(1000);
00126 stream = visir_stream_new(block, 1000);
00127
00128 serialize_uint32(stream, cpl_frameset_get_size(frames));
00129 FOR_EACH_FRAMESET_C(frm, frames) {
00130 serialize_uint32(stream, cpl_frame_get_type(frm));
00131 serialize_uint32(stream, cpl_frame_get_group(frm));
00132 serialize_uint32(stream, cpl_frame_get_level(frm));
00133 serialize_string(stream, cpl_frame_get_tag(frm));
00134 serialize_string(stream, cpl_frame_get_filename(frm));
00135 }
00136
00137 *size = visir_stream_get_size(stream);
00138 block = stream->base_buffer;
00139 cpl_free(stream);
00140
00141 return block;
00142 }
00143
00144 cpl_frameset *
00145 visir_frameset_deserialize(char * block, size_t * size)
00146 {
00147 visir_stream * stream = visir_stream_new(block, 0);
00148 uint32_t nframes = deserialize_uint32(stream);
00149 cpl_frameset * frames = cpl_frameset_new();
00150
00151 for (uint32_t i = 0; i < nframes; i++) {
00152 uint32_t type = deserialize_uint32(stream);
00153 uint32_t group = deserialize_uint32(stream);
00154 uint32_t level = deserialize_uint32(stream);
00155 char * tag = deserialize_string(stream);
00156 char * filename = deserialize_string(stream);
00157 cpl_frame * frm = cpl_frame_new();
00158 cpl_frame_set_type(frm, type);
00159 cpl_frame_set_group(frm, group);
00160 cpl_frame_set_level(frm, level);
00161 cpl_frame_set_filename(frm, filename);
00162 cpl_frame_set_tag(frm, tag);
00163 cpl_free(filename);
00164 cpl_free(tag);
00165 cpl_frameset_insert(frames, frm);
00166 }
00167
00168 if (size)
00169 *size = visir_stream_get_size(stream);
00170
00171 cpl_free(stream);
00172 return frames;
00173 }
00174
00175
00176 cpl_error_code
00177 visir_send_frameset(FILE * stream, const cpl_frameset * frames)
00178 {
00179 size_t size;
00180 char * block = visir_frameset_serialize(frames, &size);
00181 cpl_error_code err = cpl_error_get_code();
00182
00183 skip_if(fwrite(&err, sizeof(err), 1, stream) != 1);
00184 skip_if(fwrite(&size, sizeof(size), 1, stream) != 1);
00185 skip_if(fwrite(block, size, 1, stream) != 1);
00186
00187 end_skip;
00188
00189 cpl_free(block);
00190 return cpl_error_get_code();
00191 }