]> git.ipfire.org Git - thirdparty/lldpd.git/blob - src/marshal.h
4bdf39b4fe4d8cfac94cda3382c8cd4e5899c75b
[thirdparty/lldpd.git] / src / marshal.h
1 /* -*- mode: c; c-file-style: "openbsd" -*- */
2 /*
3 * Copyright (c) 2012 Vincent Bernat <bernat@luffy.cx>
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18 #ifndef _MARSHAL_H
19 #define _MARSHAL_H
20
21 #include <stddef.h>
22 #include <sys/types.h>
23
24 struct marshal_info;
25 enum marshal_subinfo_kind {
26 pointer,
27 substruct,
28 ignore,
29 };
30 #define MARSHAL_INFO_POINTER 1
31 #define MARSHAL_INFO_SUB 2
32 struct marshal_subinfo {
33 size_t offset; /* Offset compared to parent structure */
34 size_t offset2; /* Ancillary offset (for related data) */
35 enum marshal_subinfo_kind kind; /* Kind of substructure */
36 struct marshal_info *mi;
37 };
38 #define MARSHAL_SUBINFO_NULL { .offset = 0, .offset2 = 0, .kind = ignore, .mi = NULL }
39 struct marshal_info {
40 char *name; /* Name of structure */
41 size_t size; /* Size of the structure */
42 #if defined __GNUC__ && __GNUC__ < 3
43 /* With gcc 2.96, flexible arrays are not supported, even with
44 * -std=gnu99. And with gcc 3.x, zero-sized arrays cannot be statically
45 * initialized (with more than one element). */
46 struct marshal_subinfo pointers[0]; /* Pointer to other structures */
47 #else
48 struct marshal_subinfo pointers[]; /* Pointer to other structures */
49 #endif
50 };
51 /* Special case for strings */
52 extern struct marshal_info marshal_info_string;
53 extern struct marshal_info marshal_info_fstring;
54 extern struct marshal_info marshal_info_ignore;
55
56 /* Declare a new marshal_info struct named after the type we want to
57 marshal. The marshalled type has to be a structure. */
58 #define MARSHAL_INFO(type) marshal_info_##type
59 #ifdef MARSHAL_EXPORT
60 #define MARSHAL_BEGIN(type) struct marshal_info MARSHAL_INFO(type) = \
61 { \
62 .name = #type, \
63 .size = sizeof(struct type), \
64 .pointers = {
65 #define MARSHAL_ADD(_kind, type, subtype, member) \
66 { .offset = offsetof(struct type, member), \
67 .offset2 = 0, \
68 .kind = _kind, \
69 .mi = &MARSHAL_INFO(subtype) },
70 #define MARSHAL_FSTR(type, member, len) \
71 { .offset = offsetof(struct type, member), \
72 .offset2 = offsetof(struct type, len), \
73 .kind = pointer, \
74 .mi = &marshal_info_fstring },
75 #define MARSHAL_END MARSHAL_SUBINFO_NULL }}
76 #else
77 #define MARSHAL_BEGIN(type) extern struct marshal_info MARSHAL_INFO(type)
78 #define MARSHAL_ADD(...)
79 #define MARSHAL_FSTR(...)
80 #define MARSHAL_END
81 #endif
82 /* Shortcuts */
83 #define MARSHAL_POINTER(...) MARSHAL_ADD(pointer, ##__VA_ARGS__)
84 #define MARSHAL_SUBSTRUCT(...) MARSHAL_ADD(substruct, ##__VA_ARGS__)
85 #define MARSHAL_STR(type, member) MARSHAL_ADD(pointer, type, string, member)
86 #define MARSHAL_IGNORE(type, member) MARSHAL_ADD(ignore, type, ignore, member)
87 #define MARSHAL_TQE(type, field) \
88 MARSHAL_POINTER(type, type, field.tqe_next) \
89 MARSHAL_IGNORE(type, field.tqe_prev)
90 /* Support for TAILQ list is partial. Access to last and previous
91 elements is not available. Some operations are therefore not
92 possible. However, TAILQ_FOREACH and TAILQ_REMOVE are still
93 available. */
94 #define MARSHAL_TQH(type, subtype) \
95 MARSHAL_POINTER(type, subtype, tqh_first) \
96 MARSHAL_IGNORE(type, tqh_last)
97 #define MARSHAL_SUBTQ(type, subtype, field) \
98 MARSHAL_POINTER(type, subtype, field.tqh_first) \
99 MARSHAL_IGNORE(type, field.tqh_last)
100 #define MARSHAL(type) \
101 MARSHAL_BEGIN(type) \
102 MARSHAL_END
103 #define MARSHAL_TQ(type, subtype) \
104 MARSHAL_BEGIN(type) \
105 MARSHAL_TQH(type, subtype) \
106 MARSHAL_END
107
108 /* Serialization */
109 size_t marshal_serialize_(struct marshal_info *, void *, void **, int, void *, int);
110 #define marshal_serialize(type, o, output) marshal_serialize_(&MARSHAL_INFO(type), o, output, 0, NULL, 0)
111
112 /* Unserialization */
113 size_t marshal_unserialize_(struct marshal_info *, void *, size_t, void **, void*, int, int);
114 #define marshal_unserialize(type, o, l, input) \
115 marshal_unserialize_(&MARSHAL_INFO(type), o, l, (void **)input, NULL, 0, 0)
116
117 #endif