#ifndef DTOB_H
#define DTOB_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define DTOB_CODE_OPEN 0
#define DTOB_CODE_ARR_CLOSE 1
#define DTOB_CODE_KV_CLOSE 2
#define DTOB_CODE_TYPES_CLOSE 3
#define DTOB_CODE_UQT 4
#define DTOB_CODE_RAW 5
#define DTOB_CODE_FLOAT 6
#define DTOB_CODE_DOUBLE 7
#define DTOB_CODE_INT8 8
#define DTOB_CODE_INT16 9
#define DTOB_CODE_INT32 10
#define DTOB_CODE_INT64 11
#define DTOB_CODE_UINT8 12
#define DTOB_CODE_UINT16 13
#define DTOB_CODE_UINT32 14
#define DTOB_CODE_UINT64 15
#define DTOB_CODE_BLAST 8191
#define DTOB_CUSTOM_MIN 16
#define DTOB_CUSTOM_MAX 8190
#define DTOB_IS_CTRL(b) (((b) & 0xC0) == 0xC0)
#define DTOB_MAGIC "13032026"
#define DTOB_MAGIC_LEN 8
#define DTOB_CODE_IS_INT(c) ((c) >= 8 && (c) <= 15)
#define DTOB_CODE_INT_UNSIGNED(c) (((c) - 8) & 4)
#define DTOB_CODE_INT_WIDTH(c) (1 << (((c) - 8) & 3))
typedef enum {
DTOB_ARRAY,
DTOB_KV_SET,
DTOB_INT,
DTOB_FLOAT,
DTOB_RAW,
DTOB_CUSTOM
} DtobType;
typedef struct DtobValue DtobValue;
typedef struct DtobKVPair DtobKVPair;
typedef struct {
uint16_t code;
char *name;
uint16_t opcodes[15];
size_t n_opcodes;
uint8_t is_struct;
} DtobCustomType;
typedef struct {
DtobCustomType *entries;
size_t count;
size_t cap;
} DtobTypesHeader;
struct DtobKVPair {
uint8_t *key;
size_t key_len;
DtobValue *value;
};
struct DtobValue {
DtobType type;
uint16_t custom_code;
uint16_t inner_code;
uint8_t *data;
size_t data_len;
DtobValue **elements;
size_t num_elements;
DtobKVPair *pairs;
size_t num_pairs;
};
typedef struct {
uint8_t *buf;
size_t cap;
size_t pos;
} DtobWriter;
void dtob_writer_init(DtobWriter *w);
void dtob_writer_byte(DtobWriter *w, uint8_t b);
void dtob_writer_ctrl(DtobWriter *w, uint16_t code);
void dtob_writer_data(DtobWriter *w, const uint8_t *bytes, size_t len);
void dtob_writer_value(DtobWriter *w, const DtobValue *v);
void dtob_writer_value_typed(DtobWriter *w, const DtobValue *v,
const DtobTypesHeader *types);
size_t dtob_trit_encode(const uint8_t *bytes, size_t byte_len,
uint8_t **out_buf);
size_t dtob_trit_decode(const uint8_t *buf, size_t buf_len,
uint8_t **out_bytes);
DtobValue *dtob_decode(const uint8_t *buf, size_t len);
DtobValue *dtob_decode_with_types(const uint8_t *buf, size_t len,
DtobTypesHeader *out_types);
uint8_t *dtob_encode(const DtobValue *root, size_t *out_len);
uint8_t *dtob_encode_with_types(const DtobValue *root,
const DtobTypesHeader *types,
int strict_validation,
size_t *out_len);
uint8_t *dtob_encode_chunk(const DtobValue *v,
const DtobTypesHeader *types,
int strict_validation,
size_t *out_len);
int dtob_verify_file_types(const char *path, const DtobTypesHeader *types, int strict);
DtobValue *dtob_int(int64_t val);
DtobValue *dtob_uint(uint64_t val);
DtobValue *dtob_float(double val);
DtobValue *dtob_raw(const uint8_t *data, size_t len);
DtobValue *dtob_array(void);
DtobValue *dtob_kvset(void);
DtobValue *dtob_custom(uint16_t code, const uint8_t *data, size_t len);
void dtob_array_push(DtobValue *arr, DtobValue *val);
void dtob_custom_push(DtobValue *custom, DtobValue *val);
void dtob_kvset_put(DtobValue *kvs, const char *key, DtobValue *val);
void dtob_types_init(DtobTypesHeader *th);
void dtob_types_cleanup(DtobTypesHeader *th);
int dtob_types_add(DtobTypesHeader *th, uint16_t code, const char *name,
const uint16_t *opcodes, size_t n_opcodes);
const char *dtob_types_lookup(const DtobTypesHeader *th, uint16_t code);
DtobCustomType *dtob_types_get(const DtobTypesHeader *th, uint16_t code);
int dtob_opcode_data_size(uint16_t opcode);
typedef struct DtobSchema DtobSchema;
DtobSchema *dtob_schema_new(void);
void dtob_schema_add(DtobSchema *s, const char *path, DtobType type);
void dtob_schema_free(DtobSchema *s);
DtobValue *dtob_from_json(const char *json, const DtobSchema *schema);
DtobValue *dtob_from_xml(const char *xml);
DtobValue *dtob_from_html(const char *html);
void dtob_free(DtobValue *val);
DtobValue *dtob_deep_copy(const DtobValue *val);
int64_t dtob_val_to_i64(const DtobValue *v);
uint64_t dtob_val_to_u64(const DtobValue *v);
size_t dtob_val_to_str(const DtobValue *v, char *out, size_t outsz);
DtobValue *dtob_kvset_get(const DtobValue *kvs, const char *key);
int64_t dtob_kvset_int(const DtobValue *kvs, const char *key);
uint64_t dtob_kvset_uint(const DtobValue *kvs, const char *key);
double dtob_kvset_float(const DtobValue *kvs, const char *key);
size_t dtob_kvset_str(const DtobValue *kvs, const char *key,
char *out, size_t outsz);
const uint8_t *dtob_kvset_raw(const DtobValue *kvs, const char *key,
size_t *out_len);
int dtob_array_append_to_file(const char *path, DtobValue *entry);
void dtob_print(const DtobValue *val, int indent);
void dtob_print_with_types(const DtobValue *val,
const DtobTypesHeader *th, int indent);
#ifdef __cplusplus
}
#endif
#endif