]> git.ipfire.org Git - thirdparty/lldpd.git/blame - src/marshal.h
marshal: don't declare serialize/unserialize helper for string
[thirdparty/lldpd.git] / src / marshal.h
CommitLineData
4b292b55 1/* -*- mode: c; c-file-style: "openbsd" -*- */
db323555
VB
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
4b292b55
VB
21#include <stddef.h>
22#include <sys/types.h>
23
db323555
VB
24struct marshal_info;
25enum marshal_subinfo_kind {
26 pointer,
27 substruct,
305e061c 28 ignore,
db323555
VB
29};
30#define MARSHAL_INFO_POINTER 1
31#define MARSHAL_INFO_SUB 2
32struct marshal_subinfo {
33 size_t offset; /* Offset compared to parent structure */
ca4ed9da 34 size_t offset2; /* Ancillary offset (for related data) */
db323555
VB
35 enum marshal_subinfo_kind kind; /* Kind of substructure */
36 struct marshal_info *mi;
37};
01d467de 38#define MARSHAL_SUBINFO_NULL { .offset = 0, .offset2 = 0, .kind = ignore, .mi = NULL }
db323555
VB
39struct marshal_info {
40 char *name; /* Name of structure */
41 size_t size; /* Size of the structure */
01d467de
VB
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
db323555 48 struct marshal_subinfo pointers[]; /* Pointer to other structures */
01d467de 49#endif
db323555 50};
da781141 51/* Special case for strings */
6bf5e749
VB
52extern struct marshal_info marshal_info_string;
53extern struct marshal_info marshal_info_fstring;
54extern struct marshal_info marshal_info_ignore;
db323555
VB
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. */
6bf5e749
VB
58#define MARSHAL_INFO(type) marshal_info_##type
59#ifdef MARSHAL_EXPORT
985a4cb5
VB
60#define MARSHAL_HELPER_FUNCTIONS(type, ttype) \
61 ssize_t \
62 type ## _serialize(ttype *source, void *buffer) { \
63 return marshal_serialize(type, \
64 source, buffer); \
65 } \
66 size_t \
67 type ## _unserialize(void *buffer, size_t len, \
68 ttype **destination) { \
69 void *p; \
70 size_t rc; \
71 rc = marshal_unserialize(type, \
72 buffer, len, &p); \
73 if (rc <= 0) return rc; \
74 *destination = p; \
75 return rc; \
76 }
6bf5e749 77#define MARSHAL_BEGIN(type) struct marshal_info MARSHAL_INFO(type) = \
db323555
VB
78 { \
79 .name = #type, \
80 .size = sizeof(struct type), \
81 .pointers = {
ca4ed9da
VB
82#define MARSHAL_ADD(_kind, type, subtype, member) \
83 { .offset = offsetof(struct type, member), \
01d467de 84 .offset2 = 0, \
ca4ed9da 85 .kind = _kind, \
6bf5e749 86 .mi = &MARSHAL_INFO(subtype) },
ca4ed9da
VB
87#define MARSHAL_FSTR(type, member, len) \
88 { .offset = offsetof(struct type, member), \
89 .offset2 = offsetof(struct type, len), \
90 .kind = pointer, \
6bf5e749 91 .mi = &marshal_info_fstring },
985a4cb5
VB
92#define MARSHAL_END(type) MARSHAL_SUBINFO_NULL }}; \
93 MARSHAL_HELPER_FUNCTIONS(type, struct type)
6bf5e749 94#else
985a4cb5
VB
95#define MARSHAL_HELPER_FUNCTIONS(type, ttype) \
96 ssize_t type ## _serialize(ttype*, void*); \
97 size_t type ## _unserialize(void*, size_t, ttype**);
98#define MARSHAL_BEGIN(type) extern struct marshal_info MARSHAL_INFO(type);
6bf5e749
VB
99#define MARSHAL_ADD(...)
100#define MARSHAL_FSTR(...)
985a4cb5 101#define MARSHAL_END(type) MARSHAL_HELPER_FUNCTIONS(type, struct type)
6bf5e749
VB
102#endif
103/* Shortcuts */
104#define MARSHAL_POINTER(...) MARSHAL_ADD(pointer, ##__VA_ARGS__)
105#define MARSHAL_SUBSTRUCT(...) MARSHAL_ADD(substruct, ##__VA_ARGS__)
106#define MARSHAL_STR(type, member) MARSHAL_ADD(pointer, type, string, member)
107#define MARSHAL_IGNORE(type, member) MARSHAL_ADD(ignore, type, ignore, member)
5e73393b
VB
108#define MARSHAL_TQE(type, field) \
109 MARSHAL_POINTER(type, type, field.tqe_next) \
6bf5e749
VB
110 MARSHAL_IGNORE(type, field.tqe_prev)
111/* Support for TAILQ list is partial. Access to last and previous
112 elements is not available. Some operations are therefore not
4e90a9e0 113 possible. However, TAILQ_FOREACH is still
6bf5e749 114 available. */
5e73393b
VB
115#define MARSHAL_TQH(type, subtype) \
116 MARSHAL_POINTER(type, subtype, tqh_first) \
6bf5e749 117 MARSHAL_IGNORE(type, tqh_last)
5e73393b
VB
118#define MARSHAL_SUBTQ(type, subtype, field) \
119 MARSHAL_POINTER(type, subtype, field.tqh_first) \
6bf5e749 120 MARSHAL_IGNORE(type, field.tqh_last)
5e73393b
VB
121#define MARSHAL(type) \
122 MARSHAL_BEGIN(type) \
985a4cb5 123 MARSHAL_END(type)
5e73393b
VB
124#define MARSHAL_TQ(type, subtype) \
125 MARSHAL_BEGIN(type) \
126 MARSHAL_TQH(type, subtype) \
985a4cb5 127 MARSHAL_END(type)
db323555
VB
128
129/* Serialization */
aa015c26
VB
130ssize_t marshal_serialize_(struct marshal_info *, void *, void **, int, void *, int)
131 __attribute__((nonnull (1, 2, 3) ));
6bf5e749 132#define marshal_serialize(type, o, output) marshal_serialize_(&MARSHAL_INFO(type), o, output, 0, NULL, 0)
db323555
VB
133
134/* Unserialization */
aa015c26
VB
135size_t marshal_unserialize_(struct marshal_info *, void *, size_t, void **, void*, int, int)
136 __attribute__((nonnull (1, 2, 4) ));
db323555 137#define marshal_unserialize(type, o, l, input) \
0e940d8d 138 marshal_unserialize_(&MARSHAL_INFO(type), o, l, input, NULL, 0, 0)
db323555
VB
139
140#endif