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