 |
Software APIs
|
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"
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_WITH_PADDING(name_, decl_) \
123 status_t ujson_serialize_with_padding_##name_(ujson_t *uj, const name_ *self, size_t max_size) { \
124 size_t nfield = decl_(ujson_count, ujson_count); \
126 TRY(ujson_putbuf(uj, "{", 1)); \
127 decl_(ujson_ser_field, ujson_ser_string) \
128 if (max_size > uj->str_size + 1) { \
129 for (size_t i = 0; i < max_size - uj->str_size - 1; i++) { \
130 TRY(ujson_putbuf(uj, " ", 1)); \
133 TRY(ujson_putbuf(uj, "}", 1)); \
134 return OK_STATUS(); \
136 extern const int __never_referenced___here_to_eat_a_semicolon[]
138#define UJSON_IMPL_SERIALIZE_STRUCT(name_, decl_) \
139 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) { \
140 size_t nfield = decl_(ujson_count, ujson_count); \
141 TRY(ujson_putbuf(uj, "{", 1)); \
142 decl_(ujson_ser_field, ujson_ser_string) \
143 TRY(ujson_putbuf(uj, "}", 1)); \
144 return OK_STATUS(); \
146 extern const int __never_referenced___here_to_eat_a_semicolon[]
148#define ujson_ser_enum(formal_name_, name_, ...) \
149 case k ##formal_name_ ## name_: \
150 TRY(ujson_serialize_string(uj, #name_)); break;
152#define UJSON_IMPL_SERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
153 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) { \
155 decl_(formal_name_, ujson_ser_enum) \
157 const uint32_t value = (uint32_t)(*self); \
158 if (ujson_get_flags(__VA_ARGS__) & WITH_UNKNOWN) { \
159 TRY(ujson_serialize_uint32_t(uj, &value)); \
161 TRY(ujson_putbuf(uj, \
162 "{\"" RUST_ENUM_INTVALUE_STR "\":", \
163 sizeof("{\"" RUST_ENUM_INTVALUE_STR "\":") - 1)); \
164 TRY(ujson_serialize_uint32_t(uj, &value)); \
165 TRY(ujson_putbuf(uj, "}", 1)); \
169 return OK_STATUS(); \
171 extern const int __never_referenced___here_to_eat_a_semicolon[]
176#define ujson_de_loop_indirect() ujson_de_loop
177#define ujson_de_loop(mult, expr, count, ...) \
178 TRY(ujson_consume(uj, '[')); \
179 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
183 if (TRY(ujson_consume_maybe(uj, ']'))) break; \
184 if (i) TRY(ujson_consume(uj, ',')); \
185 if (i < count) { expr; ++i; } \
187 if (i < count) { p += (count - i) * mult; } \
189 for(size_t x=0;; ++x) { \
190 if (TRY(ujson_consume_maybe(uj, ']'))) break; \
191 if (x) TRY(ujson_consume(uj, ',')); \
192 OT_OBSTRUCT(ujson_de_loop_indirect)()(mult, expr, __VA_ARGS__) \
196#define ujson_de_field(name_, type_, ...) \
197 else if (ujson_streq(key, #name_)) { \
198 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
200 TRY(ujson_deserialize_##type_(uj, &self->name_)); \
202 type_ *p = (type_*)self->name_; \
203 OT_EVAL(ujson_de_loop(1, \
204 TRY(ujson_deserialize_##type_(uj, p++)), __VA_ARGS__)) \
208#define ujson_de_string(name_, size_, ...) \
209 else if (ujson_streq(key, #name_)) { \
210 OT_IIF(OT_NOT(OT_VA_ARGS_COUNT(dummy, ##__VA_ARGS__))) \
212 TRY(ujson_parse_qs(uj, self->name_, sizeof(self->name_))); \
214 char *p = (char*)self->name_; \
215 OT_EVAL(ujson_de_loop(size_, \
216 TRY(ujson_parse_qs(uj, p, sizeof(self->name_))); p+=size_, __VA_ARGS__)) \
220#define UJSON_IMPL_DESERIALIZE_STRUCT(name_, decl_) \
221 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) { \
225 TRY(ujson_consume(uj, '{')); \
226 while(TRY(ujson_consume_maybe(uj, '}')) == 0) { \
227 if (nfield++ > 0) { \
228 TRY(ujson_consume(uj, ',')); \
230 TRY(ujson_parse_qs(uj, key, sizeof(key))); \
231 TRY(ujson_consume(uj, ':')); \
233 decl_(ujson_de_field, ujson_de_string) \
235 return INVALID_ARGUMENT(); \
238 return OK_STATUS(); \
240 extern const int __never_referenced___here_to_eat_a_semicolon[]
242#define ujson_de_enum(formal_name_, name_, ...) \
243 else if (ujson_streq(value, #name_)) { *self = k ##formal_name_ ## name_; }
245#define UJSON_IMPL_DESERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
246 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) { \
249 if (TRY(ujson_consume_maybe(uj, '"'))) { \
250 TRY(ujson_ungetc(uj, '"')); \
251 TRY(ujson_parse_qs(uj, value, sizeof(value))); \
253 decl_(formal_name_, ujson_de_enum) \
255 return INVALID_ARGUMENT(); \
257 } else if(TRY(ujson_consume_maybe(uj, '{'))) { \
258 TRY(ujson_parse_qs(uj, value, sizeof(value))); \
259 TRY(ujson_consume(uj, ':')); \
260 if (ujson_streq(value, RUST_ENUM_INTVALUE_STR)) { \
261 TRY(ujson_deserialize_uint32_t(uj, (uint32_t*)self)); \
263 return INVALID_ARGUMENT(); \
265 TRY(ujson_consume(uj, '}')); \
267 TRY(ujson_deserialize_uint32_t(uj, (uint32_t*)self)); \
269 return OK_STATUS(); \
271 extern const int __never_referenced___here_to_eat_a_semicolon[]
273#ifndef UJSON_SERDE_IMPL
274#define UJSON_SERDE_IMPL 0
277#define UJSON_SERIALIZE_STRUCT(name_, decl_) \
278 OT_IIF(UJSON_SERDE_IMPL) \
280 UJSON_IMPL_SERIALIZE_STRUCT(name_, decl_) \
282 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) \
285#define UJSON_SERIALIZE_STRUCT_WITH_PADDING(name_, decl_) \
286 OT_IIF(UJSON_SERDE_IMPL) \
288 UJSON_IMPL_SERIALIZE_STRUCT_WITH_PADDING(name_, decl_) \
290 status_t ujson_serialize_with_padding_##name_(ujson_t *uj, const name_ *self, size_t max_size) \
293#define UJSON_SERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
294 OT_IIF(UJSON_SERDE_IMPL) \
296 UJSON_IMPL_SERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__) \
298 status_t ujson_serialize_##name_(ujson_t *uj, const name_ *self) \
301#define UJSON_DESERIALIZE_STRUCT(name_, decl_) \
302 OT_IIF(UJSON_SERDE_IMPL) \
304 UJSON_IMPL_DESERIALIZE_STRUCT(name_, decl_) \
306 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) \
309#define UJSON_DESERIALIZE_ENUM(formal_name_, name_, decl_, ...) \
310 OT_IIF(UJSON_SERDE_IMPL) \
312 UJSON_IMPL_DESERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__) \
314 status_t ujson_deserialize_##name_(ujson_t *uj, name_ *self) \
321#define UJSON_SERDE_STRUCT(formal_name_, name_, decl_, ...) \
322 UJSON_DECLARE_STRUCT(formal_name_, name_, decl_, ##__VA_ARGS__); \
323 UJSON_SERIALIZE_STRUCT(name_, decl_); \
324 UJSON_SERIALIZE_STRUCT_WITH_PADDING(name_, decl_); \
325 UJSON_DESERIALIZE_STRUCT(name_, decl_)
327#define UJSON_SERDE_ENUM(formal_name_, name_, decl_, ...) \
328 UJSON_DECLARE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__); \
329 UJSON_SERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__); \
330 UJSON_DESERIALIZE_ENUM(formal_name_, name_, decl_, ##__VA_ARGS__)
333#define RUST_ONLY(x) \
334 extern const int __never_referenced___here_to_eat_a_semicolon[]
337#include "sw/device/lib/ujson/ujson_rust.h"