Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libcbor/src/cbor/data.h
39507 views
1
/*
2
* Copyright (c) 2014-2020 Pavel Kalvoda <[email protected]>
3
*
4
* libcbor is free software; you can redistribute it and/or modify
5
* it under the terms of the MIT license. See LICENSE for details.
6
*/
7
8
#ifndef LIBCBOR_DATA_H
9
#define LIBCBOR_DATA_H
10
11
#include <stdbool.h>
12
#include <stddef.h>
13
#include <stdint.h>
14
#include <stdlib.h>
15
16
#ifdef __cplusplus
17
extern "C" {
18
#endif
19
20
typedef const unsigned char* cbor_data;
21
typedef unsigned char* cbor_mutable_data;
22
23
/** Specifies the Major type of ::cbor_item_t */
24
typedef enum cbor_type {
25
CBOR_TYPE_UINT /** 0 - positive integers */
26
,
27
CBOR_TYPE_NEGINT /** 1 - negative integers*/
28
,
29
CBOR_TYPE_BYTESTRING /** 2 - byte strings */
30
,
31
CBOR_TYPE_STRING /** 3 - strings */
32
,
33
CBOR_TYPE_ARRAY /** 4 - arrays */
34
,
35
CBOR_TYPE_MAP /** 5 - maps */
36
,
37
CBOR_TYPE_TAG /** 6 - tags */
38
,
39
CBOR_TYPE_FLOAT_CTRL /** 7 - decimals and special values (true, false, nil,
40
...) */
41
} cbor_type;
42
43
/** Possible decoding errors */
44
typedef enum {
45
CBOR_ERR_NONE,
46
CBOR_ERR_NOTENOUGHDATA,
47
CBOR_ERR_NODATA,
48
// TODO: Should be "malformed" or at least "malformatted". Retained for
49
// backwards compatibility.
50
CBOR_ERR_MALFORMATED,
51
CBOR_ERR_MEMERROR /** Memory error - item allocation failed. Is it too big for
52
your allocator? */
53
,
54
CBOR_ERR_SYNTAXERROR /** Stack parsing algorithm failed */
55
} cbor_error_code;
56
57
/** Possible widths of #CBOR_TYPE_UINT items */
58
typedef enum {
59
CBOR_INT_8,
60
CBOR_INT_16,
61
CBOR_INT_32,
62
CBOR_INT_64
63
} cbor_int_width;
64
65
/** Possible widths of #CBOR_TYPE_FLOAT_CTRL items */
66
typedef enum {
67
CBOR_FLOAT_0 /** Internal use - ctrl and special values */
68
,
69
CBOR_FLOAT_16 /** Half float */
70
,
71
CBOR_FLOAT_32 /** Single float */
72
,
73
CBOR_FLOAT_64 /** Double */
74
} cbor_float_width;
75
76
/** Metadata for dynamically sized types */
77
typedef enum {
78
_CBOR_METADATA_DEFINITE,
79
_CBOR_METADATA_INDEFINITE
80
} _cbor_dst_metadata;
81
82
/** Semantic mapping for CTRL simple values */
83
typedef enum {
84
CBOR_CTRL_NONE = 0,
85
CBOR_CTRL_FALSE = 20,
86
CBOR_CTRL_TRUE = 21,
87
CBOR_CTRL_NULL = 22,
88
CBOR_CTRL_UNDEF = 23
89
} _cbor_ctrl;
90
91
// Metadata items use size_t (instead of uint64_t) because items in memory take
92
// up at least 1B per entry or string byte, so if size_t is narrower than
93
// uint64_t, we wouldn't be able to create them in the first place and can save
94
// some space.
95
96
/** Integers specific metadata */
97
struct _cbor_int_metadata {
98
cbor_int_width width;
99
};
100
101
/** Bytestrings specific metadata */
102
struct _cbor_bytestring_metadata {
103
size_t length;
104
_cbor_dst_metadata type;
105
};
106
107
/** Strings specific metadata */
108
struct _cbor_string_metadata {
109
size_t length;
110
size_t codepoint_count; /* Sum of chunks' codepoint_counts for indefinite
111
strings */
112
_cbor_dst_metadata type;
113
};
114
115
/** Arrays specific metadata */
116
struct _cbor_array_metadata {
117
size_t allocated;
118
size_t end_ptr;
119
_cbor_dst_metadata type;
120
};
121
122
/** Maps specific metadata */
123
struct _cbor_map_metadata {
124
size_t allocated;
125
size_t end_ptr;
126
_cbor_dst_metadata type;
127
};
128
129
/** Arrays specific metadata
130
*
131
* The pointer is included - cbor_item_metadata is
132
* 2 * sizeof(size_t) + sizeof(_cbor_string_type_metadata),
133
* lets use the space
134
*/
135
struct _cbor_tag_metadata {
136
struct cbor_item_t* tagged_item;
137
uint64_t value;
138
};
139
140
/** Floats specific metadata - includes CTRL values */
141
struct _cbor_float_ctrl_metadata {
142
cbor_float_width width;
143
uint8_t ctrl;
144
};
145
146
/** Raw memory casts helper */
147
union _cbor_float_helper {
148
float as_float;
149
uint32_t as_uint;
150
};
151
152
/** Raw memory casts helper */
153
union _cbor_double_helper {
154
double as_double;
155
uint64_t as_uint;
156
};
157
158
/** Union of metadata across all possible types - discriminated in #cbor_item_t
159
*/
160
union cbor_item_metadata {
161
struct _cbor_int_metadata int_metadata;
162
struct _cbor_bytestring_metadata bytestring_metadata;
163
struct _cbor_string_metadata string_metadata;
164
struct _cbor_array_metadata array_metadata;
165
struct _cbor_map_metadata map_metadata;
166
struct _cbor_tag_metadata tag_metadata;
167
struct _cbor_float_ctrl_metadata float_ctrl_metadata;
168
};
169
170
/** The item handle */
171
typedef struct cbor_item_t {
172
/** Discriminated by type */
173
union cbor_item_metadata metadata;
174
/** Reference count - initialize to 0 */
175
size_t refcount;
176
/** Major type discriminator */
177
cbor_type type;
178
/** Raw data block - interpretation depends on metadata */
179
unsigned char* data;
180
} cbor_item_t;
181
182
/** Defines cbor_item_t#data structure for indefinite strings and bytestrings
183
*
184
* Used to cast the raw representation for a sane manipulation
185
*/
186
struct cbor_indefinite_string_data {
187
size_t chunk_count;
188
size_t chunk_capacity;
189
cbor_item_t** chunks;
190
};
191
192
/** High-level decoding error */
193
struct cbor_error {
194
/** Approximate position */
195
size_t position;
196
/** Description */
197
cbor_error_code code;
198
};
199
200
/** Simple pair of items for use in maps */
201
struct cbor_pair {
202
cbor_item_t *key, *value;
203
};
204
205
/** High-level decoding result */
206
struct cbor_load_result {
207
/** Error indicator */
208
struct cbor_error error;
209
/** Number of bytes read */
210
size_t read;
211
};
212
213
/** Streaming decoder result - status */
214
enum cbor_decoder_status {
215
/** Decoding finished successfully (a callback has been invoked)
216
*
217
* Note that this does *not* mean that the buffer has been fully decoded;
218
* there may still be unread bytes for which no callback has been involved.
219
*/
220
CBOR_DECODER_FINISHED,
221
/** Not enough data to invoke a callback */
222
// TODO: The name is inconsistent with CBOR_ERR_NOTENOUGHDATA. Retained for
223
// backwards compatibility.
224
CBOR_DECODER_NEDATA,
225
/** Bad data (reserved MTB, malformed value, etc.) */
226
CBOR_DECODER_ERROR
227
};
228
229
/** Streaming decoder result */
230
struct cbor_decoder_result {
231
/** Input bytes read/consumed
232
*
233
* If this is less than the size of input buffer, the client will likely
234
* resume parsing starting at the next byte (e.g. `buffer + result.read`).
235
*
236
* Set to 0 if the #status is not #CBOR_DECODER_FINISHED.
237
*/
238
size_t read;
239
240
/** The decoding status */
241
enum cbor_decoder_status status;
242
243
/** Number of bytes in the input buffer needed to resume parsing
244
*
245
* Set to 0 unless the result status is #CBOR_DECODER_NEDATA. If it is, then:
246
* - If at least one byte was passed, #required will be set to the minimum
247
* number of bytes needed to invoke a decoded callback on the current
248
* prefix.
249
*
250
* For example: Attempting to decode a 1B buffer containing `0x19` will
251
* set #required to 3 as `0x19` signals a 2B integer item, so we need at
252
* least 3B to continue (the `0x19` MTB byte and two bytes of data needed
253
* to invoke #cbor_callbacks.uint16).
254
*
255
* - If there was no data at all, #read will always be set to 1
256
*/
257
size_t required;
258
};
259
260
#ifdef __cplusplus
261
}
262
#endif
263
264
#endif // LIBCBOR_DATA_H
265
266