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