Loading...
Searching...
No Matches
as_bytes.h
Go to the documentation of this file.
1/*
2 * Copyright 2008-2021 Aerospike, Inc.
3 *
4 * Portions may be licensed to Aerospike, Inc. under one or more contributor
5 * license agreements.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8 * use this file except in compliance with the License. You may obtain a copy of
9 * the License at http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 * License for the specific language governing permissions and limitations under
15 * the License.
16 */
17
18#pragma once
19
20#include <aerospike/as_std.h>
21#include <aerospike/as_util.h>
22#include <aerospike/as_val.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/******************************************************************************
29 * TYPES
30 *****************************************************************************/
31
32/**
33 * Types for `as_bytes.type`
34 */
35typedef enum as_bytes_type_e {
36
37 /**
38 * Type is Undefined
39 */
41
42 /**
43 * Integer
44 */
46
47 /**
48 * Double
49 */
51
52 /**
53 * String
54 */
56
57 /**
58 * Generic BLOB
59 */
61
62 /**
63 * Serialized Java Object
64 */
66
67 /**
68 * Serialized C# Object
69 */
71
72 /**
73 * Pickled Python Object
74 */
76
77 /**
78 * Marshalled Ruby Object
79 */
81
82 /**
83 * Serialized PHP Object
84 */
86
87 /**
88 * Serialized Erlang Data
89 */
91
92 /**
93 * Vector
94 */
96
97 /**
98 * Boolean
99 */
101
102 /**
103 * HyperLogLog
104 */
106
107 /**
108 * Map
109 */
111
112 /**
113 * List
114 */
116
117 /**
118 * GeoJSON Data
119 */
121
122 /**
123 * Upper bounds for the enum
124 */
126
128
129/**
130 * Container for byte arrays.
131 *
132 * ## Initialization
133 *
134 * An as_bytes should be initialized via one of the provided function.
135 * - as_bytes_inita()
136 * - as_bytes_init()
137 * - as_bytes_new()
138 *
139 * The as_bytes_inita(), as_bytes_init() and as_bytes_new() are used to
140 * initialize empty internal buffers of a specified size.
141 *
142 * To initialize a stack allocated as_string, use as_bytes_init():
143 *
144 * ~~~~~~~~~~{.c}
145 * as_bytes b;
146 * as_bytes_init(&b, 20);
147 * ~~~~~~~~~~
148 *
149 * The above initialized the variable, and allocated 20 bytes to the buffer
150 * using `cf_malloc()`.
151 *
152 * To use only stack allocated buffer for as_bytes, ten you should use
153 * as_bytes_inita():
154 *
155 * ~~~~~~~~~~{.c}
156 * as_bytes b;
157 * as_bytes_inita(&b, 20);
158 * ~~~~~~~~~~
159 *
160 * You will see the APIs of the two are very similar. The key difference is
161 * as_bytes_inita() is a macro, which performs stack allocation inline.
162 *
163 * If you need a heap allocated as_bytes instance, then you should use
164 * as_bytes_new():
165 *
166 * ~~~~~~~~~~{.c}
167 * as_bytes * b = as_bytes_new(20);
168 * ~~~~~~~~~~
169 *
170 * ## Wrapping Byte Arrays
171 *
172 * If you already have a byte array allocated and want to simply wrap it
173 * in an as_bytes, then use either:
174 * - as_bytes_init_wrap()
175 * - as_bytes_new_wrap()
176 *
177 * The as_bytes_init_wrap() function is used to initialize a stack allocated
178 * as_bytes, then set the internal buffer to the byte array provided.
179 *
180 * The as_bytes_new_wrap() function is used to create an initialize a new
181 * heap allocated as_bytes, then it will set the internal buffer to the
182 * byte array provided.
183 *
184 *
185 * ## Destruction
186 *
187 * When the as_bytes instance is no longer required, then you should
188 * release the resources associated with it via as_bytes_destroy():
189 *
190 * ~~~~~~~~~~{.c}
191 * as_bytes_destroy(b);
192 * ~~~~~~~~~~
193 *
194 * ## Usage
195 *
196 * as_bytes has a number of functions for reading and writing data to its
197 * internal buffer.
198 *
199 * For reading at specified index:
200 *
201 * | Function | Description |
202 * | -------- | ----------- |
203 * | as_bytes_get() | Copy the bytes in the buffer to another buffer. |
204 * | as_bytes_get_byte() | Read a byte from the buffer |
205 * | as_bytes_get_int16() | Read a 16-bit integer from the buffer |
206 * | as_bytes_get_int32() | Read a 32-bit integer from the buffer |
207 * | as_bytes_get_int64() | Read a 64-bit integer from the buffer |
208 *
209 * For writing at specified index:
210 *
211 * | Function | Description |
212 * | -------- | ----------- |
213 * | as_bytes_set() | Copy a byte array into the buffer. |
214 * | as_bytes_set_byte() | Write a byte from the buffer |
215 * | as_bytes_set_int16() | Write a 16-bit integer from the buffer |
216 * | as_bytes_set_int32() | Write a 32-bit integer from the buffer |
217 * | as_bytes_set_int64() | Write a 64-bit integer from the buffer |
218 *
219 * For writing at to the end of the buffer:
220 *
221 * | Function | Description |
222 * | -------- | ----------- |
223 * | as_bytes_append() | Copy a byte array into the buffer. |
224 * | as_bytes_append_byte() | Write a byte from the buffer |
225 * | as_bytes_append_int16() | Write a 16-bit integer from the buffer |
226 * | as_bytes_append_int32() | Write a 32-bit integer from the buffer |
227 * | as_bytes_append_int64() | Write a 64-bit integer from the buffer |
228 *
229 *
230 * ## Conversions
231 *
232 * as_bytes is derived from as_val, so it is generally safe to down cast:
233 *
234 * ~~~~~~~~~~{.c}
235 * as_val val = (as_val) b;
236 * ~~~~~~~~~~
237 *
238 * However, upcasting is more error prone. When doing so, you should use
239 * as_bytes_fromval(). If conversion fails, then the return value is NULL.
240 *
241 * ~~~~~~~~~~{.c}
242 * as_bytes * i = as_bytes_fromval(val);
243 * ~~~~~~~~~~
244 *
245 *
246 *
247 * @extends as_val
248 * @ingroup aerospike_t
249 */
250typedef struct as_bytes_s {
251
252 /**
253 * @private
254 * as_boolean is a subtype of as_val.
255 * You can cast as_boolean to as_val.
256 */
257 as_val _;
258
259 /**
260 * The number of bytes allocated to `as_bytes.value`.
261 */
262 uint32_t capacity;
263
264 /**
265 * The number of bytes used by `as_bytes.value`.
266 */
267 uint32_t size;
268
269 /**
270 * A sequence of bytes.
271 */
272 uint8_t * value;
273
274 /**
275 * If true, then `as_bytes.value` will be freed when as_bytes_destroy()
276 * is called.
277 */
278 bool free;
279
280 /**
281 * The type of bytes.
282 */
284
285} as_bytes;
286
287/******************************************************************************
288 * MACROS
289 *****************************************************************************/
290
291/**
292 * Initializes a stack allocated `as_bytes`. Allocates an internal buffer
293 * on the stack of specified capacity using `alloca()`.
294 *
295 * ~~~~~~~~~~{.c}
296 * as_bytes bytes;
297 * as_bytes_inita(&bytes, 10);
298 * ~~~~~~~~~~
299 *
300 * @param __bytes The bytes to initialize.
301 * @param __capacity The number of bytes to allocate on the heap.
302 */
303#define as_bytes_inita(__bytes, __capacity)\
304 as_bytes_init(__bytes, 0);\
305 (__bytes)->type = AS_BYTES_BLOB;\
306 (__bytes)->free = false;\
307 (__bytes)->capacity = (__capacity);\
308 (__bytes)->size = 0;\
309 (__bytes)->value = (uint8_t*) alloca(sizeof(uint8_t) * (__capacity));
310
311
312/******************************************************************************
313 * INSTANCE FUNCTIONS
314 *****************************************************************************/
315
316/**
317 * Initializes a stack allocated `as_bytes`. Allocates an internal buffer
318 * on the heap of specified capacity using `cf_malloc()`.
319 *
320 * ~~~~~~~~~~{.c}
321 * as_bytes bytes;
322 * as_bytes_init_empty(&bytes, 10);
323 * ~~~~~~~~~~
324 *
325 * @param bytes The bytes to initialize.
326 * @param capacity The number of bytes to allocate on the heap.
327 *
328 * @return On success, the initializes bytes. Otherwise NULL.
329 *
330 * @relatesalso as_bytes
331 */
332AS_EXTERN as_bytes * as_bytes_init(as_bytes * bytes, uint32_t capacity);
333
334/**
335 * Initializes a stack allocated `as_bytes`, wrapping the given buffer.
336 *
337 * ~~~~~~~~~~{.c}
338 * uint8_t raw[10] = {0};
339 *
340 * as_bytes bytes;
341 * as_bytes_init_wrap(&bytes, raw, 10, false);
342 * ~~~~~~~~~~
343 *
344 * @param bytes The bytes to initialize.
345 * @param value The initial value.
346 * @param size The number of bytes of the initial value.
347 * @param free If true, then `as_bytes_destroy()` will free the value.
348 *
349 * @return On success, the initializes bytes. Otherwise NULL.
350 *
351 * @relatesalso as_bytes
352 */
353AS_EXTERN as_bytes * as_bytes_init_wrap(as_bytes * bytes, uint8_t * value, uint32_t size, bool free);
354
355/**
356 * Create and initialize a new heap allocated `as_bytes`. Allocates an
357 * internal buffer on the heap of specified capacity using `cf_malloc()`.
358 *
359 * ~~~~~~~~~~{.c}
360 * as_bytes * bytes = as_bytes_new(10);
361 * ~~~~~~~~~~
362 *
363 * @param capacity The number of bytes to allocate.
364 *
365 * @return On success, the initializes bytes. Otherwise NULL.
366 *
367 * @relatesalso as_bytes
368 */
369AS_EXTERN as_bytes * as_bytes_new(uint32_t capacity);
370
371/**
372 * Creates a new heap allocated `as_bytes`, wrapping the given buffer.
373 *
374 * ~~~~~~~~~~{.c}
375 * uint8_t raw[10] = {0};
376 *
377 * as_bytes * bytes = as_bytes_new_wrap(raw, 10, false);
378 * ~~~~~~~~~~
379 *
380 * @param value The initial value.
381 * @param size The number of bytes of the initial value.
382 * @param free If true, then `as_bytes_destroy()` will free the value.
383 *
384 * @return On success, the initializes bytes. Otherwise NULL.
385 *
386 * @relatesalso as_bytes
387 */
388AS_EXTERN as_bytes * as_bytes_new_wrap(uint8_t * value, uint32_t size, bool free);
389
390/**
391 * Destroy the `as_bytes` and release associated resources.
392 *
393 * ~~~~~~~~~~{.c}
394 * as_bytes_destroy(bytes);
395 * ~~~~~~~~~~
396 *
397 * @param bytes The bytes to destroy.
398 *
399 * @relatesalso as_bytes
400 */
401static inline void as_bytes_destroy(as_bytes * bytes)
402{
403 as_val_destroy((as_val *) bytes);
404}
405
406/******************************************************************************
407 * VALUE FUNCTIONS
408 *****************************************************************************/
409
410/**
411 * Get the number of bytes used.
412 *
413 * @param bytes The bytes to get the size of.
414 *
415 * @return The number of bytes used.
416 *
417 * @relatesalso as_bytes
418 */
419static inline uint32_t as_bytes_size(const as_bytes * bytes)
420{
421 if ( !bytes ) return 0;
422 return bytes->size;
423}
424
425/**
426 * Get the number of bytes allocated.
427 *
428 * @param bytes The bytes to get the capacity of.
429 *
430 * @return The number of bytes allocated.
431 *
432 * @relatesalso as_bytes
433 */
434static inline uint32_t as_bytes_capacity(const as_bytes * bytes)
435{
436 if ( !bytes ) return 0;
437 return bytes->capacity;
438}
439
440/**
441 * Get the type of bytes.
442 *
443 * @param bytes The bytes to get the type of.
444 *
445 * @return The type of bytes.
446 *
447 * @relatesalso as_bytes
448 */
449static inline as_bytes_type as_bytes_get_type(const as_bytes * bytes)
450{
451 if ( !bytes ) return AS_BYTES_UNDEF;
452 return bytes->type;
453}
454
455/**
456 * Set the type of bytes.
457 *
458 * @param bytes The bytes to set the type of.
459 * @param type The type for the bytes.
460 *
461 * @relatesalso as_bytes
462 */
463static inline void as_bytes_set_type(as_bytes * bytes, as_bytes_type type)
464{
465 if ( !bytes ) return;
466 bytes->type = type;
467}
468
469/**
470 * Get the raw value of this instance. If the instance is NULL, then
471 * return the fallback value.
472 *
473 * ~~~~~~~~~~{.c}
474 * uint8_t * raw = as_bytes_getorelse(&bytes, NULL);
475 * ~~~~~~~~~~
476 *
477 * @param bytes The bytes to get the raw value from.
478 * @param fallback The value to return if bytes is NULL.
479 *
480 * @return The pointer to the raw value if bytes is not NULL. Otherwise
481 * return the fallback.
482 *
483 * @relatesalso as_bytes
484 */
485static inline uint8_t * as_bytes_getorelse(const as_bytes * bytes, uint8_t * fallback)
486{
487 return bytes ? bytes->value : fallback;
488}
489
490/**
491 * Get the raw value of this instance.
492 *
493 * ~~~~~~~~~~{.c}
494 * uint8_t * raw = as_bytes_get(&bytes);
495 * ~~~~~~~~~~
496 *
497 * @param bytes The bytes to get the raw value from.
498 *
499 * @return The pointer to the raw value.
500 *
501 * @relatesalso as_bytes
502 */
503static inline uint8_t * as_bytes_get(const as_bytes * bytes)
504{
505 return as_bytes_getorelse(bytes, NULL);
506}
507
508
509/******************************************************************************
510 * GET AT INDEX
511 *****************************************************************************/
512
513
514/**
515 * Copy into value up to size bytes from the given `as_bytes`, returning
516 * the number of bytes copied.
517 *
518 * ~~~~~~~~~~{.c}
519 * uint8_t value[3] = {0};
520 * uint32_t sz = as_bytes_copy(&bytes, 0, value, 3);
521 * if ( sz == 0 ) {
522 * // sz == 0, means that an error occurred
523 * }
524 * ~~~~~~~~~~
525 *
526 * @param bytes The bytes to read from.
527 * @param index The positing in bytes to read from.
528 * @param value The byte buffer to copy into.
529 * @param size The number of bytes to copy into the buffer.
530 *
531 *
532 * @return The number of bytes read and stored into value. 0 (zero) indicates
533 * an error has occurred.
534 *
535 * @relatesalso as_bytes
536 */
537AS_EXTERN uint32_t as_bytes_copy(const as_bytes * bytes, uint32_t index, uint8_t * value, uint32_t size);
538
539/**
540 * Read a single byte from the given bytes.
541 *
542 * ~~~~~~~~~~{.c}
543 * uint8_t value = 0;
544 * uint32_t sz = as_bytes_get_byte(&bytes, 0, &value);
545 * if ( sz == 0 ) {
546 * // sz == 0, means that an error occurred
547 * }
548 * ~~~~~~~~~~
549 *
550 * @return The number of bytes read and stored into value. 0 (zero) indicates
551 * an error has occurred.
552 *
553 * @relatesalso as_bytes
554 */
555static inline uint32_t as_bytes_get_byte(const as_bytes * bytes, uint32_t index, uint8_t * value)
556{
557 return as_bytes_copy(bytes, index, (uint8_t *) value, 1);
558}
559
560/**
561 * Read an int16_t from the given bytes.
562 *
563 * ~~~~~~~~~~{.c}
564 * int16_t value = 0;
565 * uint32_t sz = as_bytes_get_int16(&bytes, 0, &value);
566 * if ( sz == 0 ) {
567 * // sz == 0, means that an error occurred
568 * }
569 * ~~~~~~~~~~
570 *
571 * @return The number of bytes read and stored into value. 0 (zero) indicates
572 * an error has occurred.
573 *
574 * @relatesalso as_bytes
575 */
576static inline uint32_t as_bytes_get_int16(const as_bytes * bytes, uint32_t index, int16_t * value)
577{
578 return as_bytes_copy(bytes, index, (uint8_t *) value, 2);
579}
580
581/**
582 * Read an int32_t from the given bytes.
583 *
584 * ~~~~~~~~~~{.c}
585 * int32_t value = 0;
586 * uint32_t sz = as_bytes_get_int32(&bytes, 0, &value);
587 * if ( sz == 0 ) {
588 * // sz == 0, means that an error occurred
589 * }
590 * ~~~~~~~~~~
591 *
592 * @return The number of bytes read and stored into value. 0 (zero) indicates
593 * an error has occurred.
594 *
595 * @relatesalso as_bytes
596 */
597static inline uint32_t as_bytes_get_int32(const as_bytes * bytes, uint32_t index, int32_t * value)
598{
599 return as_bytes_copy(bytes, index, (uint8_t *) value, 4);
600}
601
602/**
603 * Read an int64_t from the given bytes.
604 *
605 * ~~~~~~~~~~{.c}
606 * int64_t value = 0;
607 * uint32_t sz = as_bytes_get_int64(&bytes, 0, &value);
608 * if ( sz == 0 ) {
609 * // sz == 0, means that an error occurred
610 * }
611 * ~~~~~~~~~~
612 *
613 * @return The number of bytes read and stored into value. 0 (zero) indicates
614 * an error has occurred.
615 *
616 * @relatesalso as_bytes
617 */
618static inline uint32_t as_bytes_get_int64(const as_bytes * bytes, uint32_t index, int64_t * value)
619{
620 return as_bytes_copy(bytes, index, (uint8_t *) value, 8);
621}
622
623/**
624 * Read a double from the given bytes.
625 *
626 * ~~~~~~~~~~{.c}
627 * double value = 0;
628 * uint32_t sz = as_bytes_get_double(&bytes, 0, &value);
629 * if ( sz == 0 ) {
630 * // sz == 0, means that an error occurred
631 * }
632 * ~~~~~~~~~~
633 *
634 * @return The number of bytes read and stored into value. 0 (zero) indicates
635 * an error has occurred.
636 *
637 * @relatesalso as_bytes
638 */
639static inline uint32_t as_bytes_get_double(const as_bytes * bytes, uint32_t index, double * value)
640{
641 return as_bytes_copy(bytes, index, (uint8_t *) value, 8);
642}
643
644/**
645 * Decode an integer in variable 7-bit format.
646 * The high bit indicates if more bytes are used.
647 *
648 * ~~~~~~~~~~{.c}
649 * uint32_t value = 0;
650 * uint32_t sz = as_bytes_get_var_int(&bytes, 0, &value);
651 * if ( sz == 0 ) {
652 * // sz == 0, means that an error occurred
653 * }
654 * ~~~~~~~~~~
655 *
656 * @return The number of bytes copied in to value.
657 *
658 * @relatesalso as_bytes
659 */
660AS_EXTERN uint32_t as_bytes_get_var_int(const as_bytes * bytes, uint32_t index, uint32_t * value);
661
662/******************************************************************************
663 * SET AT INDEX
664 *****************************************************************************/
665
666/**
667 * Copy raw bytes of given size into the given `as_bytes` starting at
668 * specified index.
669 *
670 * ~~~~~~~~~~{.c}
671 * as_bytes_set(&bytes, 0, (uint8_t[]){'a','b','c'}, 3);
672 * ~~~~~~~~~~
673 *
674 * @param bytes The bytes to write to.
675 * @param index The position to write to.
676 * @param value The buffer to read from.
677 * @param size The number of bytes to read from the value.
678 *
679 * @return On success, true. Otherwise an error occurred.
680 *
681 * @relatesalso as_bytes
682 */
683AS_EXTERN bool as_bytes_set(as_bytes * bytes, uint32_t index, const uint8_t * value, uint32_t size);
684
685/**
686 * Set a byte at given index.
687 *
688 * ~~~~~~~~~~{.c}
689 * as_bytes_set_byte(&bytes, 0, 'a');
690 * ~~~~~~~~~~
691 *
692 * @return On success, true. Otherwise an error occurred.
693 *
694 * @relatesalso as_bytes
695 */
696static inline bool as_bytes_set_byte(as_bytes * bytes, uint32_t index, uint8_t value)
697{
698 return as_bytes_set(bytes, index, (uint8_t *) &value, 1);
699}
700
701/**
702 * Set 16 bit integer at given index.
703 *
704 * ~~~~~~~~~~{.c}
705 * as_bytes_set_int16(&bytes, 0, 1);
706 * ~~~~~~~~~~
707 *
708 * @return On success, true. Otherwise an error occurred.
709 *
710 * @relatesalso as_bytes
711 */
712static inline bool as_bytes_set_int16(as_bytes * bytes, uint32_t index, int16_t value)
713{
714 return as_bytes_set(bytes, index, (uint8_t *) &value, 2);
715}
716
717/**
718 * Set 32 bit integer at given index.
719 *
720 * ~~~~~~~~~~{.c}
721 * as_bytes_set_int32(&bytes, 0, 2);
722 * ~~~~~~~~~~
723 *
724 * @return On success, true. Otherwise an error occurred.
725 *
726 * @relatesalso as_bytes
727 */
728static inline bool as_bytes_set_int32(as_bytes * bytes, uint32_t index, int32_t value)
729{
730 return as_bytes_set(bytes, index, (uint8_t *) &value, 4);
731}
732
733/**
734 * Set 64 bit integer at given index.
735 *
736 * ~~~~~~~~~~{.c}
737 * as_bytes_set_int64(&bytes, 0, 3);
738 * ~~~~~~~~~~
739 *
740 * @return On success, true. Otherwise an error occurred.
741 *
742 * @relatesalso as_bytes
743 */
744static inline bool as_bytes_set_int64(as_bytes * bytes, uint32_t index, int64_t value)
745{
746 return as_bytes_set(bytes, index, (uint8_t *) &value, 8);
747}
748
749/**
750 * Set double at given index.
751 *
752 * ~~~~~~~~~~{.c}
753 * as_bytes_set_double(&bytes, 0, 4.4);
754 * ~~~~~~~~~~
755 *
756 * @return On success, true. Otherwise an error occurred.
757 *
758 * @relatesalso as_bytes
759 */
760static inline bool as_bytes_set_double(as_bytes * bytes, uint32_t index, double value)
761{
762 return as_bytes_set(bytes, index, (uint8_t *) &value, 8);
763}
764
765/**
766 * Encode an integer in 7-bit format.
767 * The high bit indicates if more bytes are used.
768 *
769 * ~~~~~~~~~~{.c}
770 * as_bytes_set_var_int(&bytes, 0, 36);
771 * ~~~~~~~~~~
772 *
773 * The `bytes` must be sufficiently sized for the data being written.
774 * To ensure the `bytes` is allocated sufficiently, you will need to call
775 * `as_bytes_ensure()`.
776 *
777 * @return The number of bytes copied into byte array.
778 *
779 * @relatesalso as_bytes
780 */
781AS_EXTERN uint32_t as_bytes_set_var_int(const as_bytes * bytes, uint32_t index, uint32_t value);
782
783/******************************************************************************
784 * APPEND TO THE END
785 *****************************************************************************/
786
787/**
788 * Append raw bytes of given size.
789 *
790 * ~~~~~~~~~~{.c}
791 * uint8_t value[3] = {'a','b','c'};
792 *
793 * as_bytes_append(&bytes, value, 3);
794 * ~~~~~~~~~~
795 *
796 * @param bytes The bytes to append to.
797 * @param value The buffer to read from.
798 * @param size The number of bytes to read from the value.
799 *
800 * @return On success, true. Otherwise an error occurred.
801 *
802 * @relatesalso as_bytes
803 */
804AS_EXTERN bool as_bytes_append(as_bytes * bytes, const uint8_t * value, uint32_t size);
805
806/**
807 * Append a uint8_t (byte).
808 *
809 * ~~~~~~~~~~{.c}
810 * as_bytes_append_byte(&bytes, 'a');
811 * ~~~~~~~~~~
812 *
813 * @return On success, true. Otherwise an error occurred.
814 *
815 * @relatesalso as_bytes
816 */
817static inline bool as_bytes_append_byte(as_bytes * bytes, uint8_t value)
818{
819 return as_bytes_append(bytes, (uint8_t *) &value, 1);
820}
821
822/**
823 * Append an int16_t value.
824 *
825 * ~~~~~~~~~~{.c}
826 * as_bytes_append_int16(&bytes, 123);
827 * ~~~~~~~~~~
828 *
829 * @return On success, true. Otherwise an error occurred.
830 *
831 * @relatesalso as_bytes
832 */
833static inline bool as_bytes_append_int16(as_bytes * bytes, int16_t value)
834{
835 return as_bytes_append(bytes, (uint8_t *) &value, 2);
836}
837
838/**
839 * Append an int32_t value.
840 *
841 * ~~~~~~~~~~{.c}
842 * as_bytes_append_int32(&bytes, 123);
843 * ~~~~~~~~~~
844 *
845 * @return On success, true. Otherwise an error occurred.
846 *
847 * @relatesalso as_bytes
848 */
849static inline bool as_bytes_append_int32(as_bytes * bytes, int32_t value)
850{
851 return as_bytes_append(bytes, (uint8_t *) &value, 4);
852}
853
854/**
855 * Append an int64_t value.
856 *
857 * ~~~~~~~~~~{.c}
858 * as_bytes_append_int64(&bytes, 123);
859 * ~~~~~~~~~~
860 *
861 * @return On success, true. Otherwise an error occurred.
862 *
863 * @relatesalso as_bytes
864 */
865static inline bool as_bytes_append_int64(as_bytes * bytes, int64_t value)
866{
867 return as_bytes_append(bytes, (uint8_t *) &value, 8);
868}
869
870/**
871 * Append a double value.
872 *
873 * ~~~~~~~~~~{.c}
874 * as_bytes_append_double(&bytes, 123.456);
875 * ~~~~~~~~~~
876 *
877 * @return On success, true. Otherwise an error occurred.
878 *
879 * @relatesalso as_bytes
880 */
881static inline bool as_bytes_append_double(as_bytes * bytes, double value)
882{
883 return as_bytes_append(bytes, (uint8_t *) &value, 8);
884}
885
886/******************************************************************************
887 * MODIFIES BUFFER
888 *****************************************************************************/
889
890/**
891 * Truncate the bytes' buffer. The size specifies the number of bytes to
892 * remove from the end of the buffer.
893 *
894 * This means, if the buffer has size of 100, and we truncate 10, then
895 * the remaining size is 90.
896
897 * Truncation does not modify the capacity of the buffer.
898 *
899 * ~~~~~~~~~~{.c}
900 * as_bytes_truncate(&bytes, 10);
901 * ~~~~~~~~~~
902 *
903 * @param bytes The bytes to truncate.
904 * @param n The number of bytes to remove from the end.
905 *
906 * @return On success, true. Otherwise an error occurred.
907 *
908 * @relatesalso as_bytes
909 */
910AS_EXTERN bool as_bytes_truncate(as_bytes * bytes, uint32_t n);
911
912/**
913 * Ensure the bytes buffer can handle `capacity` bytes.
914 *
915 * If `resize` is true and `capacity` exceeds the capacity of the bytes's
916 * buffer, then resize the capacity of the buffer to `capacity` bytes. If the
917 * buffer was heap allocated, then `cf_realloc()` will be used to resize. If the
918 * buffer was stack allocated, it will be converted to a heap allocated buffer
919 * using cf_malloc() and then its contents will be copied into the new heap
920 * allocated buffer.
921 *
922 * If `resize` is false, and if the capacity is not sufficient, then return
923 * false.
924 *
925 * ~~~~~~~~~~{.c}
926 * as_bytes_ensure(&bytes, 100, true);
927 * ~~~~~~~~~~
928 *
929 * @param bytes The bytes to ensure the capacity of.
930 * @param capacity The total number of bytes to ensure bytes can handle.
931 * @param resize If true and capacity is not sufficient, then resize the buffer.
932 *
933 * @return On success, true. Otherwise an error occurred.
934 *
935 * @relatesalso as_bytes
936 */
937AS_EXTERN bool as_bytes_ensure(as_bytes * bytes, uint32_t capacity, bool resize);
938
939
940/**
941 * Get the bytes value.
942 *
943 * @deprecated Use as_bytes_get() instead.
944 *
945 * @relatesalso as_bytes
946 */
947static inline uint8_t * as_bytes_tobytes(const as_bytes * bytes, uint32_t * size)
948{
949 if ( !bytes ) return NULL;
950
951 if ( size ) {
952 *size = bytes->size;
953 }
954
955 return bytes->value;
956}
957
958/******************************************************************************
959 * CONVERSION FUNCTIONS
960 *****************************************************************************/
961
962/**
963 * Convert to an as_val.
964 *
965 * @relatesalso as_bytes
966 */
967static inline as_val * as_bytes_toval(const as_bytes * b)
968{
969 return (as_val *) b;
970}
971
972/**
973 * Convert from an as_val.
974 *
975 * @relatesalso as_bytes
976 */
977static inline as_bytes * as_bytes_fromval(const as_val * v)
978{
980}
981
982/******************************************************************************
983 * as_val FUNCTIONS
984 *****************************************************************************/
985
986/**
987 * @private
988 * Internal helper function for destroying an as_val.
989 */
991
992/**
993 * @private
994 * Internal helper function for getting the hashcode of an as_val.
995 */
997
998/**
999 * @private
1000 * Internal helper function for getting the string representation of an as_val.
1001 */
1003
1004/******************************************************************************
1005 * Byte utilities
1006 *****************************************************************************/
1007
1008/**
1009 * Convert byte array to hexidecimal string.
1010 *
1011 * @param bytes Source byte array.
1012 * @param bytes_size Size of byte array.
1013 * @param str Target hex string.
1014 * @param str_size Size of hex string.
1015 *
1016 * @return true on success, false on string truncation.
1017 */
1018AS_EXTERN bool
1019as_bytes_to_string(const uint8_t* bytes, uint32_t bytes_size, char* str, uint32_t str_size);
1020
1021/**
1022 * Convert byte array to hexidecimal string with 0x prefix.
1023 *
1024 * @param bytes Source byte array.
1025 * @param bytes_size Size of byte array.
1026 * @param str Target hex string.
1027 * @param str_size Size of hex string.
1028 *
1029 * @return true on success, false on string truncation.
1030 */
1031AS_EXTERN bool
1032as_bytes_to_string_with_prefix(const uint8_t* bytes, uint32_t bytes_size, char* str, uint32_t str_size);
1033
1034/**
1035 * Convert hexidecimal string to byte array.
1036 *
1037 * @param bytes Target byte array.
1038 * @param bytes_size Size of byte array.
1039 * @param str Source hex string in format [0x][0-9]|[a-f]|[A-F]. 0x prefix is optional.
1040 *
1041 * @return count of bytes converted or -1 on invalid hex chars or byte array truncation.
1042 */
1043AS_EXTERN int
1044as_bytes_from_string(uint8_t* bytes, uint32_t bytes_size, const char* str);
1045
1046#ifdef __cplusplus
1047} // end extern "C"
1048#endif
as_bytes_type
Definition as_bytes.h:35
@ AS_BYTES_BLOB
Definition as_bytes.h:60
@ AS_BYTES_LIST
Definition as_bytes.h:115
@ AS_BYTES_BOOL
Definition as_bytes.h:100
@ AS_BYTES_JAVA
Definition as_bytes.h:65
@ AS_BYTES_RUBY
Definition as_bytes.h:80
@ AS_BYTES_ERLANG
Definition as_bytes.h:90
@ AS_BYTES_INTEGER
Definition as_bytes.h:45
@ AS_BYTES_GEOJSON
Definition as_bytes.h:120
@ AS_BYTES_UNDEF
Definition as_bytes.h:40
@ AS_BYTES_CSHARP
Definition as_bytes.h:70
@ AS_BYTES_PYTHON
Definition as_bytes.h:75
@ AS_BYTES_DOUBLE
Definition as_bytes.h:50
@ AS_BYTES_HLL
Definition as_bytes.h:105
@ AS_BYTES_MAP
Definition as_bytes.h:110
@ AS_BYTES_STRING
Definition as_bytes.h:55
@ AS_BYTES_VECTOR
Definition as_bytes.h:95
@ AS_BYTES_PHP
Definition as_bytes.h:85
@ AS_BYTES_TYPE_MAX
Definition as_bytes.h:125
AS_EXTERN uint32_t as_bytes_val_hashcode(const as_val *v)
static uint8_t * as_bytes_getorelse(const as_bytes *bytes, uint8_t *fallback)
Definition as_bytes.h:485
AS_EXTERN char * as_bytes_val_tostring(const as_val *v)
AS_EXTERN void as_bytes_val_destroy(as_val *v)
AS_EXTERN bool as_bytes_to_string_with_prefix(const uint8_t *bytes, uint32_t bytes_size, char *str, uint32_t str_size)
AS_EXTERN uint32_t as_bytes_copy(const as_bytes *bytes, uint32_t index, uint8_t *value, uint32_t size)
AS_EXTERN bool as_bytes_set(as_bytes *bytes, uint32_t index, const uint8_t *value, uint32_t size)
AS_EXTERN bool as_bytes_append(as_bytes *bytes, const uint8_t *value, uint32_t size)
AS_EXTERN bool as_bytes_to_string(const uint8_t *bytes, uint32_t bytes_size, char *str, uint32_t str_size)
AS_EXTERN int as_bytes_from_string(uint8_t *bytes, uint32_t bytes_size, const char *str)
uint8_t type
Definition as_proto.h:1
#define AS_EXTERN
Definition as_std.h:25
#define as_util_fromval(object, type_id, type)
Definition as_util.h:43
@ AS_BYTES
Definition as_val.h:45
#define as_val_destroy(__v)
Definition as_val.h:114
static bool as_bytes_append_int32(as_bytes *bytes, int32_t value)
Definition as_bytes.h:849
static uint8_t * as_bytes_getorelse(const as_bytes *bytes, uint8_t *fallback)
Definition as_bytes.h:485
static bool as_bytes_set_int16(as_bytes *bytes, uint32_t index, int16_t value)
Definition as_bytes.h:712
static bool as_bytes_set_double(as_bytes *bytes, uint32_t index, double value)
Definition as_bytes.h:760
static bool as_bytes_set_int32(as_bytes *bytes, uint32_t index, int32_t value)
Definition as_bytes.h:728
AS_EXTERN bool as_bytes_truncate(as_bytes *bytes, uint32_t n)
AS_EXTERN uint32_t as_bytes_get_var_int(const as_bytes *bytes, uint32_t index, uint32_t *value)
static bool as_bytes_append_double(as_bytes *bytes, double value)
Definition as_bytes.h:881
AS_EXTERN bool as_bytes_ensure(as_bytes *bytes, uint32_t capacity, bool resize)
as_bytes_type type
Definition as_bytes.h:283
static bool as_bytes_append_byte(as_bytes *bytes, uint8_t value)
Definition as_bytes.h:817
static uint32_t as_bytes_get_int16(const as_bytes *bytes, uint32_t index, int16_t *value)
Definition as_bytes.h:576
AS_EXTERN as_bytes * as_bytes_new(uint32_t capacity)
static uint32_t as_bytes_get_double(const as_bytes *bytes, uint32_t index, double *value)
Definition as_bytes.h:639
static uint32_t as_bytes_capacity(const as_bytes *bytes)
Definition as_bytes.h:434
static bool as_bytes_append_int64(as_bytes *bytes, int64_t value)
Definition as_bytes.h:865
static bool as_bytes_append_int16(as_bytes *bytes, int16_t value)
Definition as_bytes.h:833
AS_EXTERN uint32_t as_bytes_copy(const as_bytes *bytes, uint32_t index, uint8_t *value, uint32_t size)
bool free
Definition as_bytes.h:278
static uint32_t as_bytes_get_byte(const as_bytes *bytes, uint32_t index, uint8_t *value)
Definition as_bytes.h:555
AS_EXTERN as_bytes * as_bytes_init_wrap(as_bytes *bytes, uint8_t *value, uint32_t size, bool free)
AS_EXTERN bool as_bytes_set(as_bytes *bytes, uint32_t index, const uint8_t *value, uint32_t size)
AS_EXTERN bool as_bytes_append(as_bytes *bytes, const uint8_t *value, uint32_t size)
static uint8_t * as_bytes_get(const as_bytes *bytes)
Definition as_bytes.h:503
AS_EXTERN as_bytes * as_bytes_init(as_bytes *bytes, uint32_t capacity)
static uint32_t as_bytes_get_int32(const as_bytes *bytes, uint32_t index, int32_t *value)
Definition as_bytes.h:597
static as_val * as_bytes_toval(const as_bytes *b)
Definition as_bytes.h:967
uint32_t capacity
Definition as_bytes.h:262
uint32_t size
Definition as_bytes.h:267
static void as_bytes_destroy(as_bytes *bytes)
Definition as_bytes.h:401
static as_bytes * as_bytes_fromval(const as_val *v)
Definition as_bytes.h:977
static uint8_t * as_bytes_tobytes(const as_bytes *bytes, uint32_t *size)
Definition as_bytes.h:947
static uint32_t as_bytes_get_int64(const as_bytes *bytes, uint32_t index, int64_t *value)
Definition as_bytes.h:618
static void as_bytes_set_type(as_bytes *bytes, as_bytes_type type)
Definition as_bytes.h:463
static as_bytes_type as_bytes_get_type(const as_bytes *bytes)
Definition as_bytes.h:449
static bool as_bytes_set_byte(as_bytes *bytes, uint32_t index, uint8_t value)
Definition as_bytes.h:696
static bool as_bytes_set_int64(as_bytes *bytes, uint32_t index, int64_t value)
Definition as_bytes.h:744
AS_EXTERN as_bytes * as_bytes_new_wrap(uint8_t *value, uint32_t size, bool free)
AS_EXTERN uint32_t as_bytes_set_var_int(const as_bytes *bytes, uint32_t index, uint32_t value)
static uint32_t as_bytes_size(const as_bytes *bytes)
Definition as_bytes.h:419
uint8_t * value
Definition as_bytes.h:272