#ifndef _MDESC_MUTABLE_H_
#define _MDESC_MUTABLE_H_
#ifdef DEBUG
#include <assert.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DEBUG
#define ASSERT(_s) assert(_s)
#else
#define ASSERT(_s)
#endif
#define MD_ALIGNMENT_SIZE 0x10
#define MD_OFFSET_UNDEF (uint32_t)-1
#define CHAIN(_type, _chain) \
struct { \
_type *startp; \
_type *endp; \
int count; \
} _chain
#define CHAIN_ITER(_chain, _itv) \
for ((_itv) = CHAIN_START(_chain); (_itv) != NULL; \
(_itv) = (_itv)->nextp)
#define CHAIN_START(_name) ((_name).startp)
#define CHAIN_LENGTH(_name) ((_name).count)
#define CHAIN_ADD(_chain, _nodep) \
do { \
if ((_chain).startp == NULL) { \
(_chain).startp = (_nodep); \
} else { \
(_chain).endp->nextp = (_nodep); \
} \
(_chain).endp = (_nodep); \
(_nodep)->nextp = NULL; \
(_chain).count++; \
NOTE(CONSTCOND) } while (0)
typedef struct md_string md_string_t;
typedef struct md_data_block md_data_block_t;
typedef struct md_prop md_prop_t;
typedef struct md_node md_node_t;
typedef struct mmd mmd_t;
struct md_string {
md_string_t *nextp;
char *strp;
int size;
uint32_t hash;
int ref_cnt;
uint32_t build_offset;
};
struct md_data_block {
md_data_block_t *nextp;
uint8_t *datap;
uint32_t size;
uint32_t hash;
int ref_cnt;
uint32_t build_offset;
};
struct md_prop {
uint8_t type;
md_string_t *sp;
union {
uint64_t value;
struct {
boolean_t is_ptr;
union {
uint64_t index;
md_node_t *nodep;
} val;
} arc;
md_data_block_t *dbp;
} d;
md_prop_t *nextp;
};
struct md_node {
md_string_t *typep;
CHAIN(md_prop_t, prop_list);
md_node_t *nextp;
int build_index;
int next_index;
char seen;
char deleted;
};
struct mmd {
CHAIN(md_node_t, node_list);
CHAIN(md_string_t, string_list);
CHAIN(md_data_block_t, data_block_list);
};
md_node_t *md_new_node(mmd_t *mdp, char *sp);
int md_add_value_property(mmd_t *mdp,
md_node_t *nodep, char *sp, uint64_t value);
int md_add_string_property(mmd_t *mdp, md_node_t *nodep, char *sp, char *bufp);
int md_add_data_property(mmd_t *mdp, md_node_t *nodep, char *sp, int len,
uint8_t *bufp);
int md_gen_bin(mmd_t *mdp, uint8_t **bufpp);
md_node_t *md_link_new_node(mmd_t *mdp, char *nodenamep, md_node_t *parentnodep,
char *linktonewp, char *linkbackp);
mmd_t *md_new_md(void);
void md_free_node(mmd_t *mdp, md_node_t *nodep);
void md_destroy(mmd_t *);
#ifdef __cplusplus
}
#endif
#endif