All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_record.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2008-2013 by Aerospike.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20  * IN THE SOFTWARE.
21  *****************************************************************************/
22 
23 #pragma once
24 
25 #include <aerospike/as_bin.h>
26 #include <aerospike/as_bytes.h>
27 #include <aerospike/as_integer.h>
28 #include <aerospike/as_key.h>
29 #include <aerospike/as_list.h>
30 #include <aerospike/as_map.h>
31 #include <aerospike/as_rec.h>
32 #include <aerospike/as_string.h>
33 #include <aerospike/as_util.h>
34 #include <aerospike/as_val.h>
35 
36 #include <stdbool.h>
37 #include <stdint.h>
38 
39 /******************************************************************************
40  * TYPES
41  *****************************************************************************/
42 
43 /**
44  * Records in Aerospike are collections of named bins.
45  *
46  * The bins in a record are analogous to columns in relational databases.
47  * However, unlike columns, the bins themselves are not typed. Instead, bins
48  * contain values which are typed. So, it is possible to have multiple records
49  * with bins of the same name but different types for values.
50  *
51  * The bin's value can only be of the types defined in `as_bin_value`.
52  *
53  * ## Initialization
54  *
55  * There are several ways to initialize an `as_record`.
56  *
57  * You can create the `as_record` on the stack:
58  *
59  * ~~~~~~~~~~{.c}
60  * as_record rec;
61  * ~~~~~~~~~~
62  *
63  * Then initialize it using either the `as_record_init()` function or
64  * `as_record_inita()` macro.
65  *
66  * The `as_record_init()` function will initialize the variable, then
67  * allocate the specified number of bins using `malloc()`. The following
68  * initializes `rec` with 2 bins.
69  *
70  * ~~~~~~~~~~{.c}
71  * as_record_init(&rec, 2);
72  * ~~~~~~~~~~
73  *
74  * The `as_record_inita()` macro will initialize the variable, then allocate
75  * the specified number of bins using `alloca()`. The following initializes
76  * `rec` with 2 bins.
77  *
78  * ~~~~~~~~~~{.c}
79  * as_record_inita(&rec, 2);
80  * ~~~~~~~~~~
81  *
82  * The `as_record_new()` function will allocate an `as_record` on the heap
83  * using `malloc()` then allocate the specified number of bins using
84  * `malloc()`. The following creates a new `as_record` with 2 bins.
85  *
86  * ~~~~~~~~~~{.c}
87  * as_record * rec = as_record_new(2);
88  * ~~~~~~~~~~
89  *
90  * ## Destruction
91  *
92  * When you no longer require an as_record, you should call `as_record_destroy()`
93  * to release the record and associated resources.
94  *
95  * ~~~~~~~~~~{.c}
96  * as_record_destroy(rec);
97  * ~~~~~~~~~~
98  *
99  * If the record has been ref-counted, then the ref-count will be decremented,
100  * until it reaches 0 (zero), at which point, the record will be released.
101  *
102  * ## Setting Bin Values
103  *
104  * The following are functions for setting values in bins of a record. Utilize
105  * the appropriate setter for the data you want to store in a bin.
106  *
107  * Function | Description
108  * ---------------------------- | ----------------------------------------------
109  * `as_record_set_int64()` | Set the bin value to a 64-bit integer.
110  * `as_record_set_str()` | Set the bin value to a NULL-terminated string.
111  * `as_record_set_integer()` | Set the bin value to an `as_integer`.
112  * `as_record_set_string()` | Set the bin value to an `as_string`.
113  * `as_record_set_bytes()` | Set the bin value to an `as_bytes`.
114  * `as_record_set_list()` | Set the bin value to an `as_list`.
115  * `as_record_set_map()` | Set the bin value to an `as_map`.
116  * `as_record_set_nil()` | Set the bin value to an `as_nil`.
117  * `as_record_set()` | Set the bin value to an `as_bin_value`.
118  *
119  * ## Getting Bin Values
120  *
121  * The following are functions for getting values from bins of a record.
122  * Utilize the appropriate getter for the data you want to read from a bin.
123  *
124  *
125  * Function | Description
126  * ---------------------------- | ----------------------------------------------
127  * `as_record_get_int64()` | Get the bin as a 64-bit integer.
128  * `as_record_get_str()` | Get the bin as a NULL-terminated string.
129  * `as_record_get_integer()` | Get the bin as an `as_integer`.
130  * `as_record_get_string()` | Get the bin as an `as_string`.
131  * `as_record_get_bytes()` | Get the bin as an `as_bytes`.
132  * `as_record_get_list()` | Get the bin as an `as_list`.
133  * `as_record_get_map()` | Get the bin as an `as_map`.
134  * `as_record_get()` | Get the bin as an `as_bin_value`.
135  *
136  * If you are unsure of the type of data stored in the bin, then you should
137  * use `as_record_get()`. You can then check the type of the value using
138  * `as_val_type()`.
139  *
140  * ~~~~~~~~~~{.c}
141  * as_val * value = as_record_get(rec, "bin1");
142  * switch ( as_val_type(value) ) {
143  * case AS_NIL: break;
144  * case AS_INTEGER: break;
145  * case AS_STRING: break;
146  * case AS_BYTES: break;
147  * case AS_LIST: break;
148  * case AS_MAP: break;
149  * case AS_REC: break;
150  * case AS_UNDEF: break;
151  * }
152  * ~~~~~~~~~~
153  *
154  * ## Traversing Bins
155  *
156  * If you want to traverse the bins of a record, then you have two options:
157  *
158  * - as_record_foreach() — Calls a function for each bin traversed.
159  * - as_record_iterator — Uses an iterator pattern to traverse bins.
160  *
161  * @extends as_rec
162  * @ingroup client_objects
163  */
164 typedef struct as_record_s {
165 
166  /**
167  * @private
168  * as_record is "derived" from as_rec.
169  * So you can actually type cast as_record to as_rec.
170  */
172 
173  /**
174  * The key of the record.
175  * This is populated when a record is read from the database.
176  * This should not be set by the user.
177  */
179 
180  /**
181  * The generation of the record.
182  */
183  uint16_t gen;
184 
185  /**
186  * The time-to-live (expiration) of the record in seconds.
187  * There are two special values that can be set in the record TTL:
188  * (*) ZERO (defined as AS_RECORD_DEFAULT_TTL), which means that the
189  * record will adopt the default TTL value from the namespace.
190  * (*) 0xFFFFFFFF (also, -1 in a signed 32 bit int)
191  * (defined as AS_RECORD_NO_EXPIRE_TTL), which means that the record
192  * will get an internal "void_time" of zero, and thus will never expire.
193  *
194  * Note that the TTL value will be employed ONLY on write/update calls.
195  */
196  uint32_t ttl;
197 
198  /**
199  * The bins of the record.
200  */
202 
203 } as_record;
204 
205 /**
206  * When the record is given a TTL value of ZERO, it will adopt the TTL value
207  * that is the default TTL value for the namespace (defined in the config file).
208  */
209 #define AS_RECORD_DEFAULT_TTL 0
210 
211 /**
212  * When the record is given a TTL value of 0xFFFFFFFF, it will set the internal
213  * void_time value (the absolute clock time value that shows when a record
214  * will expire) to zero, which means the record will never expire
215  */
216 #define AS_RECORD_NO_EXPIRE_TTL 0xFFFFFFFF
217 
218 /******************************************************************************
219  * MACROS
220  *****************************************************************************/
221 
222 /**
223  * Initialize a stack allocated `as_record` then allocate `__nbins` capacity
224  * for as_record.bins on the stack.
225  *
226  * ~~~~~~~~~~{.c}
227  * as_record record;
228  * as_record_inita(&record, 2);
229  * as_record_set_int64(&record, "bin1", 123);
230  * as_record_set_int64(&record, "bin2", 456);
231  * ~~~~~~~~~~
232  *
233  * When you are finished using the `as_record` instance, you should release the
234  * resources allocated to it by calling `as_record_destroy()`.
235  *
236  * @param __rec The `as_record *` to initialize.
237  * @param __nbins The number of `as_record.bins.entries` to allocate on the
238  * stack.
239  *
240  * @relates as_record
241  */
242 #define as_record_inita(__rec, __nbins) \
243  as_record_init(__rec, 0);\
244  (__rec)->bins._free = false;\
245  (__rec)->bins.capacity = __nbins;\
246  (__rec)->bins.size = 0;\
247  (__rec)->bins.entries = (as_bin *) alloca(sizeof(as_bin) * __nbins);
248 
249 /******************************************************************************
250  * FUNCTIONS
251  *****************************************************************************/
252 
253 /**
254  * Create a new as_record on the heap.
255  *
256  * ~~~~~~~~~~{.c}
257  * as_record * r = as_record_new(2);
258  * as_record_set_int64(r, "bin1", 123);
259  * as_record_set_str(r, "bin1", "abc");
260  * ~~~~~~~~~~
261  *
262  * When you are finished using the `as_record` instance, you should release the
263  * resources allocated to it by calling `as_record_destroy()`.
264  *
265  * @param nbins The number of bins to initialize. Set to 0, if unknown.
266  *
267  * @return a pointer to the new as_record if successful, otherwise NULL.
268  *
269  * @relates as_record
270  */
271 as_record * as_record_new(uint16_t nbins);
272 
273 /**
274  * Initializes an as_record created on the stack.
275  *
276  * ~~~~~~~~~~{.c}
277  * as_record r;
278  * as_record_init(&r, 2);
279  * as_record_set_int64(&r, "bin1", 123);
280  * as_record_set_str(&r, "bin1", "abc");
281  * ~~~~~~~~~~
282  *
283  * When you are finished using the `as_record` instance, you should release the
284  * resources allocated to it by calling `as_record_destroy()`.
285  *
286  * @param rec The record to initialize.
287  * @param nbins The number of bins to initialize. Set to 0, if unknown.
288  *
289  * @return a pointer to the initialized as_record if successful, otherwise NULL.
290  *
291  * @relates as_record
292  */
293 as_record * as_record_init(as_record * rec, uint16_t nbins);
294 
295 /**
296  * Destroy the as_record and associated resources.
297  *
298  * @param rec The record to destroy.
299  *
300  * @relates as_record
301  */
302 void as_record_destroy(as_record * rec);
303 
304 /**
305  * Get the number of bins in the record.
306  *
307  * @return the number of bins in the record.
308  *
309  * @relates as_record
310  */
311 uint16_t as_record_numbins(const as_record * rec);
312 
313 /**
314  * Set specified bin's value to an as_bin_value.
315  *
316  * @param rec The record containing the bin.
317  * @param name The name of the bin.
318  * @param value The value of the bin.
319  *
320  * @return true on success, false on failure.
321  *
322  * @relates as_record
323  */
324 bool as_record_set(as_record * rec, const as_bin_name name, as_bin_value * value);
325 
326 /**
327  * Set specified bin's value to an int64_t.
328  *
329  * ~~~~~~~~~~{.c}
330  * as_record_set_int64(rec, "bin", 123);
331  * ~~~~~~~~~~
332  *
333  * @param rec The record containing the bin.
334  * @param name The name of the bin.
335  * @param value The value of the bin.
336  *
337  * @return true on success, false on failure.
338  *
339  * @relates as_record
340  */
341 bool as_record_set_int64(as_record * rec, const as_bin_name name, int64_t value);
342 
343 /**
344  * Set specified bin's value to an NULL terminated string.
345  *
346  * ~~~~~~~~~~{.c}
347  * as_record_set_strp(rec, "bin", strdup("abc"), true);
348  * ~~~~~~~~~~
349  *
350  * @param rec The record containing the bin.
351  * @param name The name of the bin.
352  * @param value The value of the bin.
353  * @param free If true, then the value will be freed when the record is destroyed.
354  *
355  * @return true on success, false on failure.
356  *
357  * @relates as_record
358  */
359 bool as_record_set_strp(as_record * rec, const as_bin_name name, const char * value, bool free);
360 
361 /**
362  * Set specified bin's value to an NULL terminated string.
363  *
364  * ~~~~~~~~~~{.c}
365  * as_record_set_str(rec, "bin", "abc");
366  * ~~~~~~~~~~
367  *
368  * @param rec The record containing the bin.
369  * @param name The name of the bin.
370  * @param value The value of the bin. Must last for the lifetime of the record.
371  *
372  * @return true on success, false on failure.
373  *
374  * @relates as_record
375  */
376 static inline bool as_record_set_str(as_record * rec, const as_bin_name name, const char * value)
377 {
378  return as_record_set_strp(rec, name, value, false);
379 }
380 
381 /**
382  * Set specified bin's value to an NULL terminated string.
383  *
384  * ~~~~~~~~~~{.c}
385  * uint8_t * bytes = (uint8_t *) malloc(3);
386  * bytes[0] = 1;
387  * bytes[1] = 2;
388  * bytes[3] = 3;
389  *
390  * as_record_set_raw(rec, "bin", bytes, 3, true);
391  * ~~~~~~~~~~
392  *
393  * @param rec The record containing the bin.
394  * @param name The name of the bin.
395  * @param value The value of the bin.
396  * @param size The size of the value.
397  * @param free If true, then the value will be freed when the record is destroyed.
398  *
399  * @return true on success, false on failure.
400  *
401  * @relates as_record
402  */
403 bool as_record_set_rawp(as_record * rec, const as_bin_name name, const uint8_t * value, uint32_t size, bool free);
404 
405 /**
406  * Set specified bin's value to an as_bytes value of a specified type.
407  *
408  * ~~~~~~~~~~{.c}
409  * uint8_t * bytes = (uint8_t *) malloc(3);
410  * bytes[0] = 1;
411  * bytes[1] = 2;
412  * bytes[3] = 3;
413  *
414  * as_record_set_raw(rec, "bin", bytes, 3, true);
415  * ~~~~~~~~~~
416  *
417  * @param rec The record containing the bin.
418  * @param name The name of the bin.
419  * @param value The value of the bin.
420  * @param size The size of the value.
421  * @param type The as_bytes_type designation (AS_BYTES_*)
422  * @param free If true, then the value will be freed when the record is destroyed.
423  *
424  * @return true on success, false on failure.
425  *
426  * @relates as_record
427  */
428 bool as_record_set_raw_typep(as_record * rec, const as_bin_name name, const uint8_t * value, uint32_t size, as_bytes_type type, bool free);
429 
430 /**
431  * Set specified bin's value to an NULL terminated string.
432  *
433  * ~~~~~~~~~~{.c}
434  * uint8_t bytes[3] = {1,2,3};
435  * as_record_set_raw(rec, "bin", bytes, 3);
436  * ~~~~~~~~~~
437  *
438  * @param rec The record containing the bin.
439  * @param name The name of the bin.
440  * @param value The value of the bin.
441  * @param size The size of the value. Must last for the lifetime of the record.
442  *
443  * @return true on success, false on failure.
444  *
445  * @relates as_record
446  */
447 static inline bool as_record_set_raw(as_record * rec, const as_bin_name name, const uint8_t * value, uint32_t size)
448 {
449  return as_record_set_rawp(rec, name, value, size, false);
450 }
451 
452 /**
453  * Set specified bin's value to an as_integer.
454  *
455  * ~~~~~~~~~~{.c}
456  * as_record_set_integer(rec, "bin", as_integer_new(123));
457  * ~~~~~~~~~~
458  *
459  * @param rec The record containing the bin.
460  * @param name The name of the bin.
461  * @param value The value of the bin.
462  *
463  * @return true on success, false on failure.
464  *
465  * @relates as_record
466  */
467 bool as_record_set_integer(as_record * rec, const as_bin_name name, as_integer * value);
468 
469 /**
470  * Set specified bin's value to an as_string.
471  *
472  * ~~~~~~~~~~{.c}
473  * as_record_set_string(rec, "bin", as_string_new("abc", false));
474  * ~~~~~~~~~~
475  *
476  * @param rec The record containing the bin.
477  * @param name The name of the bin.
478  * @param value The value of the bin.
479  *
480  * @return true on success, false on failure.
481  *
482  * @relates as_record
483  */
484 bool as_record_set_string(as_record * rec, const as_bin_name name, as_string * value);
485 
486 /**
487  * Set specified bin's value to an as_bytes.
488  *
489  * ~~~~~~~~~~{.c}
490  * as_record_set_integer(rec, "bin", bytes);
491  * ~~~~~~~~~~
492  *
493  * @param rec The record containing the bin.
494  * @param name The name of the bin.
495  * @param value The value of the bin.
496  *
497  * @return true on success, false on failure.
498  *
499  * @relates as_record
500  */
501 bool as_record_set_bytes(as_record * rec, const as_bin_name name, as_bytes * value);
502 
503 /**
504  * Set specified bin's value to an as_list.
505  *
506  * ~~~~~~~~~~{.c}
507  * as_arraylist list;
508  * as_arraylist_init(&list);
509  * as_arraylist_add_int64(&list, 1);
510  * as_arraylist_add_int64(&list, 2);
511  * as_arraylist_add_int64(&list, 3);
512  *
513  * as_record_set_list(rec, "bin", &list);
514  * ~~~~~~~~~~
515  *
516  * @param rec The record containing the bin.
517  * @param name The name of the bin.
518  * @param value The value of the bin.
519  *
520  * @return true on success, false on failure.
521  *
522  * @relates as_record
523  */
524 bool as_record_set_list(as_record * rec, const as_bin_name name, as_list * value);
525 
526 /**
527  * Set specified bin's value to an as_map.
528  *
529  * ~~~~~~~~~~{.c}
530  * as_map map;
531  * as_stringmap_init(&map);
532  * as_stringmap_set_int64(&map, "a", 1);
533  * as_stringmap_set_int64(&map, "b", 2);
534  * as_stringmap_set_int64(&map, "c", 3);
535  *
536  * as_record_set_map(rec, "bin", &map);
537  * ~~~~~~~~~~
538  *
539  * @param rec The record containing the bin.
540  * @param name The name of the bin.
541  * @param value The value of the bin.
542  *
543  * @return true on success, false on failure.
544  *
545  * @relates as_record
546  */
547 bool as_record_set_map(as_record * rec, const as_bin_name name, as_map * value);
548 
549 /**
550  * Set specified bin's value to as_nil.
551  *
552  * ~~~~~~~~~~{.c}
553  * as_record_set_nil(rec, "bin");
554  * ~~~~~~~~~~
555  *
556  * @param rec The record containing the bin.
557  * @param name The name of the bin.
558  *
559  * @return true on success, false on failure.
560  *
561  * @relates as_record
562  */
563 bool as_record_set_nil(as_record * rec, const as_bin_name name);
564 
565 /**
566  * Get specified bin's value.
567  *
568  * ~~~~~~~~~~{.c}
569  * as_val * value = as_record_get(rec, "bin");
570  * ~~~~~~~~~~
571  *
572  * @param rec The record containing the bin.
573  * @param name The name of the bin.
574  *
575  * @return the value if it exists, otherwise NULL.
576  *
577  * @relates as_record
578  */
579 as_bin_value * as_record_get(const as_record * rec, const as_bin_name name);
580 
581 /**
582  * Get specified bin's value as an int64_t.
583  *
584  * ~~~~~~~~~~{.c}
585  * int64_t value = as_record_get_int64(rec, "bin", INT64_MAX);
586  * ~~~~~~~~~~
587  *
588  * @param rec The record containing the bin.
589  * @param name The name of the bin.
590  * @param fallback The default value to use, if the bin doesn't exist or is not an integer.
591  *
592  * @return the value if it exists, otherwise 0.
593  *
594  * @relates as_record
595  */
596 int64_t as_record_get_int64(const as_record * rec, const as_bin_name name, int64_t fallback);
597 
598 /**
599  * Get specified bin's value as an NULL terminated string.
600  *
601  * ~~~~~~~~~~{.c}
602  * char * value = as_record_get_str(rec, "bin");
603  * ~~~~~~~~~~
604  *
605  * @param rec The record containing the bin.
606  * @param name The name of the bin.
607  *
608  * @return the value if it exists, otherwise NULL.
609  *
610  * @relates as_record
611  */
612 char * as_record_get_str(const as_record * rec, const as_bin_name name);
613 
614 /**
615  * Get specified bin's value as an as_integer.
616  *
617  * ~~~~~~~~~~{.c}
618  * as_integer * value = as_record_get_integer(rec, "bin");
619  * ~~~~~~~~~~
620  *
621  * @param rec The record containing the bin.
622  * @param name The name of the bin.
623  *
624  * @return the value if it exists, otherwise NULL.
625  *
626  * @relates as_record
627  */
628 as_integer * as_record_get_integer(const as_record * rec, const as_bin_name name);
629 
630 /**
631  * Get specified bin's value as an as_string.
632  *
633  * ~~~~~~~~~~{.c}
634  * as_string * value = as_record_get_string(rec, "bin");
635  * ~~~~~~~~~~
636  *
637  * @param rec The record containing the bin.
638  * @param name The name of the bin.
639  *
640  * @return the value if it exists, otherwise NULL.
641  *
642  * @relates as_record
643  */
644 as_string * as_record_get_string(const as_record * rec, const as_bin_name name);
645 
646 /**
647  * Get specified bin's value as an as_bytes.
648  *
649  * ~~~~~~~~~~{.c}
650  * as_bytes * value = as_record_get_bytes(rec, "bin");
651  * ~~~~~~~~~~
652  *
653  * @param rec The record containing the bin.
654  * @param name The name of the bin.
655  *
656  * @return the value if it exists, otherwise NULL.
657  *
658  * @relates as_record
659  */
660 as_bytes * as_record_get_bytes(const as_record * rec, const as_bin_name name);
661 
662 /**
663  * Get specified bin's value as an as_list.
664  *
665  * ~~~~~~~~~~{.c}
666  * as_list * value = as_record_get_list(rec, "bin");
667  * ~~~~~~~~~~
668  *
669  * @param rec The record containing the bin.
670  * @param name The name of the bin.
671  *
672  * @return the value if it exists, otherwise NULL.
673  *
674  * @relates as_record
675  */
676 as_list * as_record_get_list(const as_record * rec, const as_bin_name name);
677 
678 /**
679  * Get specified bin's value as an as_map.
680  *
681  * ~~~~~~~~~~{.c}
682  * as_map * value = as_record_get_map(rec, "bin");
683  * ~~~~~~~~~~
684  *
685  * @param rec The record containing the bin.
686  * @param name The name of the bin.
687  *
688  * @return the value if it exists, otherwise NULL.
689  *
690  * @relates as_record
691  */
692 as_map * as_record_get_map(const as_record * rec, const as_bin_name name);
693 
694 /******************************************************************************
695  * ITERATION FUNCTIONS
696  ******************************************************************************/
697 
698 /**
699  * Iterate over each bin in the record and invoke the callback function.
700  *
701  * ~~~~~~~~~~{.c}
702  * bool print_bin(const char * name, const as_val * value, void * udata) {
703  * char * sval = as_val_tostring(value);
704  * printf("bin: name=%s, value=%s\n", name, sval);
705  * free(sval);
706  * return true;
707  * }
708  *
709  * as_record_foreach(rec, print_bin, NULL);
710  * ~~~~~~~~~~
711  *
712  * If the callback returns true, then iteration will continue to the next bin.
713  * Otherwise, the iteration will halt and `as_record_foreach()` will return
714  * false.
715  *
716  * @param rec The record containing the bins to iterate over.
717  * @param callback The callback to invoke for each bin.
718  * @param udata User-data provided for the callback.
719  *
720  * @return true if iteration completes fully. false if iteration was aborted.
721  *
722  * @relates as_record
723  */
724 bool as_record_foreach(const as_record * rec, as_rec_foreach_callback callback, void * udata);
725 
726 /******************************************************************************
727  * CONVERSION FUNCTIONS
728  ******************************************************************************/
729 
730 /**
731  * Convert to an as_val.
732  *
733  * @relates as_record
734  */
735 static inline as_val * as_record_toval(const as_record * rec)
736 {
737  return (as_val *) rec;
738 }
739 
740 /**
741  * Convert from an as_val.
742  *
743  * @relates as_record
744  */
745 static inline as_record * as_record_fromval(const as_val * v)
746 {
747  return (as_record *) as_util_fromval(v, AS_REC, as_rec);
748 }
749