5 #ifndef OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_DERIVE_H_
6 #define OPENTITAN_SW_DEVICE_LIB_UJSON_UJSON_DERIVE_H_
9 #define RUST_ENUM_INTVALUE IntValue
11 #ifndef RUST_PREPROCESSOR_EMIT
14 #include "sw/device/lib/base/adv_macros.h"
15 #include "sw/device/lib/base/status.h"
16 #include "sw/device/lib/ujson/ujson.h"
21 #define WITH_UNKNOWN 1
22 #define RUST_ENUM_INTVALUE_STR OT_STRINGIFY(RUST_ENUM_INTVALUE)
27 #define ujson_get_flags(...) \
28 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
35 #define ujson_struct_field_array_indirect() ujson_struct_field_array
36 #define ujson_struct_field_array(nt_, sz_, ...) \
37 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
41 OT_OBSTRUCT(ujson_struct_field_array_indirect)()(nt_[sz_], __VA_ARGS__) \
44 #define ujson_struct_field(name_, type_, ...) \
45 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
49 OT_EVAL(ujson_struct_field_array(type_ name_, __VA_ARGS__)); \
52 #define ujson_struct_string(name_, size_, ...) \
53 ujson_struct_field(name_, char, ##__VA_ARGS__, size_)
55 #define UJSON_DECLARE_STRUCT(formal_name_, name_, decl_, ...) \
56 typedef struct formal_name_ { \
57 decl_(ujson_struct_field, ujson_struct_string) \
60 #define ujson_enum_value(formal_name_, name_, ...) \
61 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
63 k ##formal_name_ ## name_ \
65 k ##formal_name_ ## name_ = __VA_ARGS__ \
68 #define UJSON_DECLARE_ENUM(formal_name_, name_, decl_, ...) \
69 typedef enum formal_name_ { \
70 decl_(formal_name_, ujson_enum_value) \
75 #define ujson_count(name_, type_, ...) +1
80 #define ujson_ser_loop_indirect() ujson_ser_loop
81 #define ujson_ser_loop(expr, count, ...) \
82 TRY(ujson_putbuf(uj, "[", 1)); \
83 for(size_t x=0; x < count; ++x) { \
84 if (x) TRY(ujson_putbuf(uj, ",", 1)); \
85 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
89 OT_OBSTRUCT(ujson_ser_loop_indirect)()(expr, __VA_ARGS__) \
92 TRY(ujson_putbuf(uj, "]", 1));
94 #define ujson_ser_field(name_, type_, ...) { \
95 TRY(ujson_serialize_string(uj, #name_)); \
96 TRY(ujson_putbuf(uj, ":", 1)); \
97 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
99 TRY(ujson_serialize_##type_(uj, &self->name_)); \
101 const type_ *p = (const type_*)self->name_; \
102 OT_EVAL(ujson_ser_loop( \
103 TRY(ujson_serialize_##type_(uj, p++)), __VA_ARGS__)) \
105 if (--nfield) TRY(ujson_putbuf(uj, ",", 1)); \
108 #define ujson_ser_string(name_, size_, ...) { \
109 TRY(ujson_serialize_string(uj, #name_)); \
110 TRY(ujson_putbuf(uj, ":", 1)); \
111 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
113 TRY(ujson_serialize_string(uj, self->name_)); \
115 const char *p = (const char*)self->name_; \
116 OT_EVAL(ujson_ser_loop( \
117 TRY(ujson_serialize_string(uj, p)); p+=size_, __VA_ARGS__)) \
119 if (--nfield) TRY(ujson_putbuf(uj, ",", 1)); \
122 #define UJSON_IMPL_SERIALIZE_STRUCT(name_, decl_) \
123 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) { \
124 size_t nfield = decl_(ujson_count, ujson_count); \
125 TRY(ujson_putbuf(uj, "{", 1)); \
126 decl_(ujson_ser_field, ujson_ser_string) \
127 TRY(ujson_putbuf(uj, "}", 1)); \
128 return OK_STATUS(); \
130 extern const int __never_referenced___here_to_eat_a_semicolon[]
132 #define ujson_ser_enum(formal_name_, name_, ...) \
133 case k ##formal_name_ ## name_: \
134 TRY(ujson_serialize_string(uj, #name_)); break;
136 #define UJSON_IMPL_SERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
137 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) { \
139 decl_(formal_name_, ujson_ser_enum) \
141 const uint32_t value = (uint32_t)(*self); \
142 if (ujson_get_flags(__VA_ARGS__) & WITH_UNKNOWN) { \
143 TRY(ujson_serialize_uint32_t(uj, &value)); \
145 TRY(ujson_putbuf(uj, \
146 "{\"" RUST_ENUM_INTVALUE_STR "\":", \
147 sizeof("{\"" RUST_ENUM_INTVALUE_STR "\":") - 1)); \
148 TRY(ujson_serialize_uint32_t(uj, &value)); \
149 TRY(ujson_putbuf(uj, "}", 1)); \
153 return OK_STATUS(); \
155 extern const int __never_referenced___here_to_eat_a_semicolon[]
160 #define ujson_de_loop_indirect() ujson_de_loop
161 #define ujson_de_loop(mult, expr, count, ...) \
162 TRY(ujson_consume(uj, '[')); \
163 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
167 if (TRY(ujson_consume_maybe(uj, ']'))) break; \
168 if (i) TRY(ujson_consume(uj, ',')); \
169 if (i < count) { expr; ++i; } \
171 if (i < count) { p += (count - i) * mult; } \
173 for(size_t x=0;; ++x) { \
174 if (TRY(ujson_consume_maybe(uj, ']'))) break; \
175 if (x) TRY(ujson_consume(uj, ',')); \
176 OT_OBSTRUCT(ujson_de_loop_indirect)()(mult, expr, __VA_ARGS__) \
180 #define ujson_de_field(name_, type_, ...) \
181 else if (ujson_streq(key, #name_)) { \
182 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
184 TRY(ujson_deserialize_##type_(uj, &self->name_)); \
186 type_ *p = (type_*)self->name_; \
187 OT_EVAL(ujson_de_loop(1, \
188 TRY(ujson_deserialize_##type_(uj, p++)), __VA_ARGS__)) \
192 #define ujson_de_string(name_, size_, ...) \
193 else if (ujson_streq(key, #name_)) { \
194 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
196 TRY(ujson_parse_qs(uj, self->name_, sizeof(self->name_))); \
198 char *p = (char*)self->name_; \
199 OT_EVAL(ujson_de_loop(size_, \
200 TRY(ujson_parse_qs(uj, p, sizeof(self->name_))); p+=size_, __VA_ARGS__)) \
204 #define UJSON_IMPL_DESERIALIZE_STRUCT(name_, decl_) \
205 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) { \
208 TRY(ujson_consume(uj, '{')); \
209 while(TRY(ujson_consume_maybe(uj, '}')) == 0) { \
210 if (nfield++ > 0) { \
211 TRY(ujson_consume(uj, ',')); \
213 TRY(ujson_parse_qs(uj, key, sizeof(key))); \
214 TRY(ujson_consume(uj, ':')); \
216 decl_(ujson_de_field, ujson_de_string) \
218 return INVALID_ARGUMENT(); \
221 return OK_STATUS(); \
223 extern const int __never_referenced___here_to_eat_a_semicolon[]
225 #define ujson_de_enum(formal_name_, name_, ...) \
226 else if (ujson_streq(value, #name_)) { *self = k ##formal_name_ ## name_; }
228 #define UJSON_IMPL_DESERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
229 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) { \
231 if (TRY(ujson_consume_maybe(uj, '"'))) { \
232 TRY(ujson_ungetc(uj, '"')); \
233 TRY(ujson_parse_qs(uj, value, sizeof(value))); \
235 decl_(formal_name_, ujson_de_enum) \
237 return INVALID_ARGUMENT(); \
239 } else if(TRY(ujson_consume_maybe(uj, '{'))) { \
240 TRY(ujson_parse_qs(uj, value, sizeof(value))); \
241 TRY(ujson_consume(uj, ':')); \
242 if (ujson_streq(value, RUST_ENUM_INTVALUE_STR)) { \
243 TRY(ujson_deserialize_uint32_t(uj, (uint32_t*)self)); \
245 return INVALID_ARGUMENT(); \
247 TRY(ujson_consume(uj, '}')); \
249 TRY(ujson_deserialize_uint32_t(uj, (uint32_t*)self)); \
251 return OK_STATUS(); \
253 extern const int __never_referenced___here_to_eat_a_semicolon[]
255 #ifndef UJSON_SERDE_IMPL
256 #define UJSON_SERDE_IMPL 0
259 #define UJSON_SERIALIZE_STRUCT(name_, decl_) \
260 OT_IIF(UJSON_SERDE_IMPL) \
262 UJSON_IMPL_SERIALIZE_STRUCT(name_, decl_) \
264 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) \
267 #define UJSON_SERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
268 OT_IIF(UJSON_SERDE_IMPL) \
270 UJSON_IMPL_SERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__) \
272 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) \
275 #define UJSON_DESERIALIZE_STRUCT(name_, decl_) \
276 OT_IIF(UJSON_SERDE_IMPL) \
278 UJSON_IMPL_DESERIALIZE_STRUCT(name_, decl_) \
280 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) \
283 #define UJSON_DESERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
284 OT_IIF(UJSON_SERDE_IMPL) \
286 UJSON_IMPL_DESERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__) \
288 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) \
295 #define UJSON_SERDE_STRUCT(formal_name_, name_, decl_, ...) \
296 UJSON_DECLARE_STRUCT(formal_name_, name_, decl_, ##__VA_ARGS__); \
297 UJSON_SERIALIZE_STRUCT(name_, decl_); \
298 UJSON_DESERIALIZE_STRUCT(name_, decl_)
300 #define UJSON_SERDE_ENUM(formal_name_, name_, decl_, ...) \
301 UJSON_DECLARE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__); \
302 UJSON_SERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__); \
303 UJSON_DESERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__)
306 #define RUST_ONLY(x) \
307 extern const int __never_referenced___here_to_eat_a_semicolon[]
310 #include "sw/device/lib/ujson/ujson_rust.h"