aura  0.1
 All Data Structures Functions Variables Modules Pages
serdes.c
1 #include <aura/aura.h>
2 #include <aura/private.h>
3 
4 
13 int aura_fmt_len(struct aura_node *node, const char *fmt)
14 {
15  int len=0;
16  int tmp;
17 
18  if (!fmt)
19  return 0;
20 
21  while (*fmt) {
22  switch (*fmt++) {
23  case URPC_U8:
24  case URPC_S8:
25  len += 1;
26  break;
27  case URPC_U16:
28  case URPC_S16:
29  len += 2;
30  break;
31  case URPC_U32:
32  case URPC_S32:
33  len += 4;
34  break;
35  case URPC_U64:
36  case URPC_S64:
37  case URPC_BUF:
38  len += 8;
39  break;
40  case URPC_BIN:
41  tmp = atoi(fmt);
42  if (tmp == 0)
43  BUG(node, "Internal serilizer bug processing: %s", fmt);
44  len += tmp;
45  while (*fmt && (*fmt++ != '.'));
46  break;
47  default:
48  BUG(node, "Serializer failed at token: %s", fmt);
49  }
50  }
51  return len;
52 }
53 
67 char* aura_fmt_pretty_print(const char* fmt, int *valid, int *num_args)
68 {
69  *valid = 1;
70  *num_args = 0;
71  if (!fmt) {
72  char* str;
73  asprintf(&str, "(null)");
74  return str;
75  }
76  char *str = malloc(strlen(fmt) * 10 + 64);
77  if (!str)
78  aura_panic(NULL);
79  *str = 0x0;
80  char *tmp = str;
81  int shift = 0;
82  int len;
83  int pos = 0;
84  while (*fmt) {
85  pos+=shift;
86  tmp = &tmp[shift];
87  switch (*fmt++) {
88  case URPC_U8:
89  shift = sprintf(tmp, " uint8_t");
90  break;
91  case URPC_U16:
92  shift = sprintf(tmp, " uint16_t");
93  break;
94  case URPC_U32:
95  shift = sprintf(tmp, " uint32_t");
96  break;
97  case URPC_U64:
98  shift = sprintf(tmp, " uint64_t");
99  break;
100 
101  case URPC_S8:
102  shift = sprintf(tmp, " int8_t");
103  break;
104  case URPC_S16:
105  shift = sprintf(tmp, " int16_t");
106  break;
107  case URPC_S32:
108  shift = sprintf(tmp, " int32_t");
109  break;
110  case URPC_S64:
111  shift = sprintf(tmp, " int64_t");
112  break;
113  case URPC_BUF:
114  shift = sprintf(tmp, " buf");
115  break;
116  case URPC_BIN:
117  len = atoi(fmt);
118  if (len == 0)
119  BUG(NULL, "Internal serilizer bug processing: %s", fmt);
120  shift = sprintf(tmp, " bin(%d)", len);
121  while (*fmt && (*fmt++ != '.'));
122  break;
123  case 0x0:
124  shift = sprintf(tmp, " (null)");
125  break;
126  default:
127  *valid = 0;
128  shift = sprintf(tmp, " ?[%c]?", *fmt);
129  fmt++;
130  }
131  ++(*num_args);
132  }
133  return str;
134 }
135 
136 
137 
138 //FixMe: This is likely to get messy due to integer promotion
139 // on different platforms
140 
141 #define AURA_SERDES_PARANOID
142 
143 #ifdef AURA_SERDES_PARANOID
144 #define CHECK_BOUNDS(buf,src) if (buf->pos + sizeof(src) > buf->size) \
145  BUG(NULL, "SERDES: Out of buffer bounds");
146 #else
147 #define CHECK_BOUNDS()
148 #endif
149 
150 
151 #define CHECK_AND_PUT(buf, src) \
152  CHECK_BOUNDS(buf,src); \
153  memcpy(&buf->data[buf->pos], &src, sizeof(src)); \
154  buf->pos+=sizeof(src); \
155 
156 
157 #define va_put_U8(buf, ap, swap) \
158  { \
159  uint8_t v = (uint8_t) va_arg(ap, unsigned int); \
160  CHECK_AND_PUT(buf, v); \
161  }
162 
163 #define va_put_S8(buf, ap, swap) \
164  { \
165  int8_t v = (int8_t) va_arg(ap, int); \
166  CHECK_AND_PUT(buf, v); \
167  } \
168 
169 #define va_put_U16(buf, ap, swap) \
170  { \
171  uint16_t v = (uint16_t) va_arg(ap, unsigned int); \
172  if (swap) \
173  v = __swap16(v); \
174  CHECK_AND_PUT(buf, v); \
175  }
176 
177 #define va_put_S16(buf, ap, swap) \
178  { \
179  int16_t v = (int16_t) va_arg(ap, int); \
180  if (swap) \
181  v = __swap16(v); \
182  CHECK_AND_PUT(buf, v); \
183  }
184 
185 /* FixMe: Portability, we assume no promotion here for now */
186 #define va_put_U32(buf, ap, swap) \
187  { \
188  uint32_t v = (uint32_t) va_arg(ap, uint32_t); \
189  if (swap) \
190  v = __swap32(v); \
191  CHECK_AND_PUT(buf, v); \
192  }
193 
194 #define va_put_S32(buf, ap, swap) \
195  { \
196  int32_t v = (int32_t) va_arg(ap, int32_t); \
197  if (swap) \
198  v = __swap32(v); \
199  CHECK_AND_PUT(buf, v); \
200  }
201 
202 #define va_put_U64(buf, ap, swap) \
203  { \
204  uint64_t v = (uint64_t) va_arg(ap, uint64_t); \
205  if (swap) \
206  v = __swap64(v); \
207  CHECK_AND_PUT(buf, v); \
208  }
209 
210 #define va_put_S64(buf, ap, swap) \
211  { \
212  int64_t v = (int64_t) va_arg(ap, uint64_t); \
213  if (swap) \
214  v = __swap64(v); \
215  CHECK_AND_PUT(buf, v); \
216  } \
217 
218 #define va_put_BIN(buf, len, ap) \
219  { \
220  void *ptr = va_arg(ap, void *); \
221  memcpy(&buf->data[buf->pos], ptr, len); \
222  buf->pos+=len; \
223  }
224 
225 #define va_put_BUF(buf, ap, swap) \
226  { \
227  struct aura_buffer *out = va_arg(ap, void *); \
228  struct aura_node *_node = buf->owner; \
229  if (!_node->tr->buffer_put) \
230  BUG(_node, "This node doesn't support aura_buffer as argument"); \
231  _node->tr->buffer_put(buf, out); \
232  }
233 
234 
244 struct aura_buffer *aura_serialize(struct aura_node *node, const char *fmt, int size, va_list ap)
245 {
246  struct aura_buffer *buf = aura_buffer_request(node, size);
247  if (!buf)
248  return NULL;
249 
250 #define PUT(n) \
251  case URPC_ ## n: \
252  va_put_ ## n(buf, ap, node->need_endian_swap); \
253  break; \
254 
255  while (*fmt) {
256  switch (*fmt++) {
257  PUT(U8);
258  PUT(S8);
259  PUT(U16);
260  PUT(S16);
261  PUT(U32);
262  PUT(S32);
263  PUT(U64);
264  PUT(S64);
265  PUT(BUF);
266  case URPC_BIN:
267  {
268  int len = atoi(fmt);
269  if (len == 0)
270  BUG(NULL, "Internal serilizer bug processing: %s", fmt);
271  va_put_BIN(buf, len, ap);
272  while (*fmt && (*fmt++ != '.'));
273  break;
274  }
275  };
276  };
277  return buf;
278 }
struct aura_buffer * aura_buffer_request(struct aura_node *nd, int size)
Definition: buffer.c:40
int pos
Definition: aura.h:339
int size
Definition: aura.h:337