|  | 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(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"