FD.io VPP  v16.06
Vector Packet Processing
serialize.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  Copyright (c) 2005 Eliot Dresselhaus
17 
18  Permission is hereby granted, free of charge, to any person obtaining
19  a copy of this software and associated documentation files (the
20  "Software"), to deal in the Software without restriction, including
21  without limitation the rights to use, copy, modify, merge, publish,
22  distribute, sublicense, and/or sell copies of the Software, and to
23  permit persons to whom the Software is furnished to do so, subject to
24  the following conditions:
25 
26  The above copyright notice and this permission notice shall be
27  included in all copies or substantial portions of the Software.
28 
29  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 */
37 
38 #ifndef included_clib_serialize_h
39 #define included_clib_serialize_h
40 
41 #include <stdarg.h>
42 #include <vppinfra/byte_order.h>
43 #include <vppinfra/types.h>
44 #include <vppinfra/vec.h>
45 #include <vppinfra/longjmp.h>
46 
48 struct serialize_stream_t;
49 
51  struct serialize_stream_t * s);
52 
53 typedef struct serialize_stream_t {
54  /* Current data buffer being serialized/unserialized. */
56 
57  /* Size of buffer in bytes. */
59 
60  /* Current index into buffer. */
62 
63  /* Overflow buffer for when there is not enough room at the end of
64  buffer to hold serialized/unserialized data. */
66 
67  /* Current index in overflow buffer for reads. */
69 
71 #define SERIALIZE_END_OF_STREAM (1 << 0)
72 
74 
75  u32 opaque[64 - 4 * sizeof (u32) - 1 * sizeof (uword) - 2 * sizeof (void *)];
77 
78 always_inline void
79 serialize_stream_set_end_of_stream (serialize_stream_t * s)
81 
83 serialize_stream_is_end_of_stream (serialize_stream_t * s)
84 { return (s->flags & SERIALIZE_END_OF_STREAM) != 0; }
85 
86 typedef struct serialize_main_header_t {
88 
89  /* Data callback function and opaque data. */
91 
92  /* Error if signaled by data function. */
94 
95  /* Exit unwind point if error occurs. */
98 
99 always_inline void
101 { clib_longjmp (&m->error_longjmp, pointer_to_uword (error)); }
102 
103 #define serialize_error_return(m,args...) \
104  serialize_error (&(m)->header, clib_error_return (0, args))
105 
107  serialize_stream_t * s,
108  uword n_bytes, uword flags);
109 
110 #define SERIALIZE_FLAG_IS_READ (1 << 0)
111 #define SERIALIZE_FLAG_IS_WRITE (1 << 1)
112 
113 always_inline void *
115  serialize_stream_t * s,
116  uword n_bytes,
117  uword flags)
118 {
119  uword i, j, l;
120 
121  l = vec_len (s->overflow_buffer);
122  i = s->current_buffer_index;
123  j = i + n_bytes;
124  s->current_buffer_index = j;
125  if (l == 0 && j <= s->n_buffer_bytes)
126  {
127  return s->buffer + i;
128  }
129  else
130  {
131  s->current_buffer_index = i;
132  return serialize_read_write_not_inline (header, s, n_bytes, flags);
133  }
134 }
135 
136 typedef struct {
138  serialize_stream_t stream;
140 
141 always_inline void
144 
148 
149 typedef struct {
151  serialize_stream_t * streams;
153 
154 typedef void (serialize_function_t) (serialize_main_t * m, va_list * va);
155 
156 always_inline void *
158 { return serialize_stream_read_write (&m->header, &m->stream, n_bytes, SERIALIZE_FLAG_IS_READ); }
159 
160 always_inline void *
162 { return serialize_stream_read_write (&m->header, &m->stream, n_bytes, SERIALIZE_FLAG_IS_WRITE); }
163 
164 always_inline void
166 {
167  u8 * p = serialize_get (m, n_bytes);
168  if (n_bytes == 1)
169  p[0] = x;
170  else if (n_bytes == 2)
171  clib_mem_unaligned (p, u16) = clib_host_to_net_u16 (x);
172  else if (n_bytes == 4)
173  clib_mem_unaligned (p, u32) = clib_host_to_net_u32 (x);
174  else if (n_bytes == 8)
175  clib_mem_unaligned (p, u64) = clib_host_to_net_u64 (x);
176  else
177  ASSERT (0);
178 }
179 
180 always_inline void
181 unserialize_integer (serialize_main_t * m, void * x, u32 n_bytes)
182 {
183  u8 * p = unserialize_get (m, n_bytes);
184  if (n_bytes == 1)
185  *(u8 *) x = p[0];
186  else if (n_bytes == 2)
187  *(u16 *) x = clib_net_to_host_unaligned_mem_u16 ((u16 *) p);
188  else if (n_bytes == 4)
189  *(u32 *) x = clib_net_to_host_unaligned_mem_u32 ((u32 *) p);
190  else if (n_bytes == 8)
191  *(u64 *) x = clib_net_to_host_unaligned_mem_u64 ((u64 *) p);
192  else
193  ASSERT (0);
194 }
195 
196 /* As above but tries to be more compact. */
197 always_inline void
199 {
200  u64 r = x;
201  u8 * p;
202 
203  /* Low bit set means it fits into 1 byte. */
204  if (r < (1 << 7))
205  {
206  p = serialize_get (m, 1);
207  p[0] = 1 + 2*r;
208  return;
209  }
210 
211  /* Low 2 bits 1 0 means it fits into 2 bytes. */
212  r -= (1 << 7);
213  if (r < (1 << 14))
214  {
215  p = serialize_get (m, 2);
216  clib_mem_unaligned (p, u16) = clib_host_to_little_u16 (4 * r + 2);
217  return;
218  }
219 
220  r -= (1 << 14);
221  if (r < (1 << 29))
222  {
223  p = serialize_get (m, 4);
224  clib_mem_unaligned (p, u32) = clib_host_to_little_u32 (8 * r + 4);
225  return;
226  }
227 
228  p = serialize_get (m, 9);
229  p[0] = 0; /* Only low 3 bits are used. */
230  clib_mem_unaligned (p + 1, u64) = clib_host_to_little_u64 (x);
231 }
232 
235 {
236  u8 * p = unserialize_get (m, 1);
237  u64 r;
238  u32 y = p[0];
239 
240  if (y & 1)
241  return y / 2;
242 
243  r = 1 << 7;
244  if (y & 2)
245  {
246  p = unserialize_get (m, 1);
247  r += (y / 4) + (p[0] << 6);
248  return r;
249  }
250 
251  r += 1 << 14;
252  if (y & 4)
253  {
254  p = unserialize_get (m, 3);
255  r += ((y / 8)
256  + (p[0] << (5 + 8*0))
257  + (p[1] << (5 + 8*1))
258  + (p[2] << (5 + 8*2)));
259  return r;
260  }
261 
262  p = unserialize_get (m, 8);
263  r = clib_mem_unaligned (p, u64);
264  r = clib_little_to_host_u64 (r);
265 
266  return r;
267 }
268 
269 always_inline void
271 {
272  u64 u = s < 0 ? -(2*s + 1) : 2*s;
274 }
275 
278 {
280  i64 s = u / 2;
281  return (u & 1) ? -s : s;
282 }
283 
284 void
286  void * data,
287  uword data_stride,
288  uword n_data);
289 void
291  void * data,
292  uword data_stride,
293  uword n_data);
294 void
296  void * data,
297  uword data_stride,
298  uword n_data);
299 
300 void
302  void * data,
303  uword data_stride,
304  uword n_data);
305 void
307  void * data,
308  uword data_stride,
309  uword n_data);
310 void
312  void * data,
313  uword data_stride,
314  uword n_data);
315 
316 always_inline void
318  void * data,
319  uword n_data_bytes,
320  uword data_stride,
321  uword n_data)
322 {
323  if (n_data_bytes == 1)
324  serialize_multiple_1 (m, data, data_stride, n_data);
325  else if (n_data_bytes == 2)
326  serialize_multiple_2 (m, data, data_stride, n_data);
327  else if (n_data_bytes == 4)
328  serialize_multiple_4 (m, data, data_stride, n_data);
329  else
330  ASSERT (0);
331 }
332 
333 always_inline void
335  void * data,
336  uword n_data_bytes,
337  uword data_stride,
338  uword n_data)
339 {
340  if (n_data_bytes == 1)
341  unserialize_multiple_1 (m, data, data_stride, n_data);
342  else if (n_data_bytes == 2)
343  unserialize_multiple_2 (m, data, data_stride, n_data);
344  else if (n_data_bytes == 4)
345  unserialize_multiple_4 (m, data, data_stride, n_data);
346  else
347  ASSERT (0);
348 }
349 
350 /* Basic types. */
357 
358 /* Basic vector types. */
363 
364 /* Serialize generic vectors. */
366 
367 #define vec_serialize(m,v,f) \
368  serialize ((m), serialize_vector, (v), sizeof ((v)[0]), (f))
369 
370 #define vec_unserialize(m,v,f) \
371  unserialize ((m), unserialize_vector, (v), sizeof ((*(v))[0]), (f))
372 
373 #define vec_unserialize_aligned(m,v,f) \
374  unserialize ((m), unserialize_aligned_vector, (v), sizeof ((*(v))[0]), (f))
375 
376 /* Serialize pools. */
378 
379 #define pool_serialize(m,v,f) \
380  serialize ((m), serialize_pool, (v), sizeof ((v)[0]), (f))
381 
382 #define pool_unserialize(m,v,f) \
383  unserialize ((m), unserialize_pool, (v), sizeof ((*(v))[0]), (f))
384 
385 #define pool_unserialize_aligned(m,v,a,f) \
386  unserialize ((m), unserialize_aligned_pool, (v), sizeof ((*(v))[0]), (a), (f))
387 
388 /* Serialize heaps. */
390 
391 void serialize_bitmap (serialize_main_t * m, uword * b);
393 
394 void serialize_cstring (serialize_main_t * m, char * string);
395 void unserialize_cstring (serialize_main_t * m, char ** string);
396 
399 
400 void serialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes);
401 void unserialize_open_data (serialize_main_t * m, u8 * data, uword n_data_bytes);
402 
403 /* Starts serialization with expanding vector as buffer. */
404 void serialize_open_vector (serialize_main_t * m, u8 * vector);
405 
406 /* Serialization is done: returns vector buffer to caller. */
408 
409 void unserialize_open_vector (serialize_main_t * m, u8 * vector);
410 
411 #ifdef CLIB_UNIX
414 
417 #endif /* CLIB_UNIX */
418 
419 /* Main routines. */
422 clib_error_t * va_serialize (serialize_main_t * m, va_list * va);
423 
424 void serialize_magic (serialize_main_t * m, void * magic, u32 magic_bytes);
425 void unserialize_check_magic (serialize_main_t * m, void * magic, u32 magic_bytes);
426 
427 #endif /* included_clib_serialize_h */
void unserialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1043
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
u32 current_overflow_index
Definition: serialize.h:68
serialize_function_t unserialize_16
Definition: serialize.h:353
void serialize_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:580
void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:835
static void(BVT(clib_bihash)*h, BVT(clib_bihash_value)*v)
void unserialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:975
void serialize_close(serialize_main_t *m)
Definition: serialize.c:822
serialize_main_header_t header
Definition: serialize.h:137
serialize_function_t serialize_32
Definition: serialize.h:352
always_inline void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
Definition: serialize.h:198
serialize_stream_t * streams
Definition: serialize.h:151
clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:639
serialize_function_t unserialize_64
Definition: serialize.h:351
serialize_function_t unserialize_vec_16
Definition: serialize.h:360
serialize_function_t serialize_pool
Definition: serialize.h:377
void clib_longjmp(clib_longjmp_t *save, uword return_value)
add_epi add_epi sub_epi sub_epi adds_epu subs_epu i16x8 y
Definition: vector_sse2.h:231
void unserialize_close(serialize_main_t *m)
Definition: serialize.c:825
struct serialize_main_header_t serialize_main_header_t
serialize_function_t serialize_64
Definition: serialize.h:351
serialize_function_t unserialize_aligned_vector
Definition: serialize.h:365
serialize_function_t unserialize_f32
Definition: serialize.h:356
serialize_function_t serialize_vector
Definition: serialize.h:365
always_inline void serialize_stream_set_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:79
#define always_inline
Definition: clib.h:84
void * serialize_close_vector(serialize_main_t *m)
Definition: serialize.c:858
always_inline void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
Definition: serialize.h:181
clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:627
serialize_function_t unserialize_aligned_pool
Definition: serialize.h:377
void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:849
unsigned long u64
Definition: types.h:89
void serialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:873
static uword pointer_to_uword(const void *p)
Definition: types.h:131
always_inline void serialize_error(serialize_main_header_t *m, clib_error_t *error)
Definition: serialize.h:100
#define SERIALIZE_FLAG_IS_READ
Definition: serialize.h:110
always_inline void serialize_likely_small_signed_integer(serialize_main_t *m, i64 s)
Definition: serialize.h:270
void unserialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1009
serialize_function_t unserialize_vec_64
Definition: serialize.h:362
serialize_function_t serialize_vec_32
Definition: serialize.h:361
clib_error_t * error
Definition: serialize.h:93
always_inline uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:83
serialize_function_t serialize_vec_64
Definition: serialize.h:362
serialize_function_t unserialize_32
Definition: serialize.h:352
void serialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:907
void serialize_open_unix_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1136
void unserialize_check_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:588
always_inline void * unserialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:157
void serialize_bitmap(serialize_main_t *m, uword *b)
Definition: serialize.c:323
u32 opaque[64-4 *sizeof(u32)-1 *sizeof(uword)-2 *sizeof(void *)]
Definition: serialize.h:75
long i64
Definition: types.h:82
serialize_function_t unserialize_vector
Definition: serialize.h:365
serialize_function_t unserialize_f64
Definition: serialize.h:355
serialize_function_t serialize_16
Definition: serialize.h:353
serialize_function_t unserialize_8
Definition: serialize.h:354
#define SERIALIZE_END_OF_STREAM
Definition: serialize.h:71
clib_error_t * serialize_open_unix_file(serialize_main_t *m, char *file)
Definition: serialize.c:1157
serialize_stream_t stream
Definition: serialize.h:138
u32 current_buffer_index
Definition: serialize.h:61
uword * unserialize_bitmap(serialize_main_t *m)
Definition: serialize.c:340
always_inline void serialize_set_end_of_stream(serialize_main_t *m)
Definition: serialize.h:142
serialize_data_function_t * data_function
Definition: serialize.h:90
always_inline void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
Definition: serialize.h:165
serialize_function_t serialize_heap
Definition: serialize.h:389
uword data_function_opaque
Definition: serialize.h:73
always_inline uword serialize_is_end_of_stream(serialize_main_t *m)
Definition: serialize.h:146
serialize_function_t serialize_vec_16
Definition: serialize.h:360
serialize_function_t unserialize_vec_8
Definition: serialize.h:359
void serialize_cstring(serialize_main_t *m, char *string)
Definition: serialize.c:135
#define ASSERT(truth)
void serialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:941
unsigned int u32
Definition: types.h:88
clib_error_t * va_serialize(serialize_main_t *m, va_list *va)
Definition: serialize.c:606
void unserialize_open_vector(serialize_main_t *m, u8 *vector)
void unserialize_cstring(serialize_main_t *m, char **string)
Definition: serialize.c:148
clib_error_t * unserialize_open_unix_file(serialize_main_t *m, char *file)
Definition: serialize.c:1161
always_inline i64 unserialize_likely_small_signed_integer(serialize_main_t *m)
Definition: serialize.h:277
serialize_function_t serialize_f32
Definition: serialize.h:356
u64 uword
Definition: types.h:112
unsigned short u16
Definition: types.h:57
serialize_function_t serialize_vec_8
Definition: serialize.h:359
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void( serialize_function_t)(serialize_main_t *m, va_list *va)
Definition: serialize.h:154
unsigned char u8
Definition: types.h:56
serialize_main_header_t header
Definition: serialize.h:150
always_inline void * serialize_stream_read_write(serialize_main_header_t *header, serialize_stream_t *s, uword n_bytes, uword flags)
Definition: serialize.h:114
always_inline void unserialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:334
void serialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:828
#define SERIALIZE_FLAG_IS_WRITE
Definition: serialize.h:111
#define clib_mem_unaligned(pointer, type)
Definition: types.h:153
serialize_function_t unserialize_heap
Definition: serialize.h:389
serialize_function_t serialize_8
Definition: serialize.h:354
always_inline void serialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:317
always_inline void * serialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:161
always_inline u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
Definition: serialize.h:234
void unserialize_open_unix_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1139
void( serialize_data_function_t)(struct serialize_main_header_t *h, struct serialize_stream_t *s)
Definition: serialize.h:50
struct serialize_stream_t serialize_stream_t
void * serialize_read_write_not_inline(serialize_main_header_t *m, serialize_stream_t *s, uword n_bytes, uword flags)
Definition: serialize.c:796
serialize_function_t unserialize_pool
Definition: serialize.h:377
clib_longjmp_t error_longjmp
Definition: serialize.h:96
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
serialize_function_t serialize_f64
Definition: serialize.h:355
serialize_function_t unserialize_vec_32
Definition: serialize.h:361