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