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