All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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
25 extern "C" {
26 #endif
27 
28 /******************************************************************************
29  * TYPES
30  *****************************************************************************/
31 
32 /**
33  * Types for `as_bytes.type`
34  */
35 typedef 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 
127 } as_bytes_type;
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  */
250 typedef 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  */
332 AS_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  */
353 AS_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  */
369 AS_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  */
388 AS_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  */
401 static 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  */
419 static 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  */
434 static 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  */
449 static 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  */
463 static 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  */
485 static 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  */
503 static 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  */
537 AS_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  */
555 static 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  */
576 static 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  */
597 static 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  */
618 static 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  */
639 static 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  */
660 AS_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  */
683 AS_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  */
696 static 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  */
712 static 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  */
728 static 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  */
744 static 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  */
760 static 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  */
781 AS_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  */
804 AS_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  */
817 static 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  */
833 static 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  */
849 static 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  */
865 static 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  */
881 static 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  */
910 AS_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  */
937 AS_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  */
947 static 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  */
967 static 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  */
977 static inline as_bytes * as_bytes_fromval(const as_val * v)
978 {
979  return as_util_fromval(v, AS_BYTES, as_bytes);
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  */
996 AS_EXTERN uint32_t as_bytes_val_hashcode(const as_val * v);
997 
998 /**
999  * @private
1000  * Internal helper function for getting the string representation of an as_val.
1001  */
1002 AS_EXTERN char * as_bytes_val_tostring(const as_val * v);
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  */
1018 AS_EXTERN bool
1019 as_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  */
1031 AS_EXTERN bool
1032 as_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  */
1043 AS_EXTERN int
1044 as_bytes_from_string(uint8_t* bytes, uint32_t bytes_size, const char* str);
1045 
1046 #ifdef __cplusplus
1047 } // end extern "C"
1048 #endif
AS_EXTERN uint32_t as_bytes_copy(const as_bytes *bytes, uint32_t index, uint8_t *value, uint32_t size)
static as_val * as_bytes_toval(const as_bytes *b)
Definition: as_bytes.h:967
AS_EXTERN as_bytes * as_bytes_init(as_bytes *bytes, uint32_t capacity)
AS_EXTERN bool as_bytes_truncate(as_bytes *bytes, uint32_t n)
uint8_t type
Definition: as_proto.h:36
AS_EXTERN bool as_bytes_set(as_bytes *bytes, uint32_t index, const uint8_t *value, uint32_t size)
static uint32_t as_bytes_get_int32(const as_bytes *bytes, uint32_t index, int32_t *value)
Definition: as_bytes.h:597
static uint32_t as_bytes_get_int16(const as_bytes *bytes, uint32_t index, int16_t *value)
Definition: as_bytes.h:576
static bool as_bytes_set_int16(as_bytes *bytes, uint32_t index, int16_t value)
Definition: as_bytes.h:712
static void as_bytes_destroy(as_bytes *bytes)
Definition: as_bytes.h:401
#define as_util_fromval(object, type_id, type)
Definition: as_util.h:43
as_bytes_type type
Definition: as_bytes.h:283
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_size(const as_bytes *bytes)
Definition: as_bytes.h:419
uint32_t capacity
Definition: as_bytes.h:262
static bool as_bytes_set_int64(as_bytes *bytes, uint32_t index, int64_t value)
Definition: as_bytes.h:744
Definition: as_val.h:61
static uint32_t as_bytes_get_byte(const as_bytes *bytes, uint32_t index, uint8_t *value)
Definition: as_bytes.h:555
static uint32_t as_bytes_get_int64(const as_bytes *bytes, uint32_t index, int64_t *value)
Definition: as_bytes.h:618
static bool as_bytes_append_int16(as_bytes *bytes, int16_t value)
Definition: as_bytes.h:833
static uint8_t * as_bytes_getorelse(const as_bytes *bytes, uint8_t *fallback)
Definition: as_bytes.h:485
AS_EXTERN bool as_bytes_ensure(as_bytes *bytes, uint32_t capacity, bool resize)
AS_EXTERN bool as_bytes_append(as_bytes *bytes, const uint8_t *value, uint32_t size)
#define AS_EXTERN
Definition: as_std.h:25
AS_EXTERN char * as_bytes_val_tostring(const as_val *v)
static void as_bytes_set_type(as_bytes *bytes, as_bytes_type type)
Definition: as_bytes.h:463
static uint8_t * as_bytes_get(const as_bytes *bytes)
Definition: as_bytes.h:503
static bool as_bytes_set_double(as_bytes *bytes, uint32_t index, double value)
Definition: as_bytes.h:760
AS_EXTERN bool as_bytes_to_string_with_prefix(const uint8_t *bytes, uint32_t bytes_size, char *str, uint32_t str_size)
uint8_t * value
Definition: as_bytes.h:272
static as_bytes * as_bytes_fromval(const as_val *v)
Definition: as_bytes.h:977
AS_EXTERN as_bytes * as_bytes_init_wrap(as_bytes *bytes, uint8_t *value, uint32_t size, bool free)
static bool as_bytes_append_int64(as_bytes *bytes, int64_t value)
Definition: as_bytes.h:865
static as_bytes_type as_bytes_get_type(const as_bytes *bytes)
Definition: as_bytes.h:449
bool free
Definition: as_bytes.h:278
as_bytes_type
Definition: as_bytes.h:35
AS_EXTERN void as_bytes_val_destroy(as_val *v)
uint32_t size
Definition: as_bytes.h:267
#define as_val_destroy(__v)
Definition: as_val.h:114
AS_EXTERN uint32_t as_bytes_val_hashcode(const as_val *v)
static bool as_bytes_set_byte(as_bytes *bytes, uint32_t index, uint8_t value)
Definition: as_bytes.h:696
static bool as_bytes_append_double(as_bytes *bytes, double value)
Definition: as_bytes.h:881
static uint8_t * as_bytes_tobytes(const as_bytes *bytes, uint32_t *size)
Definition: as_bytes.h:947
static bool as_bytes_set_int32(as_bytes *bytes, uint32_t index, int32_t value)
Definition: as_bytes.h:728
static uint32_t as_bytes_capacity(const as_bytes *bytes)
Definition: as_bytes.h:434
AS_EXTERN as_bytes * as_bytes_new_wrap(uint8_t *value, uint32_t size, bool free)
AS_EXTERN uint32_t as_bytes_get_var_int(const as_bytes *bytes, uint32_t index, uint32_t *value)
AS_EXTERN int as_bytes_from_string(uint8_t *bytes, uint32_t bytes_size, const char *str)
AS_EXTERN uint32_t as_bytes_set_var_int(const as_bytes *bytes, uint32_t index, uint32_t value)
AS_EXTERN as_bytes * as_bytes_new(uint32_t capacity)
static bool as_bytes_append_int32(as_bytes *bytes, int32_t value)
Definition: as_bytes.h:849
AS_EXTERN bool as_bytes_to_string(const uint8_t *bytes, uint32_t bytes_size, char *str, uint32_t str_size)
static bool as_bytes_append_byte(as_bytes *bytes, uint8_t value)
Definition: as_bytes.h:817