OmlValueU(3)
============

NAME
----
OmlValueU - manipulation functions

SYNOPSIS
--------
[verse]
*#include <stdint.h>*
*#include <oml2/omlc.h>*
[verse]
'void'   *omlc_zero*('OmlValueU' value); +
'void'   *omlc_zero_array*('OmlValueU' varray[], 'unsigned int' n); +
[verse]
'void'   *omlc_set_int32*('OmlValueU' value, 'int32_t' int32val); +
'void'   *omlc_set_uint32*('OmlValueU' value, 'uint32_t' uint32val); +
'void'   *omlc_set_int64*('OmlValueU' value, 'int64_t' int64val); +
'void'   *omlc_set_uint64*('OmlValueU' value, 'uint64_t' uint64val); +
'void'   *omlc_set_double*('OmlValueU' value, 'double' doubleval); +
'void'   *omlc_set_guid*('OmlValueU' value, 'oml_guid_t' guidval); +
'void'   *omlc_set_bool*('OmlValueU' value, 'uint8_t' bool); +
[verse]
'void'   *omlc_set_string*('OmlValueU' value, 'char*' stringval); +
'void'   *omlc_set_string_copy*('OmlValueU' value, 'char*' stringval); +
'void'   *omlc_copy_string*('OmlValueU' dst, 'OmlValueU' src); +
'void'   *omlc_reset_string*('OmlValueU' var); +
[verse]
'void'   *omlc_set_blob*('OmlValueU' value, 'char*' stringval, 'size_t' len); +
'void'   *omlc_copy_blob*('OmlValueU' dst, 'OmlValueU' src); +
'void'   *omlc_reset_blob*('OmlValueU' var); +
[verse]
'void'   *omlc_set_vector_double*('OmlValueU' value, 'double[]' doubleptr, 'size_t' nof_elts) \
'void'   *omlc_set_vector_int32*('OmlValueU' value, 'int32_t[]' int32ptr, 'size_t' nof_elts) \
'void'   *omlc_set_vector_uint32*('OmlValueU' value, 'uint32_t[]' uint32ptr, 'size_t' nof_elts) \
'void'   *omlc_set_vector_int64*('OmlValueU' value, 'int64_t[]' int64ptr, 'size_t' nof_elts) \
'void'   *omlc_set_vector_uint64*('OmlValueU' value, 'uint64_t[]' uint64ptr, 'size_t' nof_elts) \
'void'   *omlc_set_vector_bool*('OmlValueU' value, 'bool[]' boolptr, 'size_t' nof_elts) \
'void'   *omlc_copy_vector*('OmlValueU' dst, 'OmlValueU' src) \


DESCRIPTION
-----------

These functions are convenience macros for setting the values of an
'OmlValueU' array to be passed to linkoml:omlc_inject[3].  The
underlying 'OmlValueU' array is a simple union, but it should be treated
as an opaque type to ensure backwards compatibility for applications
using OML.  These macros operate on this type.

Before any manipulation, 'OmlValueU' storage needs to be zeroed out
properly to avoid memory corruption issue. This is done through the
'omlc_zero' and 'omlc_zero_array' functions. They can then be
manipulated with the 'omlc_set_*' group of functions described below.

The '(u)int{32,64}' variants are for setting integral types.  The
argument should be one of the equivalent types from *stdint.h*.  The
'double' variant is for setting double precision floating point values.
The 'guid' variant is similar, but is use to inject 'oml_guid_t'
globally unique identifiers generated by
linkomlalias:omlc_guid_generate[liboml2,3].

The 'guid' variant allows to manipulate the opaque GUID values of
'OML_GUID_VALUE' 'MP' fields, used to group measurement samples within
or accross 'MPs'. These values can be generated with
linkomlalias:omlc_guid_generate[liboml2,3]. The special 'NULL' value
'OMLC_GUID_NULL' can also be used as a default in case grouping is
irrelevant for a particular sample. More details on the use of this data
type can be found in linkoml:liboml2[3].

The 'bool' variant allows to manipulates boolean values. It is
recommended to use the shorthands 'OMLC_BOOL_FALSE' and 'OMLC_BOOL_TRUE'
rather than any other value. '0' is equivalent to 'OMLC_BOOL_FALSE',
while anything different is equivalent to 'OMLC_BOOL_TRUE'. There is no
guarantee that anything non '0' will retain its specific value in the
'OmlValueU'.

The 'string' variant is for setting nul-terminated string values. Note
that only the pointer is copied by the macro, but that the library
internally copies the caller's string into its own internally managed
memory, so the caller does not need to worry about preserving the string
after any call to linkoml:omlc_inject[3] on the 'OmlValueU' array. The
'string_copy' variant actually duplicates the string in dynamically
allocated storage. To avoid memory leaks, it is advised to use
'omlc_reset_string' on an 'OmlValueU' which last contained strings prior
to reusing them for other types.

The 'blob' variant is for storing arbitrary binary data. The data is
copied in a dynamically allocated memory buffer. To avoid memory leaks,
'omlc_reset_blob' must be used on an 'OmlValueU' which last contained
blobs prior to reusing them for other types.

The 'vector' variants are used to assign a variable-sized vector of
primitive values (of types (u)int{32,64}_t, double and bool) to a
single 'OmlValueU'. The vector is specified by passing a pointer to
the base element and the number of elements that the vector
contains. To avoid memory leaks, it is advised to use
'omlc_reset_vector' on an 'OmlValueU' which last contained a vector
prior to reusing them for other types.

The 'copy_*' variants do a deep copy of the 'OmlValueU' of the relevant
type, duplicating the stored data in a dynamically allocated memory
buffer.

For an example of how these macros should be used, refer
to linkoml:omlc_inject[3] and linkoml:liboml2[3].

RETURN VALUE
------------

These functions are defined as macros and so don't return values.
They should be treated as separate statements, rather than as proper
functions.  In a future version of OML they may be converted to real
inline functions.

BUGS
----
C preprocessor macros are generally brittle and error prone.
Unfortunately, they are all we've got.

include::bugs.txt[]

SEE ALSO
--------
Manual Pages
~~~~~~~~~~~~
linkoml:liboml2[3], linkoml:omlc_inject[3]

include::manual.txt[]

// vim: ft=asciidoc:tw=72
