msg.c File Reference

a simple message serialization library More...

#include <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <inttypes.h>
#include <arpa/inet.h>
#include "debug.h"
#include "util.h"
#include "msg.h"
#include "obj.h"
#include "list.h"
#include "tree.h"

Functions

size_t co_request_alloc (char *output, const size_t olen, const co_obj_t *method, co_obj_t *param)
 allocate request More...
 
size_t co_response_alloc (char *output, const size_t olen, const uint32_t id, const co_obj_t *error, co_obj_t *result)
 allocate response More...
 

Detailed Description

a simple message serialization library

Author
Josh King (jheretic), jking.nosp@m.@cha.nosp@m.mbana.nosp@m..net

Function Documentation

size_t co_request_alloc ( char *  output,
const size_t  olen,
const co_obj_t method,
co_obj_t param 
)

allocate request

Parameters
outputbuffer for output
olenoutput buffer length
methodname of method
paramparameters to method

References co_list_raw().

Referenced by co_call().

65 {
66 
67  CHECK(((output != NULL) && (method != NULL)), "Invalid request components.");
68  CHECK(olen > sizeof(_req_header) + sizeof(uint32_t) + sizeof(co_str16_t) + sizeof(co_list16_t), "Output buffer too small.");
69  size_t written = 0;
70  char *cursor = NULL;
71  size_t s = 0;
72 
73  /* Pack request header */
74  memmove(output + written, &_req_header.list_type, sizeof(_req_header.list_type));
75  written += sizeof(_req_header.list_type);
76 
77  memmove(output + written, &_req_header.list_len, sizeof(_req_header.list_len));
78  written += sizeof(_req_header.list_len);
79 
80  memmove(output + written, &_req_header.type_type, sizeof(_req_header.type_type));
81  written += sizeof(_req_header.type_type);
82 
83  memmove(output + written, &_req_header.type_value, sizeof(_req_header.type_value));
84  written += sizeof(_req_header.type_value);
85 
86  memmove(output + written, &_req_header.id_type, sizeof(_req_header.id_type));
87  written += sizeof(_req_header.id_type);
88 
89  /* Pack request ID */
90  memmove(output + written, &_id, sizeof(uint32_t));
91  written += sizeof(uint32_t);
92  _id++;
93 
94  /* Pack method call */
95  CHECK(IS_STR(method), "Not a valid method name.");
96  char *buffer = NULL;
97  size_t buffer_write = co_obj_raw(&buffer, method);
98  CHECK(buffer_write >= 0, "Failed to pack object.");
99  memmove(output + written, buffer, buffer_write);
100  written += buffer_write;
101 
102  /* Pack parameters */
103  CHECK(written < olen, "Output buffer too small.");
104  if(param != NULL)
105  {
106  if(IS_LIST(param))
107  written += co_list_raw(output + written, olen - written, param);
108  else
109  {
110  s = co_obj_raw(&cursor, param);
111  written += s;
112  memmove(output + written, cursor, s);
113  }
114  }
115  CHECK(written >= 0, "Failed to pack object.");
116  DEBUG("Request bytes written: %d", (int)written);
117  CHECK(written < olen, "Output buffer too small.");
118 
119  return written;
120 error:
121  return -1;
122 
123 }
size_t co_list_raw(char *output, const size_t olen, const co_obj_t *list)
dump raw representation of list
Definition: list.c:503
size_t co_response_alloc ( char *  output,
const size_t  olen,
const uint32_t  id,
const co_obj_t error,
co_obj_t result 
)

allocate response

Parameters
outputbuffer for output
olenoutput buffer length
idresponse ID
errorerror object
resultresult of request

References co_list_raw(), and co_tree_raw().

Referenced by dispatcher_cb().

142 {
143  CHECK(((output != NULL) && (error != NULL) && (result != NULL)), "Invalid response components.");
144  CHECK(olen > sizeof(_resp_header) + sizeof(uint32_t) + sizeof(co_str16_t) + sizeof(co_list16_t), "Output buffer too small.");
145  size_t written = 0;
146  char *cursor = NULL;
147  size_t s = 0;
148 
149  /* Pack response header */
150  memmove(output + written, &_resp_header.list_type, sizeof(_resp_header.list_type));
151  written += sizeof(_resp_header.list_type);
152 
153  memmove(output + written, &_resp_header.list_len, sizeof(_resp_header.list_len));
154  written += sizeof(_resp_header.list_len);
155 
156  memmove(output + written, &_resp_header.type_type, sizeof(_resp_header.type_type));
157  written += sizeof(_resp_header.type_type);
158 
159  memmove(output + written, &_resp_header.type_value, sizeof(_resp_header.type_value));
160  written += sizeof(_resp_header.type_value);
161 
162  memmove(output + written, &_resp_header.id_type, sizeof(_resp_header.id_type));
163  written += sizeof(_resp_header.id_type);
164 
165  /* Pack response ID */
166  memmove(output + written, &id, sizeof(uint32_t));
167  written += sizeof(uint32_t);
168 
169  /* Pack error code */
170  //CHECK(IS_STR(error) || IS_NIL(error), "Not a valid error name.");
171  if(error != NULL)
172  {
173  if(IS_LIST(error))
174  written += co_list_raw(output + written, olen - written, error);
175  else if(IS_TREE(error))
176  {
177  written += co_tree_raw(output + written, olen - written, error);
178  }
179  else
180  {
181  s = co_obj_raw(&cursor, error);
182  memmove(output + written, cursor, s);
183  written += s;
184  }
185  }
186 
187  /* Pack method result */
188  CHECK(written < olen, "Output buffer too small.");
189  if(result != NULL)
190  {
191  if(IS_LIST(result))
192  written += co_list_raw(output + written, olen - written, result);
193  else if(IS_TREE(result))
194  {
195  written += co_tree_raw(output + written, olen - written, result);
196  }
197  else
198  {
199  s = co_obj_raw(&cursor, result);
200  memmove(output + written, cursor, s);
201  written += s;
202  }
203  }
204 
205  DEBUG("Response bytes written: %d", (int)written);
206  CHECK(written < olen, "Output buffer too small.");
207 
208  return written;
209 error:
210  return -1;
211 }
size_t co_list_raw(char *output, const size_t olen, const co_obj_t *list)
dump raw representation of list
Definition: list.c:503
size_t co_tree_raw(char *output, const size_t olen, const co_obj_t *tree)
dump raw representation of tree
Definition: tree.c:623