1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
|
/*
* Functions for manipulating HTS messages
* Copyright (C) 2007 Andreas Öman
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef HTSMSG_H_
#define HTSMSG_H_
#include <inttypes.h>
#include "htsq.h"
#define HTSMSG_ERR_FIELD_NOT_FOUND -1
#define HTSMSG_ERR_CONVERSION_IMPOSSIBLE -2
TAILQ_HEAD(htsmsg_field_queue, htsmsg_field);
typedef struct htsmsg {
/**
* fields
*/
struct htsmsg_field_queue hm_fields;
/**
* Set if this message is a list, otherwise it is a map.
*/
int hm_islist;
/**
* Data to be free'd when the message is destroyed
*/
const void *hm_data;
} htsmsg_t;
#define HMF_MAP 1
#define HMF_S64 2
#define HMF_STR 3
#define HMF_BIN 4
#define HMF_LIST 5
typedef struct htsmsg_field {
TAILQ_ENTRY(htsmsg_field) hmf_link;
const char *hmf_name;
uint8_t hmf_type;
uint8_t hmf_flags;
#define HMF_ALLOCED 0x1
#define HMF_NAME_ALLOCED 0x2
union {
int64_t s64;
const char *str;
struct {
const char *data;
size_t len;
} bin;
htsmsg_t msg;
} u;
} htsmsg_field_t;
#define hmf_s64 u.s64
#define hmf_msg u.msg
#define hmf_str u.str
#define hmf_bin u.bin.data
#define hmf_binsize u.bin.len
#define htsmsg_get_map_by_field(f) \
((f)->hmf_type == HMF_MAP ? &(f)->hmf_msg : NULL)
#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link)
/**
* Create a new map
*/
htsmsg_t *htsmsg_create_map(void);
/**
* Create a new list
*/
htsmsg_t *htsmsg_create_list(void);
/**
* Destroys a message (map or list)
*/
void htsmsg_destroy(htsmsg_t *msg);
/**
* Add an integer field where source is unsigned 32 bit.
*/
void htsmsg_add_u32(htsmsg_t *msg, const char *name, uint32_t u32);
/**
* Add an integer field where source is signed 32 bit.
*/
void htsmsg_add_s32(htsmsg_t *msg, const char *name, int32_t s32);
/**
* Add an integer field where source is signed 64 bit.
*/
void htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64);
/**
* Add a string field.
*/
void htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str);
/**
* Add an field where source is a list or map message.
*/
void htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub);
/**
* Add an field where source is a list or map message.
*
* This function will not strdup() \p name but relies on the caller
* to keep the string allocated for as long as the message is valid.
*/
void htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub);
/**
* Add an binary field. The data is copied to a malloced storage
*/
void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin,
size_t len);
/**
* Add an binary field. The data is not copied, instead the caller
* is responsible for keeping the data valid for as long as the message
* is around.
*/
void htsmsg_add_binptr(htsmsg_t *msg, const char *name, const void *bin,
size_t len);
/**
* Get an integer as an unsigned 32 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p);
/**
* Get an integer as an signed 32 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p);
/**
* Get an integer as an signed 64 bit integer.
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or
* out of range for the requested storage.
*/
int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p);
/**
* Get pointer to a binary field. No copying of data is performed.
*
* @param binp Pointer to a void * that will be filled in with a pointer
* to the data
* @param lenp Pointer to a size_t that will be filled with the size of
* the data
*
* @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist
* HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not a binary blob.
*/
int htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp,
size_t *lenp);
/**
* Get a field of type 'list'. No copying is done.
*
* @return NULL if the field can not be found or not of list type.
* Otherwise a htsmsg is returned.
*/
htsmsg_t *htsmsg_get_list(htsmsg_t *msg, const char *name);
/**
* Get a field of type 'string'. No copying is done.
*
* @return NULL if the field can not be found or not of string type.
* Otherwise a pointer to the data is returned.
*/
const char *htsmsg_get_str(htsmsg_t *msg, const char *name);
/**
* Get a field of type 'map'. No copying is done.
*
* @return NULL if the field can not be found or not of map type.
* Otherwise a htsmsg is returned.
*/
htsmsg_t *htsmsg_get_map(htsmsg_t *msg, const char *name);
/**
* Traverse a hierarchy of htsmsg's to find a specific child.
*/
htsmsg_t *htsmsg_get_map_multi(htsmsg_t *msg, ...);
/**
* Given the field \p f, return a string if it is of type string, otherwise
* return NULL
*/
const char *htsmsg_field_get_string(htsmsg_field_t *f);
/**
* Return the field \p name as an u32.
*
* @return An unsigned 32 bit integer or NULL if the field can not be found
* or if conversion is not possible.
*/
int htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def);
/**
* Remove the given field called \p name from the message \p msg.
*/
int htsmsg_delete_field(htsmsg_t *msg, const char *name);
/**
* Detach will remove the given field (and only if it is a list or map)
* from the message and make it a 'standalone message'. This means
* the the contents of the sub message will stay valid if the parent is
* destroyed. The caller is responsible for freeing this new message.
*/
htsmsg_t *htsmsg_detach_submsg(htsmsg_field_t *f);
/**
* Print a message to stdout.
*/
void htsmsg_print(htsmsg_t *msg);
/**
* Create a new field. Primarily intended for htsmsg internal functions.
*/
htsmsg_field_t *htsmsg_field_add(htsmsg_t *msg, const char *name,
int type, int flags);
/**
* Clone a message.
*/
htsmsg_t *htsmsg_copy(htsmsg_t *src);
#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link)
#endif /* HTSMSG_H_ */
|