FD.io VPP  v20.09-64-g4f7b92f0a
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 {
55  /* Current data buffer being serialized/unserialized. */
57 
58  /* Size of buffer in bytes. */
60 
61  /* Current index into buffer. */
63 
64  /* Overflow buffer for when there is not enough room at the end of
65  buffer to hold serialized/unserialized data. */
67 
68  /* Current index in overflow buffer for reads. */
70 
72 #define SERIALIZE_END_OF_STREAM (1 << 0)
73 
75 
76  u32 opaque[64 - 4 * sizeof (u32) - 1 * sizeof (uword) -
77  2 * sizeof (void *)];
79 
80 always_inline void
81 serialize_stream_set_end_of_stream (serialize_stream_t * s)
82 {
84 }
85 
87 serialize_stream_is_end_of_stream (serialize_stream_t * s)
88 {
89  return (s->flags & SERIALIZE_END_OF_STREAM) != 0;
90 }
91 
93 {
95 
96  /* Data callback function and opaque data. */
98 
99  /* Error if signaled by data function. */
101 
102  /* Exit unwind point if error occurs. */
105 
106 always_inline void
108 {
110 }
111 
112 #define serialize_error_return(m,args...) \
113  serialize_error (&(m)->header, clib_error_return (0, args))
114 
116  serialize_stream_t * s,
117  uword n_bytes, uword flags);
118 
119 #define SERIALIZE_FLAG_IS_READ (1 << 0)
120 #define SERIALIZE_FLAG_IS_WRITE (1 << 1)
121 
122 always_inline void *
124  serialize_stream_t * s,
125  uword n_bytes, uword flags)
126 {
127  uword i, j, l;
128 
129  l = vec_len (s->overflow_buffer);
130  i = s->current_buffer_index;
131  j = i + n_bytes;
132  s->current_buffer_index = j;
133  if (l == 0 && j <= s->n_buffer_bytes)
134  {
135  return s->buffer + i;
136  }
137  else
138  {
139  s->current_buffer_index = i;
140  return serialize_read_write_not_inline (header, s, n_bytes, flags);
141  }
142 }
143 
144 typedef struct
145 {
147  serialize_stream_t stream;
149 
150 always_inline void
152 {
154 }
155 
158 {
160 }
161 
162 typedef struct
163 {
165  serialize_stream_t *streams;
167 
168 typedef void (serialize_function_t) (serialize_main_t * m, va_list * va);
169 
170 always_inline void *
172 {
173  return serialize_stream_read_write (&m->header, &m->stream, n_bytes,
175 }
176 
177 always_inline void *
179 {
180  return serialize_stream_read_write (&m->header, &m->stream, n_bytes,
182 }
183 
184 always_inline void
186 {
187  u8 *p = serialize_get (m, n_bytes);
188  if (n_bytes == 1)
189  p[0] = x;
190  else if (n_bytes == 2)
191  clib_mem_unaligned (p, u16) = clib_host_to_net_u16 (x);
192  else if (n_bytes == 4)
193  clib_mem_unaligned (p, u32) = clib_host_to_net_u32 (x);
194  else if (n_bytes == 8)
195  clib_mem_unaligned (p, u64) = clib_host_to_net_u64 (x);
196  else
197  ASSERT (0);
198 }
199 
200 always_inline void
201 unserialize_integer (serialize_main_t * m, void *x, u32 n_bytes)
202 {
203  u8 *p = unserialize_get (m, n_bytes);
204  if (n_bytes == 1)
205  *(u8 *) x = p[0];
206  else if (n_bytes == 2)
207  *(u16 *) x = clib_net_to_host_unaligned_mem_u16 ((u16 *) p);
208  else if (n_bytes == 4)
209  *(u32 *) x = clib_net_to_host_unaligned_mem_u32 ((u32 *) p);
210  else if (n_bytes == 8)
211  *(u64 *) x = clib_net_to_host_unaligned_mem_u64 ((u64 *) p);
212  else
213  ASSERT (0);
214 }
215 
216 /* As above but tries to be more compact. */
217 always_inline void
219 {
220  u64 r = x;
221  u8 *p;
222 
223  /* Low bit set means it fits into 1 byte. */
224  if (r < (1 << 7))
225  {
226  p = serialize_get (m, 1);
227  p[0] = 1 + 2 * r;
228  return;
229  }
230 
231  /* Low 2 bits 1 0 means it fits into 2 bytes. */
232  r -= (1 << 7);
233  if (r < (1 << 14))
234  {
235  p = serialize_get (m, 2);
236  clib_mem_unaligned (p, u16) = clib_host_to_little_u16 (4 * r + 2);
237  return;
238  }
239 
240  r -= (1 << 14);
241  if (r < (1 << 29))
242  {
243  p = serialize_get (m, 4);
244  clib_mem_unaligned (p, u32) = clib_host_to_little_u32 (8 * r + 4);
245  return;
246  }
247 
248  p = serialize_get (m, 9);
249  p[0] = 0; /* Only low 3 bits are used. */
250  clib_mem_unaligned (p + 1, u64) = clib_host_to_little_u64 (x);
251 }
252 
255 {
256  u8 *p = unserialize_get (m, 1);
257  u64 r;
258  u32 y = p[0];
259 
260  if (y & 1)
261  return y / 2;
262 
263  r = 1 << 7;
264  if (y & 2)
265  {
266  p = unserialize_get (m, 1);
267  r += (y / 4) + (p[0] << 6);
268  return r;
269  }
270 
271  r += 1 << 14;
272  if (y & 4)
273  {
274  p = unserialize_get (m, 3);
275  r += ((y / 8)
276  + (p[0] << (5 + 8 * 0))
277  + (p[1] << (5 + 8 * 1)) + (p[2] << (5 + 8 * 2)));
278  return r;
279  }
280 
281  p = unserialize_get (m, 8);
282  r = clib_mem_unaligned (p, u64);
283  r = clib_little_to_host_u64 (r);
284 
285  return r;
286 }
287 
288 always_inline void
290 {
291  u64 u = s < 0 ? -(2 * s + 1) : 2 * s;
293 }
294 
297 {
299  i64 s = u / 2;
300  return (u & 1) ? -s : s;
301 }
302 
303 void
305  void *data, uword data_stride, uword n_data);
306 void
308  void *data, uword data_stride, uword n_data);
309 void
311  void *data, uword data_stride, uword n_data);
312 
313 void
315  void *data, uword data_stride, uword n_data);
316 void
318  void *data, uword data_stride, uword n_data);
319 void
321  void *data, uword data_stride, uword n_data);
322 
323 always_inline void
325  void *data,
326  uword n_data_bytes, uword data_stride, uword n_data)
327 {
328  if (n_data_bytes == 1)
329  serialize_multiple_1 (m, data, data_stride, n_data);
330  else if (n_data_bytes == 2)
331  serialize_multiple_2 (m, data, data_stride, n_data);
332  else if (n_data_bytes == 4)
333  serialize_multiple_4 (m, data, data_stride, n_data);
334  else
335  ASSERT (0);
336 }
337 
338 always_inline void
340  void *data,
341  uword n_data_bytes, uword data_stride, uword n_data)
342 {
343  if (n_data_bytes == 1)
344  unserialize_multiple_1 (m, data, data_stride, n_data);
345  else if (n_data_bytes == 2)
346  unserialize_multiple_2 (m, data, data_stride, n_data);
347  else if (n_data_bytes == 4)
348  unserialize_multiple_4 (m, data, data_stride, n_data);
349  else
350  ASSERT (0);
351 }
352 
353 /* Basic types. */
360 
361 /* Basic vector types. */
366 
367 /* Serialize generic vectors. */
370 
371 #define vec_serialize(m,v,f) \
372  serialize ((m), serialize_vector, (v), sizeof ((v)[0]), (f))
373 
374 #define vec_unserialize(m,v,f) \
375  unserialize ((m), unserialize_vector, (v), sizeof ((*(v))[0]), (f))
376 
377 #define vec_unserialize_aligned(m,v,f) \
378  unserialize ((m), unserialize_aligned_vector, (v), sizeof ((*(v))[0]), (f))
379 
380 /* Serialize pools. */
383 
384 #define pool_serialize(m,v,f) \
385  serialize ((m), serialize_pool, (v), sizeof ((v)[0]), (f))
386 
387 #define pool_unserialize(m,v,f) \
388  unserialize ((m), unserialize_pool, (v), sizeof ((*(v))[0]), (f))
389 
390 #define pool_unserialize_aligned(m,v,a,f) \
391  unserialize ((m), unserialize_aligned_pool, (v), sizeof ((*(v))[0]), (a), (f))
392 
393 /* Serialize heaps. */
395 
396 void serialize_bitmap (serialize_main_t * m, uword * b);
398 
399 void serialize_cstring (serialize_main_t * m, char *string);
400 void unserialize_cstring (serialize_main_t * m, char **string);
401 
404 
405 void serialize_open_data (serialize_main_t * m, u8 * data,
406  uword n_data_bytes);
407 void unserialize_open_data (serialize_main_t * m, u8 * data,
408  uword n_data_bytes);
409 
410 /* Starts serialization with expanding vector as buffer. */
411 void serialize_open_vector (serialize_main_t * m, u8 * vector);
412 
413 /* Serialization is done: returns vector buffer to caller. */
415 
416 void unserialize_open_vector (serialize_main_t * m, u8 * vector);
417 
418 #ifdef CLIB_UNIX
421 
424 #endif /* CLIB_UNIX */
425 
426 /* Main routines. */
429 clib_error_t *va_serialize (serialize_main_t * m, va_list * va);
430 
431 void serialize_magic (serialize_main_t * m, void *magic, u32 magic_bytes);
432 void unserialize_check_magic (serialize_main_t * m, void *magic,
433  u32 magic_bytes);
434 
435 #endif /* included_clib_serialize_h */
436 
437 /*
438  * fd.io coding-style-patch-verification: ON
439  *
440  * Local Variables:
441  * eval: (c-set-style "gnu")
442  * End:
443  */
clib_error_t * unserialize_open_clib_file(serialize_main_t *m, char *file)
Definition: serialize.c:1242
void unserialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1109
u32 current_overflow_index
Definition: serialize.h:69
serialize_function_t unserialize_16
Definition: serialize.h:356
static u64 unserialize_likely_small_unsigned_integer(serialize_main_t *m)
Definition: serialize.h:254
void serialize_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:625
void unserialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:891
static uword serialize_is_end_of_stream(serialize_main_t *m)
Definition: serialize.h:157
void unserialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1040
void serialize_close(serialize_main_t *m)
Definition: serialize.c:870
unsigned long u64
Definition: types.h:89
serialize_main_header_t header
Definition: serialize.h:146
static void serialize_error(serialize_main_header_t *m, clib_error_t *error)
Definition: serialize.h:107
serialize_function_t serialize_32
Definition: serialize.h:355
serialize_stream_t * streams
Definition: serialize.h:165
clib_error_t * unserialize(serialize_main_t *m,...)
Definition: serialize.c:684
serialize_function_t unserialize_64
Definition: serialize.h:354
serialize_function_t unserialize_vec_16
Definition: serialize.h:363
static void serialize_stream_set_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:81
serialize_function_t serialize_pool
Definition: serialize.h:381
void() serialize_function_t(serialize_main_t *m, va_list *va)
Definition: serialize.h:168
void clib_longjmp(clib_longjmp_t *save, uword return_value)
void unserialize_close(serialize_main_t *m)
Definition: serialize.c:877
static void * serialize_stream_read_write(serialize_main_header_t *header, serialize_stream_t *s, uword n_bytes, uword flags)
Definition: serialize.h:123
struct serialize_main_header_t serialize_main_header_t
serialize_function_t serialize_64
Definition: serialize.h:354
unsigned char u8
Definition: types.h:56
serialize_function_t unserialize_aligned_vector
Definition: serialize.h:368
serialize_function_t unserialize_f32
Definition: serialize.h:359
static void serialize_set_end_of_stream(serialize_main_t *m)
Definition: serialize.h:151
serialize_function_t serialize_vector
Definition: serialize.h:368
void * serialize_close_vector(serialize_main_t *m)
Definition: serialize.c:919
static i64 unserialize_likely_small_signed_integer(serialize_main_t *m)
Definition: serialize.h:296
static uword serialize_stream_is_end_of_stream(serialize_stream_t *s)
Definition: serialize.h:87
static void * serialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:178
clib_error_t * serialize(serialize_main_t *m,...)
Definition: serialize.c:672
serialize_function_t unserialize_aligned_pool
Definition: serialize.h:381
void serialize_open_vector(serialize_main_t *m, u8 *vector)
Definition: serialize.c:909
unsigned int u32
Definition: types.h:88
static void serialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:324
void serialize_multiple_1(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:934
#define SERIALIZE_FLAG_IS_READ
Definition: serialize.h:119
void unserialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1072
serialize_function_t unserialize_vec_64
Definition: serialize.h:365
serialize_function_t serialize_vec_32
Definition: serialize.h:364
clib_error_t * error
Definition: serialize.h:100
serialize_function_t serialize_vec_64
Definition: serialize.h:365
serialize_function_t unserialize_32
Definition: serialize.h:355
static void serialize_likely_small_unsigned_integer(serialize_main_t *m, u64 x)
Definition: serialize.h:218
void serialize_multiple_2(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:966
unsigned short u16
Definition: types.h:57
signed long i64
Definition: types.h:78
void unserialize_check_magic(serialize_main_t *m, void *magic, u32 magic_bytes)
Definition: serialize.c:634
vec_header_t h
Definition: buffer.c:322
#define always_inline
Definition: ipsec.h:28
void unserialize_open_clib_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1215
static void * unserialize_get(serialize_main_t *m, uword n_bytes)
Definition: serialize.h:171
void serialize_bitmap(serialize_main_t *m, uword *b)
Definition: serialize.c:359
serialize_function_t unserialize_vector
Definition: serialize.h:368
serialize_function_t unserialize_f64
Definition: serialize.h:358
serialize_function_t serialize_16
Definition: serialize.h:356
serialize_function_t unserialize_8
Definition: serialize.h:357
#define SERIALIZE_END_OF_STREAM
Definition: serialize.h:72
serialize_stream_t stream
Definition: serialize.h:147
u32 current_buffer_index
Definition: serialize.h:62
uword * unserialize_bitmap(serialize_main_t *m)
Definition: serialize.c:377
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
static void unserialize_multiple(serialize_main_t *m, void *data, uword n_data_bytes, uword data_stride, uword n_data)
Definition: serialize.h:339
serialize_data_function_t * data_function
Definition: serialize.h:97
void serialize_open_clib_file_descriptor(serialize_main_t *m, int fd)
Definition: serialize.c:1209
static void unserialize_integer(serialize_main_t *m, void *x, u32 n_bytes)
Definition: serialize.h:201
static void serialize_integer(serialize_main_t *m, u64 x, u32 n_bytes)
Definition: serialize.h:185
u32 opaque[64 - 4 *sizeof(u32) - 1 *sizeof(uword) - 2 *sizeof(void *)]
Definition: serialize.h:77
static void serialize_likely_small_signed_integer(serialize_main_t *m, i64 s)
Definition: serialize.h:289
serialize_function_t serialize_heap
Definition: serialize.h:394
uword data_function_opaque
Definition: serialize.h:74
serialize_function_t serialize_vec_16
Definition: serialize.h:363
serialize_function_t unserialize_vec_8
Definition: serialize.h:362
void serialize_cstring(serialize_main_t *m, char *string)
Definition: serialize.c:164
#define ASSERT(truth)
void serialize_multiple_4(serialize_main_t *m, void *data, uword data_stride, uword n_data)
Definition: serialize.c:1003
clib_error_t * va_serialize(serialize_main_t *m, va_list *va)
Definition: serialize.c:651
void unserialize_open_vector(serialize_main_t *m, u8 *vector)
void unserialize_cstring(serialize_main_t *m, char **string)
Definition: serialize.c:178
#define clib_mem_unaligned(pointer, type)
Definition: types.h:155
static uword pointer_to_uword(const void *p)
Definition: types.h:131
serialize_function_t serialize_f32
Definition: serialize.h:359
serialize_function_t serialize_vec_8
Definition: serialize.h:362
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void() serialize_data_function_t(struct serialize_main_header_t *h, struct serialize_stream_t *s)
Definition: serialize.h:50
serialize_main_header_t header
Definition: serialize.h:164
u64 uword
Definition: types.h:112
void serialize_open_data(serialize_main_t *m, u8 *data, uword n_data_bytes)
Definition: serialize.c:883
clib_error_t * serialize_open_clib_file(serialize_main_t *m, char *file)
Definition: serialize.c:1236
#define SERIALIZE_FLAG_IS_WRITE
Definition: serialize.h:120
serialize_function_t unserialize_heap
Definition: serialize.h:394
serialize_function_t serialize_8
Definition: serialize.h:357
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:842
serialize_function_t unserialize_pool
Definition: serialize.h:381
clib_longjmp_t error_longjmp
Definition: serialize.h:103
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
serialize_function_t serialize_f64
Definition: serialize.h:358
serialize_function_t unserialize_vec_32
Definition: serialize.h:364