1/*	$OpenBSD: mdesc.h,v 1.8 2019/07/14 14:40:55 kettenis Exp $	*/
2
3/*
4 * Copyright (c) 2012 Mark Kettenis
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/types.h>
20#include <sys/queue.h>
21#include <stdbool.h>
22
23struct md_header {
24	uint32_t	transport_version;
25	uint32_t	node_blk_sz;
26	uint32_t	name_blk_sz;
27	uint32_t	data_blk_sz;
28};
29
30#define MD_TRANSPORT_VERSION    0x10000
31
32#define MD_ALIGNMENT_SIZE	0x10
33
34#define MD_LIST_END	0
35#define MD_NODE		'N'
36#define MD_NODE_END	'E'
37#define MD_NOOP		' '
38#define MD_PROP_ARC	'a'
39#define MD_PROP_VAL	'v'
40#define MD_PROP_STR	's'
41#define MD_PROP_DATA	'd'
42
43struct md_element {
44	uint8_t		tag;
45	uint8_t		name_len;
46	uint16_t	_reserved_field;
47	uint32_t	name_offset;
48	union {
49		struct {
50			uint32_t	data_len;
51			uint32_t	data_offset;
52		} y;
53		uint64_t	val;
54	} d;
55};
56
57struct md {
58	TAILQ_HEAD(md_node_head, md_node) node_list;
59	TAILQ_HEAD(md_name_head, md_name) name_list;
60	TAILQ_HEAD(md_data_head, md_data) data_list;
61};
62
63struct md_node {
64	struct md_name *name;
65	TAILQ_HEAD(md_prop_head, md_prop) prop_list;
66
67	TAILQ_ENTRY(md_node) link;
68	uint64_t index;
69};
70
71struct md_prop {
72	struct md_name *name;
73	uint8_t tag;
74	union {
75		uint64_t val;
76		struct {
77			uint64_t index;
78			struct md_node *node;
79		} arc;
80		struct md_data *data;
81	} d;
82
83	TAILQ_ENTRY(md_prop) link;
84};
85
86struct md_name {
87	const char *str;
88
89	TAILQ_ENTRY(md_name) link;
90	uint32_t offset;
91	int refcnt;
92};
93
94struct md_data {
95	void *data;
96	size_t len;
97
98	TAILQ_ENTRY(md_data) link;
99	uint32_t offset;
100	int refcnt;
101};
102
103struct md_prop *md_add_prop(struct md *, struct md_node *, const char *);
104struct md_prop *md_add_prop_val(struct md *, struct md_node *,
105		    const char *, uint64_t);
106struct md_prop *md_add_prop_str(struct md *, struct md_node *,
107		    const char *, const char *);
108struct md_prop *md_add_prop_data(struct md *, struct md_node *,
109		    const char *, const uint8_t *, size_t);
110struct md_prop *md_add_prop_arc(struct md *, struct md_node *,
111		    const char *,struct md_node *);
112void md_delete_prop(struct md *, struct md_node *, struct md_prop *);
113
114struct md_node *md_find_node(struct md *, const char *);
115struct md_node *md_find_subnode(struct md *, struct md_node *, const char *);
116struct md_node *md_add_node(struct md *, const char *);
117void md_link_node(struct md *, struct md_node *, struct md_node *);
118struct md_prop *md_find_prop(struct md *, struct md_node *, const char *);
119
120bool md_get_prop_val(struct md *, struct md_node *, const char *, uint64_t *);
121bool md_set_prop_val(struct md *, struct md_node *, const char *, uint64_t);
122bool md_get_prop_str(struct md *, struct md_node *, const char *,
123    const char **);
124bool md_set_prop_data(struct md *, struct md_node *, const char *,
125    const uint8_t *, size_t);
126bool md_get_prop_data(struct md *, struct md_node *, const char *,
127    const void **, size_t *);
128
129void md_delete_node(struct md *, struct md_node *);
130void md_find_delete_node(struct md *, const char *);
131
132void md_collect_garbage(struct md *);
133
134struct md *md_alloc(void);
135struct md *md_ingest(void *, size_t);
136size_t md_exhume(struct md *md, void **);
137struct md *md_copy(struct md *);
138
139struct md *md_read(const char *);
140void md_write(struct md *, const char *);
141uint32_t md_size(const char *);
142