1/*
2 * Copyright (c) 2015-2021 Nicholas Fraser and the MPack authors
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy of
5 * this software and associated documentation files (the "Software"), to deal in
6 * the Software without restriction, including without limitation the rights to
7 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8 * the Software, and to permit persons to whom the Software is furnished to do so,
9 * subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22/**
23 * @file
24 *
25 * Declares the MPack dynamic Node API.
26 */
27
28#ifndef MPACK_NODE_H
29#define MPACK_NODE_H 1
30
31#include "mpack-reader.h"
32
33MPACK_SILENCE_WARNINGS_BEGIN
34MPACK_EXTERN_C_BEGIN
35
36#if MPACK_NODE
37
38/**
39 * @defgroup node Node API
40 *
41 * The MPack Node API allows you to parse a chunk of MessagePack into a
42 * dynamically typed data structure, providing random access to the parsed
43 * data.
44 *
45 * See @ref docs/node.md for examples.
46 *
47 * @{
48 */
49
50/**
51 * A handle to node data in a parsed MPack tree.
52 *
53 * Nodes represent either primitive values or compound types. If a
54 * node is a compound type, it contains a pointer to its child nodes,
55 * or a pointer to its underlying data.
56 *
57 * Nodes are immutable.
58 *
59 * @note @ref mpack_node_t is an opaque reference to the node data, not the
60 * node data itself. (It contains pointers to both the node data and the tree.)
61 * It is passed by value in the Node API.
62 */
63typedef struct mpack_node_t mpack_node_t;
64
65/**
66 * The storage for nodes in an MPack tree.
67 *
68 * You only need to use this if you intend to provide your own storage
69 * for nodes instead of letting the tree allocate it.
70 *
71 * @ref mpack_node_data_t is 16 bytes on most common architectures (32-bit
72 * and 64-bit.)
73 */
74typedef struct mpack_node_data_t mpack_node_data_t;
75
76/**
77 * An MPack tree parser to parse a blob or stream of MessagePack.
78 *
79 * When a message is parsed, the tree contains a single root node which
80 * contains all parsed data. The tree and its nodes are immutable.
81 */
82typedef struct mpack_tree_t mpack_tree_t;
83
84/**
85 * An error handler function to be called when an error is flagged on
86 * the tree.
87 *
88 * The error handler will only be called once on the first error flagged;
89 * any subsequent node reads and errors are ignored, and the tree is
90 * permanently in that error state.
91 *
92 * MPack is safe against non-local jumps out of error handler callbacks.
93 * This means you are allowed to longjmp or throw an exception (in C++,
94 * Objective-C, or with SEH) out of this callback.
95 *
96 * Bear in mind when using longjmp that local non-volatile variables that
97 * have changed are undefined when setjmp() returns, so you can't put the
98 * tree on the stack in the same activation frame as the setjmp without
99 * declaring it volatile.
100 *
101 * You must still eventually destroy the tree. It is not destroyed
102 * automatically when an error is flagged. It is safe to destroy the
103 * tree within this error callback, but you will either need to perform
104 * a non-local jump, or store something in your context to identify
105 * that the tree is destroyed since any future accesses to it cause
106 * undefined behavior.
107 */
108typedef void (*mpack_tree_error_t)(mpack_tree_t* tree, mpack_error_t error);
109
110/**
111 * The MPack tree's read function. It should fill the buffer with as many bytes
112 * as are immediately available up to the given @c count, returning the number
113 * of bytes written to the buffer.
114 *
115 * In case of error, it should flag an appropriate error on the reader
116 * (usually @ref mpack_error_io.)
117 *
118 * The blocking or non-blocking behaviour of the read should match whether you
119 * are using mpack_tree_parse() or mpack_tree_try_parse().
120 *
121 * If you are using mpack_tree_parse(), the read should block until at least
122 * one byte is read. If you return 0, mpack_tree_parse() will raise @ref
123 * mpack_error_io.
124 *
125 * If you are using mpack_tree_try_parse(), the read function can always
126 * return 0, and must never block waiting for data (otherwise
127 * mpack_tree_try_parse() would be equivalent to mpack_tree_parse().)
128 * When you return 0, mpack_tree_try_parse() will return false without flagging
129 * an error.
130 */
131typedef size_t (*mpack_tree_read_t)(mpack_tree_t* tree, char* buffer, size_t count);
132
133/**
134 * A teardown function to be called when the tree is destroyed.
135 */
136typedef void (*mpack_tree_teardown_t)(mpack_tree_t* tree);
137
138
139
140/* Hide internals from documentation */
141/** @cond */
142
143struct mpack_node_t {
144 mpack_node_data_t* data;
145 mpack_tree_t* tree;
146};
147
148struct mpack_node_data_t {
149 mpack_type_t type;
150
151 /*
152 * The element count if the type is an array;
153 * the number of key/value pairs if the type is map;
154 * or the number of bytes if the type is str, bin or ext.
155 */
156 uint32_t len;
157
158 union {
159 bool b; /* The value if the type is bool. */
160
161 #if MPACK_FLOAT
162 float f; /* The value if the type is float. */
163 #else
164 uint32_t f; /*< The raw value if the type is float. */
165 #endif
166
167 #if MPACK_DOUBLE
168 double d; /* The value if the type is double. */
169 #else
170 uint64_t d; /*< The raw value if the type is double. */
171 #endif
172
173 int64_t i; /* The value if the type is signed int. */
174 uint64_t u; /* The value if the type is unsigned int. */
175 size_t offset; /* The byte offset for str, bin and ext */
176
177 mpack_node_data_t* children; /* The children for map or array */
178 } value;
179};
180
181typedef struct mpack_tree_page_t {
182 struct mpack_tree_page_t* next;
183 mpack_node_data_t nodes[1]; // variable size
184} mpack_tree_page_t;
185
186typedef enum mpack_tree_parse_state_t {
187 mpack_tree_parse_state_not_started,
188 mpack_tree_parse_state_in_progress,
189 mpack_tree_parse_state_parsed,
190} mpack_tree_parse_state_t;
191
192typedef struct mpack_level_t {
193 mpack_node_data_t* child;
194 size_t left; // children left in level
195} mpack_level_t;
196
197typedef struct mpack_tree_parser_t {
198 mpack_tree_parse_state_t state;
199
200 // We keep track of the number of "possible nodes" left in the data rather
201 // than the number of bytes.
202 //
203 // When a map or array is parsed, we ensure at least one byte for each child
204 // exists and subtract them right away. This ensures that if ever a map or
205 // array declares more elements than could possibly be contained in the data,
206 // we will error out immediately rather than allocating storage for them.
207 //
208 // For example malicious data that repeats 0xDE 0xFF 0xFF (start of a map
209 // with 65536 key-value pairs) would otherwise cause us to run out of
210 // memory. With this, the parser can allocate at most as many nodes as
211 // there are bytes in the data (plus the paging overhead, 12%.) An error
212 // will be flagged immediately if and when there isn't enough data left to
213 // fully read all children of all open compound types on the parsing stack.
214 //
215 // Once an entire message has been parsed (and there are no nodes left to
216 // parse whose bytes have been subtracted), this matches the number of left
217 // over bytes in the data.
218 size_t possible_nodes_left;
219
220 mpack_node_data_t* nodes; // next node in current page/pool
221 size_t nodes_left; // nodes left in current page/pool
222
223 size_t current_node_reserved;
224 size_t level;
225
226 #ifdef MPACK_MALLOC
227 // It's much faster to allocate the initial parsing stack inline within the
228 // parser. We replace it with a heap allocation if we need to grow it.
229 mpack_level_t* stack;
230 size_t stack_capacity;
231 bool stack_owned;
232 mpack_level_t stack_local[MPACK_NODE_INITIAL_DEPTH];
233 #else
234 // Without malloc(), we have to reserve a parsing stack the maximum allowed
235 // parsing depth.
236 mpack_level_t stack[MPACK_NODE_MAX_DEPTH_WITHOUT_MALLOC];
237 #endif
238} mpack_tree_parser_t;
239
240struct mpack_tree_t {
241 mpack_tree_error_t error_fn; /* Function to call on error */
242 mpack_tree_read_t read_fn; /* Function to call to read more data */
243 mpack_tree_teardown_t teardown; /* Function to teardown the context on destroy */
244 void* context; /* Context for tree callbacks */
245
246 mpack_node_data_t nil_node; /* a nil node to be returned in case of error */
247 mpack_node_data_t missing_node; /* a missing node to be returned in optional lookups */
248 mpack_error_t error;
249
250 #ifdef MPACK_MALLOC
251 char* buffer;
252 size_t buffer_capacity;
253 #endif
254
255 const char* data;
256 size_t data_length; // length of data (and content of buffer, if used)
257
258 size_t size; // size in bytes of tree (usually matches data_length, but not if tree has trailing data)
259 size_t node_count; // total number of nodes in tree (across all pages)
260
261 size_t max_size; // maximum message size
262 size_t max_nodes; // maximum nodes in a message
263
264 mpack_tree_parser_t parser;
265 mpack_node_data_t* root;
266
267 mpack_node_data_t* pool; // pool, or NULL if no pool provided
268 size_t pool_count;
269
270 #ifdef MPACK_MALLOC
271 mpack_tree_page_t* next;
272 #endif
273};
274
275// internal functions
276
277MPACK_INLINE mpack_node_t mpack_node(mpack_tree_t* tree, mpack_node_data_t* data) {
278 mpack_node_t node;
279 node.data = data;
280 node.tree = tree;
281 return node;
282}
283
284MPACK_INLINE mpack_node_data_t* mpack_node_child(mpack_node_t node, size_t child) {
285 return node.data->value.children + child;
286}
287
288MPACK_INLINE mpack_node_t mpack_tree_nil_node(mpack_tree_t* tree) {
289 return mpack_node(tree, &tree->nil_node);
290}
291
292MPACK_INLINE mpack_node_t mpack_tree_missing_node(mpack_tree_t* tree) {
293 return mpack_node(tree, &tree->missing_node);
294}
295
296/** @endcond */
297
298
299
300/**
301 * @name Tree Initialization
302 * @{
303 */
304
305#ifdef MPACK_MALLOC
306/**
307 * Initializes a tree parser with the given data.
308 *
309 * Configure the tree if desired, then call mpack_tree_parse() to parse it. The
310 * tree will allocate pages of nodes as needed and will free them when
311 * destroyed.
312 *
313 * The tree must be destroyed with mpack_tree_destroy().
314 *
315 * Any string or blob data types reference the original data, so the given data
316 * pointer must remain valid until after the tree is destroyed.
317 */
318void mpack_tree_init_data(mpack_tree_t* tree, const char* data, size_t length);
319
320/**
321 * Deprecated.
322 *
323 * \deprecated Renamed to mpack_tree_init_data().
324 */
325MPACK_INLINE void mpack_tree_init(mpack_tree_t* tree, const char* data, size_t length) {
326 mpack_tree_init_data(tree, data, length);
327}
328
329/**
330 * Initializes a tree parser from an unbounded stream, or a stream of
331 * unknown length.
332 *
333 * The parser can be used to read a single message from a stream of unknown
334 * length, or multiple messages from an unbounded stream, allowing it to
335 * be used for RPC communication. Call @ref mpack_tree_parse() to parse
336 * a message from a blocking stream, or @ref mpack_tree_try_parse() for a
337 * non-blocking stream.
338 *
339 * The stream will use a growable internal buffer to store the most recent
340 * message, as well as allocated pages of nodes for the parse tree.
341 *
342 * Maximum allowances for message size and node count must be specified in this
343 * function (since the stream is unbounded.) They can be changed later with
344 * @ref mpack_tree_set_limits().
345 *
346 * @param tree The tree parser
347 * @param read_fn The read function
348 * @param context The context for the read function
349 * @param max_message_size The maximum size of a message in bytes
350 * @param max_message_nodes The maximum number of nodes per message. See
351 * @ref mpack_node_data_t for the size of nodes.
352 *
353 * @see mpack_tree_read_t
354 * @see mpack_reader_context()
355 */
356void mpack_tree_init_stream(mpack_tree_t* tree, mpack_tree_read_t read_fn, void* context,
357 size_t max_message_size, size_t max_message_nodes);
358#endif
359
360/**
361 * Initializes a tree parser with the given data, using the given node data
362 * pool to store the results.
363 *
364 * Configure the tree if desired, then call mpack_tree_parse() to parse it.
365 *
366 * If the data does not fit in the pool, @ref mpack_error_too_big will be flagged
367 * on the tree.
368 *
369 * The tree must be destroyed with mpack_tree_destroy(), even if parsing fails.
370 */
371void mpack_tree_init_pool(mpack_tree_t* tree, const char* data, size_t length,
372 mpack_node_data_t* node_pool, size_t node_pool_count);
373
374/**
375 * Initializes an MPack tree directly into an error state. Use this if you
376 * are writing a wrapper to another <tt>mpack_tree_init*()</tt> function which
377 * can fail its setup.
378 */
379void mpack_tree_init_error(mpack_tree_t* tree, mpack_error_t error);
380
381#if MPACK_STDIO
382/**
383 * Initializes a tree to parse the given file. The tree must be destroyed with
384 * mpack_tree_destroy(), even if parsing fails.
385 *
386 * The file is opened, loaded fully into memory, and closed before this call
387 * returns.
388 *
389 * @param tree The tree to initialize
390 * @param filename The filename passed to fopen() to read the file
391 * @param max_bytes The maximum size of file to load, or 0 for unlimited size.
392 */
393void mpack_tree_init_filename(mpack_tree_t* tree, const char* filename, size_t max_bytes);
394
395/**
396 * Deprecated.
397 *
398 * \deprecated Renamed to mpack_tree_init_filename().
399 */
400MPACK_INLINE void mpack_tree_init_file(mpack_tree_t* tree, const char* filename, size_t max_bytes) {
401 mpack_tree_init_filename(tree, filename, max_bytes);
402}
403
404/**
405 * Initializes a tree to parse the given libc FILE. This can be used to
406 * read from stdin, or from a file opened separately.
407 *
408 * The tree must be destroyed with mpack_tree_destroy(), even if parsing fails.
409 *
410 * The FILE is fully loaded fully into memory (and closed if requested) before
411 * this call returns.
412 *
413 * @param tree The tree to initialize.
414 * @param stdfile The FILE.
415 * @param max_bytes The maximum size of file to load, or 0 for unlimited size.
416 * @param close_when_done If true, fclose() will be called on the FILE when it
417 * is no longer needed. If false, the file will not be closed when
418 * reading is done.
419 *
420 * @warning The tree will read all data in the FILE before parsing it. If this
421 * is used on stdin, the parser will block until it is closed, even if
422 * a complete message has been written to it!
423 */
424void mpack_tree_init_stdfile(mpack_tree_t* tree, FILE* stdfile, size_t max_bytes, bool close_when_done);
425#endif
426
427/**
428 * @}
429 */
430
431/**
432 * @name Tree Functions
433 * @{
434 */
435
436/**
437 * Sets the maximum byte size and maximum number of nodes allowed per message.
438 *
439 * The default is SIZE_MAX (no limit) unless @ref mpack_tree_init_stream() is
440 * called (where maximums are required.)
441 *
442 * If a pool of nodes is used, the node limit is the lesser of this limit and
443 * the pool size.
444 *
445 * @param tree The tree parser
446 * @param max_message_size The maximum size of a message in bytes
447 * @param max_message_nodes The maximum number of nodes per message. See
448 * @ref mpack_node_data_t for the size of nodes.
449 */
450void mpack_tree_set_limits(mpack_tree_t* tree, size_t max_message_size,
451 size_t max_message_nodes);
452
453/**
454 * Parses a MessagePack message into a tree of immutable nodes.
455 *
456 * If successful, the root node will be available under @ref mpack_tree_root().
457 * If not, an appropriate error will be flagged.
458 *
459 * This can be called repeatedly to parse a series of messages from a data
460 * source. When this is called, all previous nodes from this tree and their
461 * contents (including the root node) are invalidated.
462 *
463 * If this is called with a stream (see @ref mpack_tree_init_stream()), the
464 * stream must block until data is available. (Otherwise, if this is called on
465 * a non-blocking stream, parsing will fail with @ref mpack_error_io when the
466 * fill function returns 0.)
467 *
468 * There is no way to recover a tree in an error state. It must be destroyed.
469 */
470void mpack_tree_parse(mpack_tree_t* tree);
471
472/**
473 * Attempts to parse a MessagePack message from a non-blocking stream into a
474 * tree of immutable nodes.
475 *
476 * A non-blocking read function must have been passed to the tree in
477 * mpack_tree_init_stream().
478 *
479 * If this returns true, a message is available under
480 * @ref mpack_tree_root(). The tree nodes and data will be valid until
481 * the next time a parse is started.
482 *
483 * If this returns false, no message is available, because either not enough
484 * data is available yet or an error has occurred. You must check the tree for
485 * errors whenever this returns false. If there is no error, you should try
486 * again later when more data is available. (You will want to select()/poll()
487 * on the underlying socket or use some other asynchronous mechanism to
488 * determine when it has data.)
489 *
490 * There is no way to recover a tree in an error state. It must be destroyed.
491 *
492 * @see mpack_tree_init_stream()
493 */
494bool mpack_tree_try_parse(mpack_tree_t* tree);
495
496/**
497 * Returns the root node of the tree, if the tree is not in an error state.
498 * Returns a nil node otherwise.
499 *
500 * @warning You must call mpack_tree_parse() before calling this. If
501 * @ref mpack_tree_parse() was never called, the tree will assert.
502 */
503mpack_node_t mpack_tree_root(mpack_tree_t* tree);
504
505/**
506 * Returns the error state of the tree.
507 */
508MPACK_INLINE mpack_error_t mpack_tree_error(mpack_tree_t* tree) {
509 return tree->error;
510}
511
512/**
513 * Returns the size in bytes of the current parsed message.
514 *
515 * If there is something in the buffer after the MessagePack object, this can
516 * be used to find it.
517 *
518 * This is zero if an error occurred during tree parsing (since the
519 * portion of the data that the first complete object occupies cannot
520 * be determined if the data is invalid or corrupted.)
521 */
522MPACK_INLINE size_t mpack_tree_size(mpack_tree_t* tree) {
523 return tree->size;
524}
525
526/**
527 * Destroys the tree.
528 */
529mpack_error_t mpack_tree_destroy(mpack_tree_t* tree);
530
531/**
532 * Sets the custom pointer to pass to the tree callbacks, such as teardown.
533 *
534 * @param tree The MPack tree.
535 * @param context User data to pass to the tree callbacks.
536 *
537 * @see mpack_reader_context()
538 */
539MPACK_INLINE void mpack_tree_set_context(mpack_tree_t* tree, void* context) {
540 tree->context = context;
541}
542
543/**
544 * Returns the custom context for tree callbacks.
545 *
546 * @see mpack_tree_set_context
547 * @see mpack_tree_init_stream
548 */
549MPACK_INLINE void* mpack_tree_context(mpack_tree_t* tree) {
550 return tree->context;
551}
552
553/**
554 * Sets the error function to call when an error is flagged on the tree.
555 *
556 * This should normally be used with mpack_tree_set_context() to register
557 * a custom pointer to pass to the error function.
558 *
559 * See the definition of mpack_tree_error_t for more information about
560 * what you can do from an error callback.
561 *
562 * @see mpack_tree_error_t
563 * @param tree The MPack tree.
564 * @param error_fn The function to call when an error is flagged on the tree.
565 */
566MPACK_INLINE void mpack_tree_set_error_handler(mpack_tree_t* tree, mpack_tree_error_t error_fn) {
567 tree->error_fn = error_fn;
568}
569
570/**
571 * Sets the teardown function to call when the tree is destroyed.
572 *
573 * This should normally be used with mpack_tree_set_context() to register
574 * a custom pointer to pass to the teardown function.
575 *
576 * @param tree The MPack tree.
577 * @param teardown The function to call when the tree is destroyed.
578 */
579MPACK_INLINE void mpack_tree_set_teardown(mpack_tree_t* tree, mpack_tree_teardown_t teardown) {
580 tree->teardown = teardown;
581}
582
583/**
584 * Places the tree in the given error state, calling the error callback if one
585 * is set.
586 *
587 * This allows you to externally flag errors, for example if you are validating
588 * data as you read it.
589 *
590 * If the tree is already in an error state, this call is ignored and no
591 * error callback is called.
592 */
593void mpack_tree_flag_error(mpack_tree_t* tree, mpack_error_t error);
594
595/**
596 * @}
597 */
598
599/**
600 * @name Node Core Functions
601 * @{
602 */
603
604/**
605 * Places the node's tree in the given error state, calling the error callback
606 * if one is set.
607 *
608 * This allows you to externally flag errors, for example if you are validating
609 * data as you read it.
610 *
611 * If the tree is already in an error state, this call is ignored and no
612 * error callback is called.
613 */
614void mpack_node_flag_error(mpack_node_t node, mpack_error_t error);
615
616/**
617 * Returns the error state of the node's tree.
618 */
619MPACK_INLINE mpack_error_t mpack_node_error(mpack_node_t node) {
620 return mpack_tree_error(node.tree);
621}
622
623/**
624 * Returns a tag describing the given node, or a nil tag if the
625 * tree is in an error state.
626 */
627mpack_tag_t mpack_node_tag(mpack_node_t node);
628
629/** @cond */
630
631#if MPACK_DEBUG && MPACK_STDIO
632/*
633 * Converts a node to a pseudo-JSON string for debugging purposes, placing the
634 * result in the given buffer with a null-terminator.
635 *
636 * If the buffer does not have enough space, the result will be truncated (but
637 * it is guaranteed to be null-terminated.)
638 *
639 * This is only available in debug mode, and only if stdio is available (since
640 * it uses snprintf().) It's strictly for debugging purposes.
641 */
642void mpack_node_print_to_buffer(mpack_node_t node, char* buffer, size_t buffer_size);
643
644/*
645 * Converts a node to pseudo-JSON for debugging purposes, calling the given
646 * callback as many times as is necessary to output the character data.
647 *
648 * No null-terminator or trailing newline will be written.
649 *
650 * This is only available in debug mode, and only if stdio is available (since
651 * it uses snprintf().) It's strictly for debugging purposes.
652 */
653void mpack_node_print_to_callback(mpack_node_t node, mpack_print_callback_t callback, void* context);
654
655/*
656 * Converts a node to pseudo-JSON for debugging purposes
657 * and pretty-prints it to the given file.
658 *
659 * This is only available in debug mode, and only if stdio is available (since
660 * it uses snprintf().) It's strictly for debugging purposes.
661 */
662void mpack_node_print_to_file(mpack_node_t node, FILE* file);
663
664/*
665 * Converts a node to pseudo-JSON for debugging purposes
666 * and pretty-prints it to stdout.
667 *
668 * This is only available in debug mode, and only if stdio is available (since
669 * it uses snprintf().) It's strictly for debugging purposes.
670 */
671MPACK_INLINE void mpack_node_print_to_stdout(mpack_node_t node) {
672 mpack_node_print_to_file(node, stdout);
673}
674
675/*
676 * Deprecated.
677 *
678 * \deprecated Renamed to mpack_node_print_to_stdout().
679 */
680MPACK_INLINE void mpack_node_print(mpack_node_t node) {
681 mpack_node_print_to_stdout(node);
682}
683#endif
684
685/** @endcond */
686
687/**
688 * @}
689 */
690
691/**
692 * @name Node Primitive Value Functions
693 * @{
694 */
695
696/**
697 * Returns the type of the node.
698 */
699mpack_type_t mpack_node_type(mpack_node_t node);
700
701/**
702 * Returns true if the given node is a nil node; false otherwise.
703 *
704 * To ensure that a node is nil and flag an error otherwise, use
705 * mpack_node_nil().
706 */
707bool mpack_node_is_nil(mpack_node_t node);
708
709/**
710 * Returns true if the given node handle indicates a missing node; false otherwise.
711 *
712 * To ensure that a node is missing and flag an error otherwise, use
713 * mpack_node_missing().
714 */
715bool mpack_node_is_missing(mpack_node_t node);
716
717/**
718 * Checks that the given node is of nil type, raising @ref mpack_error_type
719 * otherwise.
720 *
721 * Use mpack_node_is_nil() to return whether the node is nil.
722 */
723void mpack_node_nil(mpack_node_t node);
724
725/**
726 * Checks that the given node indicates a missing node, raising @ref
727 * mpack_error_type otherwise.
728 *
729 * Use mpack_node_is_missing() to return whether the node is missing.
730 */
731void mpack_node_missing(mpack_node_t node);
732
733/**
734 * Returns the bool value of the node. If this node is not of the correct
735 * type, false is returned and mpack_error_type is raised.
736 */
737bool mpack_node_bool(mpack_node_t node);
738
739/**
740 * Checks if the given node is of bool type with value true, raising
741 * mpack_error_type otherwise.
742 */
743void mpack_node_true(mpack_node_t node);
744
745/**
746 * Checks if the given node is of bool type with value false, raising
747 * mpack_error_type otherwise.
748 */
749void mpack_node_false(mpack_node_t node);
750
751/**
752 * Returns the 8-bit unsigned value of the node. If this node is not
753 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
754 */
755uint8_t mpack_node_u8(mpack_node_t node);
756
757/**
758 * Returns the 8-bit signed value of the node. If this node is not
759 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
760 */
761int8_t mpack_node_i8(mpack_node_t node);
762
763/**
764 * Returns the 16-bit unsigned value of the node. If this node is not
765 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
766 */
767uint16_t mpack_node_u16(mpack_node_t node);
768
769/**
770 * Returns the 16-bit signed value of the node. If this node is not
771 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
772 */
773int16_t mpack_node_i16(mpack_node_t node);
774
775/**
776 * Returns the 32-bit unsigned value of the node. If this node is not
777 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
778 */
779uint32_t mpack_node_u32(mpack_node_t node);
780
781/**
782 * Returns the 32-bit signed value of the node. If this node is not
783 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
784 */
785int32_t mpack_node_i32(mpack_node_t node);
786
787/**
788 * Returns the 64-bit unsigned value of the node. If this node is not
789 * of a compatible type, @ref mpack_error_type is raised, and zero is returned.
790 */
791uint64_t mpack_node_u64(mpack_node_t node);
792
793/**
794 * Returns the 64-bit signed value of the node. If this node is not
795 * of a compatible type, @ref mpack_error_type is raised and zero is returned.
796 */
797int64_t mpack_node_i64(mpack_node_t node);
798
799/**
800 * Returns the unsigned int value of the node.
801 *
802 * Returns zero if an error occurs.
803 *
804 * @throws mpack_error_type If the node is not an integer type or does not fit in the range of an unsigned int
805 */
806unsigned int mpack_node_uint(mpack_node_t node);
807
808/**
809 * Returns the int value of the node.
810 *
811 * Returns zero if an error occurs.
812 *
813 * @throws mpack_error_type If the node is not an integer type or does not fit in the range of an int
814 */
815int mpack_node_int(mpack_node_t node);
816
817#if MPACK_FLOAT
818/**
819 * Returns the float value of the node. The underlying value can be an
820 * integer, float or double; the value is converted to a float.
821 *
822 * @note Reading a double or a large integer with this function can incur a
823 * loss of precision.
824 *
825 * @throws mpack_error_type if the underlying value is not a float, double or integer.
826 */
827float mpack_node_float(mpack_node_t node);
828#endif
829
830#if MPACK_DOUBLE
831/**
832 * Returns the double value of the node. The underlying value can be an
833 * integer, float or double; the value is converted to a double.
834 *
835 * @note Reading a very large integer with this function can incur a
836 * loss of precision.
837 *
838 * @throws mpack_error_type if the underlying value is not a float, double or integer.
839 */
840double mpack_node_double(mpack_node_t node);
841#endif
842
843#if MPACK_FLOAT
844/**
845 * Returns the float value of the node. The underlying value must be a float,
846 * not a double or an integer. This ensures no loss of precision can occur.
847 *
848 * @throws mpack_error_type if the underlying value is not a float.
849 */
850float mpack_node_float_strict(mpack_node_t node);
851#endif
852
853#if MPACK_DOUBLE
854/**
855 * Returns the double value of the node. The underlying value must be a float
856 * or double, not an integer. This ensures no loss of precision can occur.
857 *
858 * @throws mpack_error_type if the underlying value is not a float or double.
859 */
860double mpack_node_double_strict(mpack_node_t node);
861#endif
862
863#if !MPACK_FLOAT
864/**
865 * Returns the float value of the node as a raw uint32_t. The underlying value
866 * must be a float, not a double or an integer.
867 *
868 * @throws mpack_error_type if the underlying value is not a float.
869 */
870uint32_t mpack_node_raw_float(mpack_node_t node);
871#endif
872
873#if !MPACK_DOUBLE
874/**
875 * Returns the double value of the node as a raw uint64_t. The underlying value
876 * must be a double, not a float or an integer.
877 *
878 * @throws mpack_error_type if the underlying value is not a float or double.
879 */
880uint64_t mpack_node_raw_double(mpack_node_t node);
881#endif
882
883
884#if MPACK_EXTENSIONS
885/**
886 * Returns a timestamp.
887 *
888 * @note This requires @ref MPACK_EXTENSIONS.
889 *
890 * @throws mpack_error_type if the underlying value is not a timestamp.
891 */
892mpack_timestamp_t mpack_node_timestamp(mpack_node_t node);
893
894/**
895 * Returns a timestamp's (signed) seconds since 1970-01-01T00:00:00Z.
896 *
897 * @note This requires @ref MPACK_EXTENSIONS.
898 *
899 * @throws mpack_error_type if the underlying value is not a timestamp.
900 */
901int64_t mpack_node_timestamp_seconds(mpack_node_t node);
902
903/**
904 * Returns a timestamp's additional nanoseconds.
905 *
906 * @note This requires @ref MPACK_EXTENSIONS.
907 *
908 * @return A nanosecond count between 0 and 999,999,999 inclusive.
909 * @throws mpack_error_type if the underlying value is not a timestamp.
910 */
911uint32_t mpack_node_timestamp_nanoseconds(mpack_node_t node);
912#endif
913
914/**
915 * @}
916 */
917
918/**
919 * @name Node String and Data Functions
920 * @{
921 */
922
923/**
924 * Checks that the given node contains a valid UTF-8 string.
925 *
926 * If the string is invalid, this flags an error, which would cause subsequent calls
927 * to mpack_node_str() to return NULL and mpack_node_strlen() to return zero. So you
928 * can check the node for error immediately after calling this, or you can call those
929 * functions to use the data anyway and check for errors later.
930 *
931 * @throws mpack_error_type If this node is not a string or does not contain valid UTF-8.
932 *
933 * @param node The string node to test
934 *
935 * @see mpack_node_str()
936 * @see mpack_node_strlen()
937 */
938void mpack_node_check_utf8(mpack_node_t node);
939
940/**
941 * Checks that the given node contains a valid UTF-8 string with no NUL bytes.
942 *
943 * This does not check that the string has a null-terminator! It only checks whether
944 * the string could safely be represented as a C-string by appending a null-terminator.
945 * (If the string does already contain a null-terminator, this will flag an error.)
946 *
947 * This is performed automatically by other UTF-8 cstr helper functions. Only
948 * call this if you will do something else with the data directly, but you still
949 * want to ensure it will be valid as a UTF-8 C-string.
950 *
951 * @throws mpack_error_type If this node is not a string, does not contain valid UTF-8,
952 * or contains a NUL byte.
953 *
954 * @param node The string node to test
955 *
956 * @see mpack_node_str()
957 * @see mpack_node_strlen()
958 * @see mpack_node_copy_utf8_cstr()
959 * @see mpack_node_utf8_cstr_alloc()
960 */
961void mpack_node_check_utf8_cstr(mpack_node_t node);
962
963#if MPACK_EXTENSIONS
964/**
965 * Returns the extension type of the given ext node.
966 *
967 * This returns zero if the tree is in an error state.
968 *
969 * @note This requires @ref MPACK_EXTENSIONS.
970 */
971int8_t mpack_node_exttype(mpack_node_t node);
972#endif
973
974/**
975 * Returns the number of bytes in the given bin node.
976 *
977 * This returns zero if the tree is in an error state.
978 *
979 * If this node is not a bin, @ref mpack_error_type is raised and zero is returned.
980 */
981size_t mpack_node_bin_size(mpack_node_t node);
982
983/**
984 * Returns the length of the given str, bin or ext node.
985 *
986 * This returns zero if the tree is in an error state.
987 *
988 * If this node is not a str, bin or ext, @ref mpack_error_type is raised and zero
989 * is returned.
990 */
991uint32_t mpack_node_data_len(mpack_node_t node);
992
993/**
994 * Returns the length in bytes of the given string node. This does not
995 * include any null-terminator.
996 *
997 * This returns zero if the tree is in an error state.
998 *
999 * If this node is not a str, @ref mpack_error_type is raised and zero is returned.
1000 */
1001size_t mpack_node_strlen(mpack_node_t node);
1002
1003/**
1004 * Returns a pointer to the data contained by this node, ensuring the node is a
1005 * string.
1006 *
1007 * @warning Strings are not null-terminated! Use one of the cstr functions
1008 * to get a null-terminated string.
1009 *
1010 * The pointer is valid as long as the data backing the tree is valid.
1011 *
1012 * If this node is not a string, @ref mpack_error_type is raised and @c NULL is returned.
1013 *
1014 * @see mpack_node_copy_cstr()
1015 * @see mpack_node_cstr_alloc()
1016 * @see mpack_node_utf8_cstr_alloc()
1017 */
1018const char* mpack_node_str(mpack_node_t node);
1019
1020/**
1021 * Returns a pointer to the data contained by this node.
1022 *
1023 * @note Strings are not null-terminated! Use one of the cstr functions
1024 * to get a null-terminated string.
1025 *
1026 * The pointer is valid as long as the data backing the tree is valid.
1027 *
1028 * If this node is not of a str, bin or ext, @ref mpack_error_type is raised, and
1029 * @c NULL is returned.
1030 *
1031 * @see mpack_node_copy_cstr()
1032 * @see mpack_node_cstr_alloc()
1033 * @see mpack_node_utf8_cstr_alloc()
1034 */
1035const char* mpack_node_data(mpack_node_t node);
1036
1037/**
1038 * Returns a pointer to the data contained by this bin node.
1039 *
1040 * The pointer is valid as long as the data backing the tree is valid.
1041 *
1042 * If this node is not a bin, @ref mpack_error_type is raised and @c NULL is
1043 * returned.
1044 */
1045const char* mpack_node_bin_data(mpack_node_t node);
1046
1047/**
1048 * Copies the bytes contained by this node into the given buffer, returning the
1049 * number of bytes in the node.
1050 *
1051 * @throws mpack_error_type If this node is not a str, bin or ext type
1052 * @throws mpack_error_too_big If the string does not fit in the given buffer
1053 *
1054 * @param node The string node from which to copy data
1055 * @param buffer A buffer in which to copy the node's bytes
1056 * @param bufsize The size of the given buffer
1057 *
1058 * @return The number of bytes in the node, or zero if an error occurs.
1059 */
1060size_t mpack_node_copy_data(mpack_node_t node, char* buffer, size_t bufsize);
1061
1062/**
1063 * Checks that the given node contains a valid UTF-8 string and copies the
1064 * string into the given buffer, returning the number of bytes in the string.
1065 *
1066 * @throws mpack_error_type If this node is not a string
1067 * @throws mpack_error_too_big If the string does not fit in the given buffer
1068 *
1069 * @param node The string node from which to copy data
1070 * @param buffer A buffer in which to copy the node's bytes
1071 * @param bufsize The size of the given buffer
1072 *
1073 * @return The number of bytes in the node, or zero if an error occurs.
1074 */
1075size_t mpack_node_copy_utf8(mpack_node_t node, char* buffer, size_t bufsize);
1076
1077/**
1078 * Checks that the given node contains a string with no NUL bytes, copies the string
1079 * into the given buffer, and adds a null terminator.
1080 *
1081 * If this node is not of a string type, @ref mpack_error_type is raised. If the string
1082 * does not fit, @ref mpack_error_data is raised.
1083 *
1084 * If any error occurs, the buffer will contain an empty null-terminated string.
1085 *
1086 * @param node The string node from which to copy data
1087 * @param buffer A buffer in which to copy the node's string
1088 * @param size The size of the given buffer
1089 */
1090void mpack_node_copy_cstr(mpack_node_t node, char* buffer, size_t size);
1091
1092/**
1093 * Checks that the given node contains a valid UTF-8 string with no NUL bytes,
1094 * copies the string into the given buffer, and adds a null terminator.
1095 *
1096 * If this node is not of a string type, @ref mpack_error_type is raised. If the string
1097 * does not fit, @ref mpack_error_data is raised.
1098 *
1099 * If any error occurs, the buffer will contain an empty null-terminated string.
1100 *
1101 * @param node The string node from which to copy data
1102 * @param buffer A buffer in which to copy the node's string
1103 * @param size The size of the given buffer
1104 */
1105void mpack_node_copy_utf8_cstr(mpack_node_t node, char* buffer, size_t size);
1106
1107#ifdef MPACK_MALLOC
1108/**
1109 * Allocates a new chunk of data using MPACK_MALLOC() with the bytes
1110 * contained by this node.
1111 *
1112 * The allocated data must be freed with MPACK_FREE() (or simply free()
1113 * if MPack's allocator hasn't been customized.)
1114 *
1115 * @throws mpack_error_type If this node is not a str, bin or ext type
1116 * @throws mpack_error_too_big If the size of the data is larger than the
1117 * given maximum size
1118 * @throws mpack_error_memory If an allocation failure occurs
1119 *
1120 * @param node The node from which to allocate and copy data
1121 * @param maxsize The maximum size to allocate
1122 *
1123 * @return The allocated data, or NULL if any error occurs.
1124 */
1125char* mpack_node_data_alloc(mpack_node_t node, size_t maxsize);
1126
1127/**
1128 * Allocates a new null-terminated string using MPACK_MALLOC() with the string
1129 * contained by this node.
1130 *
1131 * The allocated string must be freed with MPACK_FREE() (or simply free()
1132 * if MPack's allocator hasn't been customized.)
1133 *
1134 * @throws mpack_error_type If this node is not a string or contains NUL bytes
1135 * @throws mpack_error_too_big If the size of the string plus null-terminator
1136 * is larger than the given maximum size
1137 * @throws mpack_error_memory If an allocation failure occurs
1138 *
1139 * @param node The node from which to allocate and copy string data
1140 * @param maxsize The maximum size to allocate, including the null-terminator
1141 *
1142 * @return The allocated string, or NULL if any error occurs.
1143 */
1144char* mpack_node_cstr_alloc(mpack_node_t node, size_t maxsize);
1145
1146/**
1147 * Allocates a new null-terminated string using MPACK_MALLOC() with the UTF-8
1148 * string contained by this node.
1149 *
1150 * The allocated string must be freed with MPACK_FREE() (or simply free()
1151 * if MPack's allocator hasn't been customized.)
1152 *
1153 * @throws mpack_error_type If this node is not a string, is not valid UTF-8,
1154 * or contains NUL bytes
1155 * @throws mpack_error_too_big If the size of the string plus null-terminator
1156 * is larger than the given maximum size
1157 * @throws mpack_error_memory If an allocation failure occurs
1158 *
1159 * @param node The node from which to allocate and copy string data
1160 * @param maxsize The maximum size to allocate, including the null-terminator
1161 *
1162 * @return The allocated string, or NULL if any error occurs.
1163 */
1164char* mpack_node_utf8_cstr_alloc(mpack_node_t node, size_t maxsize);
1165#endif
1166
1167/**
1168 * Searches the given string array for a string matching the given
1169 * node and returns its index.
1170 *
1171 * If the node does not match any of the given strings,
1172 * @ref mpack_error_type is flagged. Use mpack_node_enum_optional()
1173 * if you want to allow values other than the given strings.
1174 *
1175 * If any error occurs or if the tree is in an error state, @a count
1176 * is returned.
1177 *
1178 * This can be used to quickly parse a string into an enum when the
1179 * enum values range from 0 to @a count-1. If the last value in the
1180 * enum is a special "count" value, it can be passed as the count,
1181 * and the return value can be cast directly to the enum type.
1182 *
1183 * @code{.c}
1184 * typedef enum { APPLE , BANANA , ORANGE , COUNT} fruit_t;
1185 * const char* fruits[] = {"apple", "banana", "orange"};
1186 *
1187 * fruit_t fruit = (fruit_t)mpack_node_enum(node, fruits, COUNT);
1188 * @endcode
1189 *
1190 * @param node The node
1191 * @param strings An array of expected strings of length count
1192 * @param count The number of strings
1193 * @return The index of the matched string, or @a count in case of error
1194 */
1195size_t mpack_node_enum(mpack_node_t node, const char* strings[], size_t count);
1196
1197/**
1198 * Searches the given string array for a string matching the given node,
1199 * returning its index or @a count if no strings match.
1200 *
1201 * If the value is not a string, or it does not match any of the
1202 * given strings, @a count is returned and no error is flagged.
1203 *
1204 * If any error occurs or if the tree is in an error state, @a count
1205 * is returned.
1206 *
1207 * This can be used to quickly parse a string into an enum when the
1208 * enum values range from 0 to @a count-1. If the last value in the
1209 * enum is a special "count" value, it can be passed as the count,
1210 * and the return value can be cast directly to the enum type.
1211 *
1212 * @code{.c}
1213 * typedef enum { APPLE , BANANA , ORANGE , COUNT} fruit_t;
1214 * const char* fruits[] = {"apple", "banana", "orange"};
1215 *
1216 * fruit_t fruit = (fruit_t)mpack_node_enum_optional(node, fruits, COUNT);
1217 * @endcode
1218 *
1219 * @param node The node
1220 * @param strings An array of expected strings of length count
1221 * @param count The number of strings
1222 * @return The index of the matched string, or @a count in case of error
1223 */
1224size_t mpack_node_enum_optional(mpack_node_t node, const char* strings[], size_t count);
1225
1226/**
1227 * @}
1228 */
1229
1230/**
1231 * @name Compound Node Functions
1232 * @{
1233 */
1234
1235/**
1236 * Returns the length of the given array node. Raises mpack_error_type
1237 * and returns 0 if the given node is not an array.
1238 */
1239size_t mpack_node_array_length(mpack_node_t node);
1240
1241/**
1242 * Returns the node in the given array at the given index. If the node
1243 * is not an array, @ref mpack_error_type is raised and a nil node is returned.
1244 * If the given index is out of bounds, @ref mpack_error_data is raised and
1245 * a nil node is returned.
1246 */
1247mpack_node_t mpack_node_array_at(mpack_node_t node, size_t index);
1248
1249/**
1250 * Returns the number of key/value pairs in the given map node. Raises
1251 * mpack_error_type and returns 0 if the given node is not a map.
1252 */
1253size_t mpack_node_map_count(mpack_node_t node);
1254
1255/**
1256 * Returns the key node in the given map at the given index.
1257 *
1258 * A nil node is returned in case of error.
1259 *
1260 * @throws mpack_error_type if the node is not a map
1261 * @throws mpack_error_data if the given index is out of bounds
1262 */
1263mpack_node_t mpack_node_map_key_at(mpack_node_t node, size_t index);
1264
1265/**
1266 * Returns the value node in the given map at the given index.
1267 *
1268 * A nil node is returned in case of error.
1269 *
1270 * @throws mpack_error_type if the node is not a map
1271 * @throws mpack_error_data if the given index is out of bounds
1272 */
1273mpack_node_t mpack_node_map_value_at(mpack_node_t node, size_t index);
1274
1275/**
1276 * Returns the value node in the given map for the given integer key.
1277 *
1278 * The key must exist within the map. Use mpack_node_map_int_optional() to
1279 * check for optional keys.
1280 *
1281 * The key must be unique. An error is flagged if the node has multiple
1282 * entries with the given key.
1283 *
1284 * @throws mpack_error_type If the node is not a map
1285 * @throws mpack_error_data If the node does not contain exactly one entry with the given key
1286 *
1287 * @return The value node for the given key, or a nil node in case of error
1288 */
1289mpack_node_t mpack_node_map_int(mpack_node_t node, int64_t num);
1290
1291/**
1292 * Returns the value node in the given map for the given integer key, or a
1293 * missing node if the map does not contain the given key.
1294 *
1295 * The key must be unique. An error is flagged if the node has multiple
1296 * entries with the given key.
1297 *
1298 * @throws mpack_error_type If the node is not a map
1299 * @throws mpack_error_data If the node contains more than one entry with the given key
1300 *
1301 * @return The value node for the given key, or a missing node if the key does
1302 * not exist, or a nil node in case of error
1303 *
1304 * @see mpack_node_is_missing()
1305 */
1306mpack_node_t mpack_node_map_int_optional(mpack_node_t node, int64_t num);
1307
1308/**
1309 * Returns the value node in the given map for the given unsigned integer key.
1310 *
1311 * The key must exist within the map. Use mpack_node_map_uint_optional() to
1312 * check for optional keys.
1313 *
1314 * The key must be unique. An error is flagged if the node has multiple
1315 * entries with the given key.
1316 *
1317 * @throws mpack_error_type If the node is not a map
1318 * @throws mpack_error_data If the node does not contain exactly one entry with the given key
1319 *
1320 * @return The value node for the given key, or a nil node in case of error
1321 */
1322mpack_node_t mpack_node_map_uint(mpack_node_t node, uint64_t num);
1323
1324/**
1325 * Returns the value node in the given map for the given unsigned integer
1326 * key, or a missing node if the map does not contain the given key.
1327 *
1328 * The key must be unique. An error is flagged if the node has multiple
1329 * entries with the given key.
1330 *
1331 * @throws mpack_error_type If the node is not a map
1332 * @throws mpack_error_data If the node contains more than one entry with the given key
1333 *
1334 * @return The value node for the given key, or a missing node if the key does
1335 * not exist, or a nil node in case of error
1336 *
1337 * @see mpack_node_is_missing()
1338 */
1339mpack_node_t mpack_node_map_uint_optional(mpack_node_t node, uint64_t num);
1340
1341/**
1342 * Returns the value node in the given map for the given string key.
1343 *
1344 * The key must exist within the map. Use mpack_node_map_str_optional() to
1345 * check for optional keys.
1346 *
1347 * The key must be unique. An error is flagged if the node has multiple
1348 * entries with the given key.
1349 *
1350 * @throws mpack_error_type If the node is not a map
1351 * @throws mpack_error_data If the node does not contain exactly one entry with the given key
1352 *
1353 * @return The value node for the given key, or a nil node in case of error
1354 */
1355mpack_node_t mpack_node_map_str(mpack_node_t node, const char* str, size_t length);
1356
1357/**
1358 * Returns the value node in the given map for the given string key, or a missing
1359 * node if the map does not contain the given key.
1360 *
1361 * The key must be unique. An error is flagged if the node has multiple
1362 * entries with the given key.
1363 *
1364 * @throws mpack_error_type If the node is not a map
1365 * @throws mpack_error_data If the node contains more than one entry with the given key
1366 *
1367 * @return The value node for the given key, or a missing node if the key does
1368 * not exist, or a nil node in case of error
1369 *
1370 * @see mpack_node_is_missing()
1371 */
1372mpack_node_t mpack_node_map_str_optional(mpack_node_t node, const char* str, size_t length);
1373
1374/**
1375 * Returns the value node in the given map for the given null-terminated
1376 * string key.
1377 *
1378 * The key must exist within the map. Use mpack_node_map_cstr_optional() to
1379 * check for optional keys.
1380 *
1381 * The key must be unique. An error is flagged if the node has multiple
1382 * entries with the given key.
1383 *
1384 * @throws mpack_error_type If the node is not a map
1385 * @throws mpack_error_data If the node does not contain exactly one entry with the given key
1386 *
1387 * @return The value node for the given key, or a nil node in case of error
1388 */
1389mpack_node_t mpack_node_map_cstr(mpack_node_t node, const char* cstr);
1390
1391/**
1392 * Returns the value node in the given map for the given null-terminated
1393 * string key, or a missing node if the map does not contain the given key.
1394 *
1395 * The key must be unique. An error is flagged if the node has multiple
1396 * entries with the given key.
1397 *
1398 * @throws mpack_error_type If the node is not a map
1399 * @throws mpack_error_data If the node contains more than one entry with the given key
1400 *
1401 * @return The value node for the given key, or a missing node if the key does
1402 * not exist, or a nil node in case of error
1403 *
1404 * @see mpack_node_is_missing()
1405 */
1406mpack_node_t mpack_node_map_cstr_optional(mpack_node_t node, const char* cstr);
1407
1408/**
1409 * Returns true if the given node map contains exactly one entry with the
1410 * given integer key.
1411 *
1412 * The key must be unique. An error is flagged if the node has multiple
1413 * entries with the given key.
1414 *
1415 * @throws mpack_error_type If the node is not a map
1416 * @throws mpack_error_data If the node contains more than one entry with the given key
1417 */
1418bool mpack_node_map_contains_int(mpack_node_t node, int64_t num);
1419
1420/**
1421 * Returns true if the given node map contains exactly one entry with the
1422 * given unsigned integer key.
1423 *
1424 * The key must be unique. An error is flagged if the node has multiple
1425 * entries with the given key.
1426 *
1427 * @throws mpack_error_type If the node is not a map
1428 * @throws mpack_error_data If the node contains more than one entry with the given key
1429 */
1430bool mpack_node_map_contains_uint(mpack_node_t node, uint64_t num);
1431
1432/**
1433 * Returns true if the given node map contains exactly one entry with the
1434 * given string key.
1435 *
1436 * The key must be unique. An error is flagged if the node has multiple
1437 * entries with the given key.
1438 *
1439 * @throws mpack_error_type If the node is not a map
1440 * @throws mpack_error_data If the node contains more than one entry with the given key
1441 */
1442bool mpack_node_map_contains_str(mpack_node_t node, const char* str, size_t length);
1443
1444/**
1445 * Returns true if the given node map contains exactly one entry with the
1446 * given null-terminated string key.
1447 *
1448 * The key must be unique. An error is flagged if the node has multiple
1449 * entries with the given key.
1450 *
1451 * @throws mpack_error_type If the node is not a map
1452 * @throws mpack_error_data If the node contains more than one entry with the given key
1453 */
1454bool mpack_node_map_contains_cstr(mpack_node_t node, const char* cstr);
1455
1456/**
1457 * @}
1458 */
1459
1460/**
1461 * @}
1462 */
1463
1464#endif
1465
1466MPACK_EXTERN_C_END
1467MPACK_SILENCE_WARNINGS_END
1468
1469#endif
1470
1471
1472