Ziti C SDK
Loading...
Searching...
No Matches
model_support.h
Go to the documentation of this file.
1// Copyright (c) 2020-2022. NetFoundry Inc.
2//
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// https://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#ifndef ZITI_SDK_MODEL_SUPPORT_H
17#define ZITI_SDK_MODEL_SUPPORT_H
18
19#ifndef __cplusplus
20#include <stdbool.h>
21#include <stddef.h>
22#include <stdlib.h>
23#ifndef _MSC_VER
24#include <sys/time.h>
25#endif
26#endif
27
28#include <string.h>
29
30// workaround conflicting ssize_t definitions between json-c and libuv (on Windows x86)
31// json-c internal ssize_t (json_inttypes.h) leaks into application scope
32// even though it is not use in json-c API
33#ifdef _MSC_VER
34#define ssize_t json_c_ssize_t
35#endif
36#include <json-c/json.h>
37#ifdef _MSC_VER
38#undef ssize_t
39#endif
40
41#include "externs.h"
42#include "model_collections.h"
43#include "types.h"
44
45#if !defined(__DEFINED_ssize_t) && !defined(__ssize_t_defined)
46#if _WIN32
47typedef intptr_t ssize_t;
48#define __DEFINED_ssize_t
49#define __ssize_t_defined
50#else
51#include <unistd.h>
52#endif
53#endif
54
77#define MODEL_VISIBILITY
78
79#define MODEL_JSON_COMPACT 0x1
80
81#define none(t) t
82#define ptr(t) t*
83#define array(t) t##_array
84#define map(t) model_map
85#define list(t) model_list
86
87#define FIELD_DECL(name, type, mod, path, _) mod(type) name;
88
89#define DECLARE_MODEL(type, model) \
90typedef struct type##_s {\
91model(FIELD_DECL, type) \
92} type;\
93DECLARE_MODEL_FUNCS(type)
94
95#define DECLARE_MODEL_FUNCS(T) \
96typedef T ** T##_array; \
97MODEL_VISIBILITY const type_meta* get_##T##_meta();\
98static inline ptr(T) alloc_##T(){ return (ptr(T))model_alloc(get_##T##_meta()); }\
99static inline void free_##T(ptr(T) v) { model_free(v, get_##T##_meta()); } \
100static inline void free_##T##_ptr(ptr(T) v) { model_free(v, get_##T##_meta()); free(v); }; \
101static inline int cmp_##T(const ptr(T) lh, const ptr(T) rh) { return model_cmp(lh, rh, get_##T##_meta()); } \
102MODEL_VISIBILITY void free_##T##_array(array(T) *ap);\
103MODEL_VISIBILITY int parse_##T(ptr(T) v, const char* json, size_t len);\
104MODEL_VISIBILITY int parse_##T##_ptr(ptr(T) *p, const char* json, size_t len);\
105MODEL_VISIBILITY int parse_##T##_array(array(T) *a, const char* json, size_t len); \
106MODEL_VISIBILITY int parse_##T##_list(list(T) *l, const char* json, size_t len); \
107static inline ssize_t T##_to_json_r(const ptr(T) v, int flags, char *outbuf, size_t max) { return model_to_json_r(v, get_##T##_meta(), flags, outbuf, max); } \
108static inline char* T##_to_json(const ptr(T) v, int flags, size_t *len) { return model_to_json(v, get_##T##_meta(), flags, len); } \
109static inline int T##_from_json(ptr(T) v, struct json_object *j) { return model_from_json(v, j, get_##T##_meta()); } \
110static inline int T##_ptr_from_json(ptr(T) *v, struct json_object *j) { \
111 if (j == NULL || json_object_get_type(j) == json_type_null) { *v = NULL; return 0; } \
112 *v = alloc_##T(); \
113 int rc = model_from_json(*v, j, get_##T##_meta()); \
114 if (rc != 0) { free_##T##_ptr(*v); *v = NULL;} \
115 return rc;\
116} \
117static inline int T##_list_from_json(list(T) *l, struct json_object *j) { return model_list_from_json(l, j, get_##T##_meta()); } \
118static inline int T##_array_from_json(array(T) *a, struct json_object *j) { return model_array_from_json((void***)a, j, get_##T##_meta()); }
119
120#define gen_field_meta(n, memtype, modifier, p, partype) {\
121.name = #n, \
122.path = #p, \
123.offset = offsetof(partype,n), \
124.mod = modifier##_mod, \
125.meta = get_##memtype##_meta, \
126},
127
128#define IMPL_MODEL(type, model) \
129static field_meta type##_FIELDS[] = {\
130 model(gen_field_meta, type) \
131 }; \
132static type_meta type##_META = { \
133.name = #type, \
134.size = sizeof(type),\
135.field_count = sizeof(type##_FIELDS) / sizeof(field_meta),\
136.fields = type##_FIELDS,\
137}; \
138IMPL_MODEL_FUNCS(type)
139
140#define IMPL_MODEL_FUNCS(T) \
141const type_meta* get_##T##_meta() { return &T##_META; }\
142int parse_##T(ptr(T) v, const char* json, size_t len) { return model_parse(v, json, len, get_##T##_meta()); } \
143int parse_##T##_ptr(ptr(T) *p, const char* json, size_t len) {\
144*p = (ptr(T))calloc(1, sizeof(T)); \
145int rc = parse_##T(*p, json, len); \
146if (rc < 0) { free_##T(*p); free(*p); *p = NULL; } \
147return rc;\
148}\
149int parse_##T##_array(array(T) *a, const char *json, size_t len) { return model_parse_array((void***)a, json, len, get_##T##_meta()); }\
150int parse_##T##_list(list(T) *l, const char *json, size_t len) { return model_parse_list(l, json, len, get_##T##_meta()); }\
151void free_##T##_array(array(T) *ap) { model_free_array((void***)ap, get_##T##_meta()); }
152
153#ifdef __cplusplus
154extern "C" {
155#endif
156typedef const char *model_string;
157
159typedef int64_t model_number;
161typedef bool model_bool;
163typedef char *json;
164
172
173typedef struct field_meta {
174 const char *name;
175 const char *path;
176 size_t offset;
178
179 const struct type_meta *(*meta)();
180} field_meta;
181
182typedef int (*_parse_f)(void *obj, const char *json, void *tok);
183typedef int (*_to_json_f)(const void *obj, void *buf, int indent, int flags);
184typedef void (*_free_f)(void *obj);
185typedef int (*_cmp_f)(const void *lh, const void *rh);
186
187typedef int (*from_json_func)(void *obj, struct json_object *json, const struct type_meta *meta);
188typedef struct json_object* (*to_json_func)(const void *obj);
189
201
202#define MODEL_PARSE_INVALID (-2)
203#define MODEL_PARSE_PARTIAL (-3)
204
205ZITI_FUNC void* model_alloc(const type_meta *meta);
206ZITI_FUNC void model_free(void *obj, const type_meta *meta);
207
208ZITI_FUNC void model_free_array(void ***ap, const type_meta *meta);
209
210ZITI_FUNC int model_cmp(const void *lh, const void *rh, const type_meta *meta);
211
212ZITI_FUNC int model_parse(void *obj, const char *json, size_t len, const type_meta *meta);
213
214ZITI_FUNC int model_from_json(void *obj, struct json_object *json, const type_meta *meta);
215ZITI_FUNC int model_list_from_json(model_list *l, struct json_object *json, const type_meta *meta);
216ZITI_FUNC int model_array_from_json(void ***obj, struct json_object *json, const type_meta *meta);
217
218ZITI_FUNC int model_parse_array(void ***arp, const char *json, size_t len, const type_meta *meta);
219
220ZITI_FUNC int model_parse_list(model_list *list, const char *json, size_t len, const type_meta *meta);
221
222ZITI_FUNC char *model_to_json(const void *obj, const type_meta *meta, int flags, size_t *len);
223
224ZITI_FUNC ssize_t model_to_json_r(const void *obj, const type_meta *meta, int flags, char *outbuf, size_t max);
225
227
229
231
233
235
237
238typedef struct timeval timestamp;
239
240int model_map_compare(const model_map *lh, const model_map *rh, const type_meta *m);
241
248
257
259
260ZITI_FUNC int enum_from_json(void *ptr, struct json_object *j, const void *enum_type);
261ZITI_FUNC int json_enum(const void *ptr, void *buf, int indent, int flags, const void *enum_type);
262ZITI_FUNC struct json_object* enum_to_json(const void* ptr, const void *enum_type);
263
264
265#define mk_enum2(v,t) t##_##v
266#define mk_enum3(v,n,t) t##_##v
267#define enum_f2(v, t) const t v
268#define enum_f3(v, n, t) const t v
269
270#define get_ovrd(_1, _2, _3, NAME, ...) NAME
271
272#define mk_enum(...) get_ovrd(__VA_ARGS__, mk_enum3, mk_enum2)(__VA_ARGS__),
273#define enum_field(...) get_ovrd(__VA_ARGS__, enum_f3, enum_f2)(__VA_ARGS__);
274
275#define DECLARE_ENUM(Enum, Values) \
276enum Enum { \
277Enum##_Unknown = 0, \
278Values(mk_enum, Enum) \
279}; \
280typedef enum Enum Enum; \
281typedef Enum **Enum##_array; \
282struct Enum##_s { \
283const char* (*name)(int v); \
284Enum (*value_of)(const char* n); \
285Enum (*value_ofn)(const char* s, size_t n); \
286Values(enum_field, Enum) \
287}; \
288MODEL_VISIBILITY const type_meta* get_##Enum##_meta();\
289extern const struct Enum##_s Enum##s;
290
291#define get_value_of_ovrd(_1, _2, _3, _4, _5, NAME, ...) NAME
292#define enum_value_of4(v, t, str, len) if(strncmp(str,#v,len) == 0){return (t)t##s.v;}
293#define enum_value_of5(n, v, t, str, len) if(strncmp(str,v,len) == 0){return (t)t##s.n;}
294#define enum_value_of(...) get_value_of_ovrd(__VA_ARGS__, enum_value_of5, enum_value_of4)(__VA_ARGS__)
295
296#define enum_c2(v,t) case t##_##v: return #v
297#define enum_c3(n,v,t) case t##_##n: return v
298#define enum_case(...) get_ovrd(__VA_ARGS__, enum_c3, enum_c2)(__VA_ARGS__);
299
300#define enum_field_v2(v,t) .v = t##_##v
301#define enum_field_v3(n,v,t) .n = t##_##n
302
303#define enum_field_val(...) get_ovrd(__VA_ARGS__, enum_field_v3, enum_field_v2)(__VA_ARGS__),
304#define IMPL_ENUM(Enum, Values) \
305static const char* Enum##_name(int v) { \
306switch (v) { \
307Values(enum_case,Enum)\
308default: return "unknown " #Enum; \
309} \
310}\
311Enum Enum##_value_ofn(const char* s, size_t n) {\
312Values(enum_value_of, Enum, s, n) \
313return Enum##_Unknown; \
314} \
315Enum Enum##_value_of(const char* s) {\
316return Enum##_value_ofn(s, strlen(s)); \
317} \
318 \
319const struct Enum##_s Enum##s = { \
320.name = Enum##_name, \
321.value_of = Enum##_value_of, \
322.value_ofn = Enum##_value_ofn, \
323Values(enum_field_val,Enum)\
324}; \
325static int cmp_##Enum(const ptr(Enum) lh, const ptr(Enum) rh) { \
326return ((lh) ? (*lh) : Enum##_Unknown) - ((rh) ? (*rh) : Enum##_Unknown); \
327};\
328static int Enum##_json(const ptr(Enum) e, void *buf, int indent, int flags) { \
329return json_enum(e, buf, indent, flags, &Enum##s); \
330} \
331static int Enum##_from_json(ptr(Enum) e, struct json_object *j, type_meta *m) { \
332 return enum_from_json(e, j, &Enum##s); \
333} \
334static struct json_object* Enum##_to_json(const ptr(Enum) e) { \
335 return enum_to_json(e, &Enum##s); \
336}\
337static type_meta Enum##_meta = {\
338 .name = #Enum, \
339 .size = sizeof(Enum), \
340 .field_count = 0, \
341 .fields = NULL, \
342 .comparer = (_cmp_f) cmp_##Enum, \
343 .jsonifier = (_to_json_f) Enum##_json, \
344 .destroyer = NULL, \
345 .from_json = (from_json_func) Enum##_from_json, \
346 .to_json = (to_json_func) Enum##_to_json, \
347 }; \
348const type_meta* get_##Enum##_meta() { return &Enum##_meta; }\
349
350#if __cplusplus
351}
352#endif
353
354#endif //ZITI_SDK_MODEL_SUPPORT_H
#define ZITI_FUNC
Definition externs.h:38
struct json_object * enum_to_json(const void *ptr, const void *enum_type)
const char * model_string
Definition model_support.h:156
model_string * model_string_array
Definition model_support.h:158
ssize_t model_to_json_r(const void *obj, const type_meta *meta, int flags, char *outbuf, size_t max)
int(* _parse_f)(void *obj, const char *json, void *tok)
Definition model_support.h:182
int(* from_json_func)(void *obj, struct json_object *json, const struct type_meta *meta)
Definition model_support.h:187
int model_list_from_json(model_list *l, struct json_object *json, const type_meta *meta)
#define list(t)
Definition model_support.h:85
bool model_bool
Definition model_support.h:161
const type_meta * get_json_meta()
struct json_object *(* to_json_func)(const void *obj)
Definition model_support.h:188
int(* _to_json_f)(const void *obj, void *buf, int indent, int flags)
Definition model_support.h:183
_field_mod
Definition model_support.h:165
@ none_mod
Definition model_support.h:166
@ list_mod
Definition model_support.h:170
@ array_mod
Definition model_support.h:168
@ ptr_mod
Definition model_support.h:167
@ map_mod
Definition model_support.h:169
void model_free_array(void ***ap, const type_meta *meta)
const type_meta * get_model_string_meta()
model_number ** model_number_array
Definition model_support.h:160
int model_from_json(void *obj, struct json_object *json, const type_meta *meta)
#define ptr(t)
Definition model_support.h:82
char * model_to_json(const void *obj, const type_meta *meta, int flags, size_t *len)
void * model_alloc(const type_meta *meta)
int(* _cmp_f)(const void *lh, const void *rh)
Definition model_support.h:185
const type_meta * get_model_bool_meta()
model_bool ** model_bool_array
Definition model_support.h:162
int model_parse_array(void ***arp, const char *json, size_t len, const type_meta *meta)
const type_meta * get_model_number_meta()
int model_cmp(const void *lh, const void *rh, const type_meta *meta)
const type_meta * get_tag_meta()
struct timeval timestamp
Definition model_support.h:238
int64_t model_number
Definition model_support.h:159
int enum_from_json(void *ptr, struct json_object *j, const void *enum_type)
void(* _free_f)(void *obj)
Definition model_support.h:184
const type_meta * get_duration_meta()
const type_meta * get_timestamp_meta()
int model_parse(void *obj, const char *json, size_t len, const type_meta *meta)
int model_array_from_json(void ***obj, struct json_object *json, const type_meta *meta)
char * json
Definition model_support.h:163
tag_type
Definition model_support.h:242
@ tag_bool
Definition model_support.h:244
@ tag_null
Definition model_support.h:243
@ tag_string
Definition model_support.h:246
@ tag_number
Definition model_support.h:245
int model_parse_list(model_list *list, const char *json, size_t len, const type_meta *meta)
int json_enum(const void *ptr, void *buf, int indent, int flags, const void *enum_type)
void model_free(void *obj, const type_meta *meta)
int model_map_compare(const model_map *lh, const model_map *rh, const type_meta *m)
Definition model_support.h:173
enum _field_mod mod
Definition model_support.h:177
const char * path
Definition model_support.h:175
size_t offset
Definition model_support.h:176
const char * name
Definition model_support.h:174
Definition model_collections.h:97
Definition model_collections.h:29
Definition model_support.h:249
model_bool bool_value
Definition model_support.h:252
tag_type type
Definition model_support.h:250
model_string string_value
Definition model_support.h:254
model_number num_value
Definition model_support.h:253
Definition model_support.h:190
from_json_func from_json
Definition model_support.h:198
_free_f destroyer
Definition model_support.h:197
const int field_count
Definition model_support.h:193
field_meta * fields
Definition model_support.h:194
_to_json_f jsonifier
Definition model_support.h:196
size_t size
Definition model_support.h:192
to_json_func to_json
Definition model_support.h:199
const char * name
Definition model_support.h:191
_cmp_f comparer
Definition model_support.h:195