]>
Commit | Line | Data |
---|---|---|
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 |
24 | struct marshal_info; |
25 | enum 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 | |
32 | struct 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 |
39 | struct 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 |
52 | extern struct marshal_info marshal_info_string; |
53 | extern struct marshal_info marshal_info_fstring; | |
54 | extern 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 | |
60 | #define MARSHAL_BEGIN(type) struct marshal_info MARSHAL_INFO(type) = \ | |
db323555 VB |
61 | { \ |
62 | .name = #type, \ | |
63 | .size = sizeof(struct type), \ | |
64 | .pointers = { | |
ca4ed9da VB |
65 | #define MARSHAL_ADD(_kind, type, subtype, member) \ |
66 | { .offset = offsetof(struct type, member), \ | |
01d467de | 67 | .offset2 = 0, \ |
ca4ed9da | 68 | .kind = _kind, \ |
6bf5e749 | 69 | .mi = &MARSHAL_INFO(subtype) }, |
ca4ed9da VB |
70 | #define MARSHAL_FSTR(type, member, len) \ |
71 | { .offset = offsetof(struct type, member), \ | |
72 | .offset2 = offsetof(struct type, len), \ | |
73 | .kind = pointer, \ | |
6bf5e749 | 74 | .mi = &marshal_info_fstring }, |
01d467de | 75 | #define MARSHAL_END MARSHAL_SUBINFO_NULL }} |
6bf5e749 VB |
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) | |
5e73393b VB |
87 | #define MARSHAL_TQE(type, field) \ |
88 | MARSHAL_POINTER(type, type, field.tqe_next) \ | |
6bf5e749 VB |
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 | |
4e90a9e0 | 92 | possible. However, TAILQ_FOREACH is still |
6bf5e749 | 93 | available. */ |
5e73393b VB |
94 | #define MARSHAL_TQH(type, subtype) \ |
95 | MARSHAL_POINTER(type, subtype, tqh_first) \ | |
6bf5e749 | 96 | MARSHAL_IGNORE(type, tqh_last) |
5e73393b VB |
97 | #define MARSHAL_SUBTQ(type, subtype, field) \ |
98 | MARSHAL_POINTER(type, subtype, field.tqh_first) \ | |
6bf5e749 | 99 | MARSHAL_IGNORE(type, field.tqh_last) |
5e73393b VB |
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 | |
db323555 VB |
107 | |
108 | /* Serialization */ | |
6bf5e749 VB |
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) | |
db323555 VB |
111 | |
112 | /* Unserialization */ | |
6bf5e749 | 113 | size_t marshal_unserialize_(struct marshal_info *, void *, size_t, void **, void*, int, int); |
db323555 | 114 | #define marshal_unserialize(type, o, l, input) \ |
6bf5e749 | 115 | marshal_unserialize_(&MARSHAL_INFO(type), o, l, (void **)input, NULL, 0, 0) |
db323555 VB |
116 | |
117 | #endif |