ALIASES += bt_pre_is_uenum_fc{1}="@pre \bt_p{\1} is an unsigned \link api-tir-fc-enum enumeration field class\endlink."
ALIASES += bt_pre_is_senum_fc{1}="@pre \bt_p{\1} is a signed \link api-tir-fc-enum enumeration field class\endlink."
ALIASES += bt_pre_is_string_fc{1}="@pre \bt_p{\1} is a \link api-tir-fc-string string field class\endlink."
+ALIASES += bt_pre_is_blob_fc{1}="@pre \bt_p{\1} is a BLOB \link api-tir-fc-blob field class\endlink."
+ALIASES += bt_pre_is_sblob_fc{1}="@pre \bt_p{\1} is a static \link api-tir-fc-blob BLOB field class\endlink."
+ALIASES += bt_pre_is_dblob_fc{1}="@pre \bt_p{\1} is a dynamic \link api-tir-fc-blob BLOB field class\endlink."
+ALIASES += bt_pre_is_dblob_wl_fc{1}="@pre \bt_p{\1} is a dynamic \link api-tir-fc-blob BLOB field class\endlink (instances with a linked length field)."
ALIASES += bt_pre_is_struct_fc{1}="@pre \bt_p{\1} is a \link api-tir-fc-struct structure field class\endlink."
ALIASES += bt_pre_is_array_fc{1}="@pre \bt_p{\1} is an array \link api-tir-fc-array field class\endlink."
ALIASES += bt_pre_is_sarray_fc{1}="@pre \bt_p{\1} is a static \link api-tir-fc-array array field class\endlink."
ALIASES += bt_pre_is_uenum_field{1}="@pre \bt_p{\1} is an unsigned \link api-tir-field-enum enumeration field\endlink."
ALIASES += bt_pre_is_senum_field{1}="@pre \bt_p{\1} is a signed \link api-tir-field-enum enumeration field\endlink."
ALIASES += bt_pre_is_string_field{1}="@pre \bt_p{\1} is a \link api-tir-field-string string field\endlink."
+ALIASES += bt_pre_is_blob_field{1}="@pre \bt_p{\1} is a \link api-tir-field-blob BLOB field\endlink."
+ALIASES += bt_pre_is_sblob_field{1}="@pre \bt_p{\1} is a static \link api-tir-field-blob BLOB field\endlink."
+ALIASES += bt_pre_is_dblob_field{1}="@pre \bt_p{\1} is a dynamic \link api-tir-field-blob BLOB field\endlink."
ALIASES += bt_pre_is_struct_field{1}="@pre \bt_p{\1} is a \link api-tir-field-struct structure field\endlink."
ALIASES += bt_pre_is_array_field{1}="@pre \bt_p{\1} is an \link api-tir-field-array array field\endlink."
ALIASES += bt_pre_is_sarray_field{1}="@pre \bt_p{\1} is a static \link api-tir-field-array array field\endlink."
# Aliases: preconditions: MIP version
ALIASES += bt_pre_tc_with_mip{2}="@pre \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version \2."
ALIASES += bt_pre_fc_with_mip{2}="@pre \bt_p{\1} was created from a \bt_trace_cls which was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version \2."
+ALIASES += bt_pre_field_with_mip{2}="@pre The class of \bt_p{\1} was created from a \bt_trace_cls which was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version \2."
ALIASES += bt_pre_trace_with_mip{2}="@pre The \link api-tir-trace-cls class\endlink of \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version \2."
ALIASES += bt_pre_clock_cls_with_mip{2}="@pre \bt_p{\1} was created from a \bt_comp which belongs to a trace processing \bt_graph with the effective \bt_mip version \2."
ALIASES += bt_senum_fc="signed \link api-tir-fc-enum enumeration field class\endlink"
ALIASES += bt_uenum_fc="unsigned \link api-tir-fc-enum enumeration field class\endlink"
ALIASES += bt_string_fc="\link api-tir-fc-string string field class\endlink"
+ALIASES += bt_blob_fc="\link api-tir-fc-blob BLOB field class\endlink"
+ALIASES += bt_sblob_fc="static \link api-tir-fc-blob BLOB field class\endlink"
+ALIASES += bt_dblob_fc="dynamic \link api-tir-fc-blob BLOB field class\endlink"
ALIASES += bt_struct_fc="\link api-tir-fc-struct structure field class\endlink"
ALIASES += bt_array_fc="\link api-tir-fc-array array field class\endlink"
ALIASES += bt_sarray_fc="static \link api-tir-fc-array array field class\endlink"
ALIASES += bt_c_senum_fc="Signed \link api-tir-fc-enum enumeration field class\endlink"
ALIASES += bt_c_uenum_fc="Unsigned \link api-tir-fc-enum enumeration field class\endlink"
ALIASES += bt_c_string_fc="\link api-tir-fc-string String field class\endlink"
+ALIASES += bt_c_blob_fc="\link api-tir-fc-blob BLOB field class\endlink"
+ALIASES += bt_c_sblob_fc="Static \link api-tir-fc-blob BLOB field class\endlink"
+ALIASES += bt_c_dblob_fc="Dynamic \link api-tir-fc-blob BLOB field class\endlink"
ALIASES += bt_c_struct_fc="\link api-tir-fc-struct Structure field class\endlink"
ALIASES += bt_c_array_fc="\link api-tir-fc-array Array field class\endlink"
ALIASES += bt_c_sarray_fc="Static \link api-tir-fc-array array field class\endlink"
ALIASES += bt_p_senum_fc="signed \link api-tir-fc-enum enumeration field classes\endlink"
ALIASES += bt_p_uenum_fc="unsigned \link api-tir-fc-enum enumeration field classes\endlink"
ALIASES += bt_p_string_fc="\link api-tir-fc-string string field classes\endlink"
+ALIASES += bt_p_blob_fc="\link api-tir-fc-blob BLOB field classes\endlink"
+ALIASES += bt_p_sblob_fc="static \link api-tir-fc-blob BLOB field classes\endlink"
+ALIASES += bt_p_dblob_fc="dynamic \link api-tir-fc-blob BLOB field classes\endlink"
ALIASES += bt_p_struct_fc="\link api-tir-fc-struct structure field classes\endlink"
ALIASES += bt_p_array_fc="\link api-tir-fc-array array field classes\endlink"
ALIASES += bt_p_sarray_fc="static \link api-tir-fc-array array field classes\endlink"
ALIASES += bt_cp_senum_fc="Signed \link api-tir-fc-enum enumeration field classes\endlink"
ALIASES += bt_cp_uenum_fc="Unsigned \link api-tir-fc-enum enumeration field classes\endlink"
ALIASES += bt_cp_string_fc="\link api-tir-fc-string String field classes\endlink"
+ALIASES += bt_cp_blob_fc="\link api-tir-fc-blob BLOB field classes\endlink"
+ALIASES += bt_cp_sblob_fc="Static \link api-tir-fc-blob BLOB field classes\endlink"
+ALIASES += bt_cp_dblob_fc="Dynamic \link api-tir-fc-blob BLOB field classes\endlink"
ALIASES += bt_cp_struct_fc="\link api-tir-fc-struct Structure field classes\endlink"
ALIASES += bt_cp_array_fc="\link api-tir-fc-array Array field classes\endlink"
ALIASES += bt_cp_sarray_fc="Static \link api-tir-fc-array array field classes\endlink"
ALIASES += bt_senum_field="signed \link api-tir-field-enum enumeration field\endlink"
ALIASES += bt_uenum_field="unsigned \link api-tir-field-enum enumeration field\endlink"
ALIASES += bt_string_field="\link api-tir-field-string string field\endlink"
+ALIASES += bt_blob_field="\link api-tir-field-blob BLOB field\endlink"
+ALIASES += bt_sblob_field="static \link api-tir-field-blob BLOB field\endlink"
+ALIASES += bt_dblob_field="dynamic \link api-tir-field-blob BLOB field\endlink"
ALIASES += bt_struct_field="\link api-tir-field-struct structure field\endlink"
ALIASES += bt_array_field="\link api-tir-field-array array field\endlink"
ALIASES += bt_sarray_field="static \link api-tir-field-array array field\endlink"
ALIASES += bt_c_senum_field="Signed \link api-tir-field-enum enumeration field\endlink"
ALIASES += bt_c_uenum_field="Unsigned \link api-tir-field-enum enumeration field\endlink"
ALIASES += bt_c_string_field="\link api-tir-field-string String field\endlink"
+ALIASES += bt_c_blob_field="\link api-tir-field-blob BLOB field\endlink"
+ALIASES += bt_c_sblob_field="Static \link api-tir-field-blob BLOB field\endlink"
+ALIASES += bt_c_dblob_field="Dynamic \link api-tir-field-blob BLOB field\endlink"
ALIASES += bt_c_struct_field="\link api-tir-field-struct Structure field\endlink"
ALIASES += bt_c_array_field="\link api-tir-field-array Array field\endlink"
ALIASES += bt_c_sarray_field="Static \link api-tir-field-array array field\endlink"
ALIASES += bt_p_senum_field="signed \link api-tir-field-enum enumeration fields\endlink"
ALIASES += bt_p_uenum_field="unsigned \link api-tir-field-enum enumeration fields\endlink"
ALIASES += bt_p_string_field="\link api-tir-field-string string fields\endlink"
+ALIASES += bt_p_blob_field="\link api-tir-field-blob BLOB fields\endlink"
+ALIASES += bt_p_sblob_field="static \link api-tir-field-blob BLOB fields\endlink"
+ALIASES += bt_p_dblob_field="dynamic \link api-tir-field-blob BLOB fields\endlink"
ALIASES += bt_p_struct_field="\link api-tir-field-struct structure fields\endlink"
ALIASES += bt_p_array_field="\link api-tir-field-array array fields\endlink"
ALIASES += bt_p_sarray_field="static \link api-tir-field-array array fields\endlink"
ALIASES += bt_cp_senum_field="Signed \link api-tir-field-enum enumeration fields\endlink"
ALIASES += bt_cp_uenum_field="Unsigned \link api-tir-field-enum enumeration fields\endlink"
ALIASES += bt_cp_string_field="\link api-tir-field-string String fields\endlink"
+ALIASES += bt_cp_blob_field="\link api-tir-field-blob BLOB fields\endlink"
+ALIASES += bt_cp_sblob_field="Static \link api-tir-field-blob BLOB fields\endlink"
+ALIASES += bt_cp_dblob_field="Dynamic \link api-tir-field-blob BLOB fields\endlink"
ALIASES += bt_cp_struct_field="\link api-tir-field-struct Structure fields\endlink"
ALIASES += bt_cp_array_field="\link api-tir-field-array Array fields\endlink"
ALIASES += bt_cp_sarray_field="Static \link api-tir-field-array array fields\endlink"
- \ref api-tir-fc-enum "Enumeration" (unsigned and signed)
- \ref api-tir-fc-real "Real" (single-precision and double-precision)
- \ref api-tir-fc-string "String"
+ - \ref api-tir-fc-blob "BLOB" (static and dynamic)
</dd>
<dt>Container</dt>
<td><em>\ref api-tir-fc-string "String"</em>
<td>#BT_FIELD_CLASS_TYPE_STRING
<td>bt_field_class_string_create()
+ <tr>
+ <td><em>Static \ref api-tir-fc-blob "BLOB"</em>
+ <td>#BT_FIELD_CLASS_TYPE_STATIC_BLOB
+ <td>bt_field_class_blob_static_create()
+ <tr>
+ <td>
+ <em>Dynamic \ref api-tir-fc-blob "BLOB"
+ (instances without a linked length field)</em>
+ <td>#BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD
+ <td>bt_field_class_blob_dynamic_without_length_field_location_create()
+ <tr>
+ <td>
+ <em>Dynamic \ref api-tir-fc-blob "BLOB"
+ (instances with a linked length field)</em>
+ <td>#BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD
+ <td>bt_field_class_blob_dynamic_with_length_field_location_create()
<tr>
<td><em>Static \ref api-tir-fc-array "array"</em>
<td>#BT_FIELD_CLASS_TYPE_STATIC_ARRAY
A string field class has no specific properties.
+<h1>\anchor api-tir-fc-blob BLOB field classes</h1>
+
+@image html fc-blob.png
+
+<strong><em>BLOB field classes</em></strong> are
+classes of \bt_p_blob_field.
+
+BLOB fields contain zero or more bytes of binary data.
+
+@note
+ BLOB field classes are only available when the \bt_trace_cls from
+ which you create them was created from a \bt_comp which belongs
+ to a trace processing \bt_graph with the effective \bt_mip
+ version 1.
+
+A BLOB field class is an \em abstract field class: you cannot create
+one. The concrete BLOB field classes are:
+
+<dl>
+ <dt>Static BLOB field class</dt>
+ <dd>
+ Its instances (static BLOB fields) contain a fixed number of bytes.
+
+ Create with bt_field_class_blob_static_create().
+
+ A static BLOB field class has the following specific property:
+
+ <dl>
+ <dt>
+ \anchor api-tir-fc-sblob-prop-len
+ Length
+ </dt>
+ <dd>
+ Number of bytes contained in the instances (static BLOB
+ fields) of the static BLOB field class.
+
+ You cannot change the length once the static BLOB field class is
+ created.
+
+ Get a static BLOB field class's length with
+ bt_field_class_blob_static_get_length().
+ </dd>
+ </dl>
+ </dd>
+
+ <dt>Dynamic BLOB field class</dt>
+ <dd>
+ Its instances (dynamic BLOB fields) contain a variable number
+ of bytes.
+
+ There are two types of dynamic BLOB field classes: instances
+ without or with a linked length field. See
+ \ref api-tir-fc-link "Fields with links to other fields"
+ to learn more.
+
+ @image html dblob-link.png "A dynamic blob field linked to an unsigned integer length field."
+
+ Create with
+ bt_field_class_blob_dynamic_without_length_field_location_create()
+ or bt_field_class_blob_dynamic_with_length_field_location_create().
+
+ The class of a dynamic BLOB field with a linked length field has
+ the following specific property:
+
+ <dl>
+ <dt>
+ \anchor api-tir-fc-dblob-prop-len-fl
+ Length field location
+ </dt>
+ <dd>
+ \bt_c_field_loc to locate the linked length field of an
+ instance.
+
+ Get a dynamic BLOB field class's length field location with
+ bt_field_class_blob_dynamic_with_length_field_borrow_length_field_location_const().
+ </dd>
+ </dl>
+ </dd>
+</dl>
+
+BLOB field classes have the following common property:
+
+<dl>
+ <dt>
+ \anchor api-tir-fc-blob-prop-media-type
+ Media type
+ </dt>
+ <dd>
+ <a href="https://datatracker.ietf.org/doc/html/rfc2046">IANA media type</a>
+ of instances of the BLOB field class.
+
+ Use bt_field_class_blob_set_media_type() and
+ bt_field_class_blob_get_media_type().
+ </dd>
+</dl>
+
<h1>\anchor api-tir-fc-array Array field classes</h1>
@image html fc-array.png
<h1>\anchor api-tir-fc-link Fields with links to other fields</h1>
-An instance of a \bt_darray_fc, a \bt_opt_fc, or a \bt_var_fc \em may
-have a link to another, anterior field within the same \bt_pkt or
-\bt_ev.
+An instance of a \bt_dblob_fc, a \bt_darray_fc, a \bt_opt_fc, or a
+\bt_var_fc \em may have a link to another, anterior field within the
+same \bt_pkt or \bt_ev.
This feature exists so that the linked field can contain the value of a
dynamic property of the "dependent" field. Those properties are:
<dl>
+ <dt>\bt_c_dblob_field</dt>
+ <dd>
+ The linked field, a \bt_uint_field, contains the \b length (number
+ of bytes) of the dynamic BLOB field.
+ </dd>
+
<dt>\bt_c_darray_field</dt>
<dd>
- The linked field, a \bt_uint_field, contains the \b length of the
- dynamic array field.
+ The linked field, a \bt_uint_field, contains the \b length (number
+ of elements) of the dynamic array field.
</dd>
<dt>\bt_c_opt_field</dt>
The functions to borrow the field location of a field class are:
+ - bt_field_class_blob_dynamic_with_length_field_borrow_length_field_location_const()
- bt_field_class_array_dynamic_with_length_field_borrow_length_field_location_const()
- bt_field_class_option_with_selector_field_borrow_selector_field_location_const()
- bt_field_class_variant_with_selector_field_borrow_selector_field_location_const()
*/
BT_FIELD_CLASS_TYPE_STRING = 1ULL << 9,
+ /*!
+ @brief
+ \bt_c_blob_fc.
+
+ No field class has this type: use it with
+ bt_field_class_type_is().
+ */
+ BT_FIELD_CLASS_TYPE_BLOB = (1ULL << 29),
+
+ /*!
+ @brief
+ \bt_c_sblob_fc.
+
+ This type conceptually inherits #BT_FIELD_CLASS_TYPE_BLOB.
+ */
+ BT_FIELD_CLASS_TYPE_STATIC_BLOB = (1ULL << 30) | BT_FIELD_CLASS_TYPE_BLOB,
+
+ /*!
+ @brief
+ \bt_c_dblob_fc.
+
+ This type conceptually inherits #BT_FIELD_CLASS_TYPE_BLOB.
+
+ No field class has this type: use it with
+ bt_field_class_type_is().
+ */
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB = (1ULL << 31) | BT_FIELD_CLASS_TYPE_BLOB,
+
+ /*!
+ @brief
+ \bt_c_dblob_fc (instances without a linked length field).
+
+ This type conceptually inherits
+ #BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB.
+ */
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD = (1ULL << 32) | BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB,
+
+ /*!
+ @brief
+ \bt_c_dblob_fc (instances with a linked length field).
+
+ This type conceptually inherits
+ #BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB.
+ */
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD = (1ULL << 33) | BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB,
+
/*!
@brief
\bt_c_struct_fc.
/*! @} */
+/*!
+@name BLOB field class
+@{
+*/
+
+/*!
+@brief
+ Creates a \bt_sblob_fc having the length \bt_p{length} from the
+ trace class \bt_p{trace_class}.
+
+On success, the returned static BLOB field class has the following
+property values:
+
+<table>
+ <tr>
+ <th>Property
+ <th>Value
+ <tr>
+ <td>\ref api-tir-fc-sarray-prop-len "Length"
+ <td>\bt_p{length}
+ <tr>
+ <td>\ref api-tir-fc-blob-prop-media-type "Media type"
+ <td><code>application/octet-stream</code>
+ <tr>
+ <td>\ref api-tir-fc-prop-user-attrs "User attributes"
+ <td>Empty \bt_map_val
+</table>
+
+@param[in] trace_class
+ Trace class from which to create a static BLOB field class.
+@param[in] length
+ Length (number of bytes) of the instances of the static BLOB
+ field class to create.
+
+@returns
+ New static BLOB field class reference, or \c NULL on memory error.
+
+@bt_pre_not_null{trace_class}
+@bt_pre_tc_with_mip{trace_class, 1}
+
+@sa bt_field_class_blob_dynamic_without_length_field_location_create() —
+ Creates a class of dynamic BLOB field without a linked length field.
+@sa bt_field_class_blob_dynamic_with_length_field_location_create() —
+ Creates a class of dynamic BLOB field with a linked length field.
+*/
+extern bt_field_class *bt_field_class_blob_static_create(
+ bt_trace_class *trace_class, uint64_t length) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Creates a \bt_dblob_fc (instances without a linked length field)
+ from the trace class \bt_p{trace_class}.
+
+On success, the returned dynamic BLOB field class has the following
+property values:
+
+<table>
+ <tr>
+ <th>Property
+ <th>Value
+ <tr>
+ <td>\ref api-tir-fc-dblob-prop-len-fl "Length field location"
+ <td>
+ \em None
+ <tr>
+ <td>\ref api-tir-fc-blob-prop-media-type "Media type"
+ <td><code>application/octet-stream</code>
+ <tr>
+ <td>\ref api-tir-fc-prop-user-attrs "User attributes"
+ <td>Empty \bt_map_val
+</table>
+
+@param[in] trace_class
+ Trace class from which to create a dynamic BLOB field class.
+
+@returns
+ New dynamic BLOB field class reference (without a length field),
+ or \c NULL on memory error.
+
+@bt_pre_not_null{trace_class}
+@bt_pre_tc_with_mip{trace_class, 1}
+
+@sa bt_field_class_blob_dynamic_with_length_field_location_create() —
+ Creates a class of dynamic BLOB field with a linked length field.
+*/
+extern bt_field_class *
+bt_field_class_blob_dynamic_without_length_field_location_create(
+ bt_trace_class *trace_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Creates a \bt_dblob_fc (instances with a linked length field)
+ having the length \bt_field_loc \bt_p{length_field_location} from
+ the trace class \bt_p{trace_class}.
+
+On success, the returned dynamic BLOB field class has the following
+property values:
+
+<table>
+ <tr>
+ <th>Property
+ <th>Value
+ <tr>
+ <td>\ref api-tir-fc-dblob-prop-len-fl "Length field location"
+ <td>
+ \bt_p{length_field_location}.
+
+ See \ref api-tir-fc-link "Fields with links to other fields"
+ to learn more.
+ <tr>
+ <td>\ref api-tir-fc-blob-prop-media-type "Media type"
+ <td><code>application/octet-stream</code>
+ <tr>
+ <td>\ref api-tir-fc-prop-user-attrs "User attributes"
+ <td>Empty \bt_map_val
+</table>
+
+@param[in] trace_class
+ Trace class from which to create a dynamic BLOB field class.
+@param[in] length_field_location
+ Length field location of the dynamic BLOB field class to create.
+
+@returns
+ New dynamic BLOB field class reference (instances with a linked
+ length field), or \c NULL on memory error.
+
+@bt_pre_not_null{trace_class}
+@bt_pre_tc_with_mip{trace_class, 1}
+@bt_pre_not_null{length_field_location}
+
+@sa bt_field_class_blob_dynamic_without_length_field_location_create() —
+ Creates a class of dynamic BLOB field without a linked
+ length field.
+*/
+extern bt_field_class *
+bt_field_class_blob_dynamic_with_length_field_location_create(
+ bt_trace_class *trace_class,
+ const bt_field_location *length_field_location) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Returns the length of the \bt_sblob_fc \bt_p{field_class}.
+
+See the \ref api-tir-fc-sblob-prop-len "length" property.
+
+@param[in] field_class
+ Static BLOB field class of which to get the length (number of bytes
+ in instances).
+
+@returns
+ Length of \bt_p{field_class}.
+
+@bt_pre_not_null{field_class}
+@bt_pre_is_sblob_fc{field_class}
+@bt_pre_fc_with_mip{field_class, 1}
+*/
+extern uint64_t bt_field_class_blob_static_get_length(
+ const bt_field_class *field_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Borrows the length field location from the \bt_dblob_fc (instances
+ with a linked length field) \bt_p{field_class}.
+
+See the \ref api-tir-fc-dblob-prop-len-fl "length field location"
+property.
+
+@param[in] field_class
+ Dynamic BLOB field class from which to borrow the length
+ field location.
+
+@returns
+ Length field location of \bt_p{field_class}.
+
+@bt_pre_not_null{field_class}
+@bt_pre_is_dblob_wl_fc{field_class}
+@bt_pre_fc_with_mip{field_class, 1}
+*/
+extern const bt_field_location *
+bt_field_class_blob_dynamic_with_length_field_borrow_length_field_location_const(
+ const bt_field_class *field_class) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Status codes for bt_field_class_blob_set_media_type().
+*/
+typedef enum bt_field_class_blob_set_media_type_status {
+ /*!
+ @brief
+ Success.
+ */
+ BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_OK = __BT_FUNC_STATUS_OK,
+
+ /*!
+ @brief
+ Out of memory.
+ */
+ BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
+} bt_field_class_blob_set_media_type_status;
+
+/*!
+@brief
+ Sets the IANA media type of the \bt_blob_fc \bt_p{field_class}
+ to a copy of \bt_p{media_type}.
+
+See the \ref api-tir-fc-blob-prop-media-type "media type" property.
+
+@param[in] field_class
+ BLOB field class of which to set the media type to a copy of
+ \bt_p{media_type}.
+@param[in] media_type
+ New media type of \bt_p{field_class} (copied).
+
+@retval #BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_OK
+ Success.
+@retval #BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_MEMORY_ERROR
+ Out of memory.
+
+@bt_pre_not_null{field_class}
+@bt_pre_hot{field_class}
+@bt_pre_is_blob_fc{field_class}
+@bt_pre_fc_with_mip{field_class, 1}
+
+@sa bt_field_class_blob_get_media_type() —
+ Returns the IANA media type of BLOB field class.
+*/
+extern bt_field_class_blob_set_media_type_status
+bt_field_class_blob_set_media_type(bt_field_class *field_class,
+ const char *media_type) __BT_NOEXCEPT;
+
+/*!
+@brief
+ Returns the IANA media type of the \bt_blob_fc \bt_p{field_class}.
+
+See the \ref api-tir-fc-blob-prop-media-type "media type" property.
+
+If \bt_p{field_class} has no media type, this function returns \c NULL.
+
+@param[in] field_class
+ BLOB field class of which to get the media type.
+
+@returns
+ @parblock
+ Media type of \bt_p{field_class}, or \c NULL if none.
+
+ The returned pointer remains valid as long as \bt_p{field_class}
+ is not modified.
+ @endparblock
+
+@bt_pre_not_null{field_class}
+@bt_pre_is_blob_fc{field_class}
+@bt_pre_fc_with_mip{field_class, 1}
+
+@sa bt_field_class_blob_set_media_type() —
+ Sets the media type of a BLOB field class.
+*/
+extern const char *bt_field_class_blob_get_media_type(
+ const bt_field_class *field_class) __BT_NOEXCEPT;
+
+/*! @} */
+
/*!
@name Array field class
@{
A field location indicates how to reach:
+- The length field of a \bt_dblob_field
+ (instances with a linked length field).
+
- The length field of a \bt_darray_field
(instances with a linked length field).
- \ref api-tir-field-enum "Enumeration" (unsigned and signed)
- \ref api-tir-field-real "Real" (single-precision and double-precision)
- \ref api-tir-field-string "String"
+ - \ref api-tir-field-blob "BLOB" (static and dynamic)
</dd>
<dt>Container</dt>
Clear a string field with bt_field_string_clear().
+<h1>\anchor api-tir-field-blob BLOB fields</h1>
+
+<strong><em>BLOB fields</em></strong> are \bt_blob_fc instances.
+
+BLOB fields contain zero or more bytes of binary data.
+
+@note
+ BLOB fields are only available when the \bt_trace_cls from
+ which you create their classes was created from a \bt_comp
+ which belongs to a trace processing \bt_graph with the effective
+ \bt_mip version 1.
+
+A BLOB field is an \em abstract field. The concrete BLOB fields are:
+
+<dl>
+ <dt>Static BLOB field</dt>
+ <dd>
+ A \bt_sblob_fc instance.
+
+ A static BLOB field contains a fixed number of bytes. Its length
+ is \ref api-tir-fc-sblob-prop-len "given by its class".
+ </dd>
+
+ <dt>Dynamic BLOB field</dt>
+ <dd>
+ A \bt_dblob_fc instance.
+
+ A dynamic BLOB field contains a variable number of bytes, that is,
+ each instance of the same dynamic BLOB field class can contain a
+ different number of bytes.
+
+ Set a dynamic BLOB field's length with
+ bt_field_blob_dynamic_set_length() before you get its data
+ with bt_field_blob_get_data().
+ </dd>
+</dl>
+
+Get a BLOB field's length with bt_field_blob_get_length().
+
+Get the data of a BLOB field with bt_field_blob_get_data()
+or bt_field_blob_get_data_const().
+
<h1>\anchor api-tir-field-array Array fields</h1>
<strong><em>Array fields</em></strong> are \bt_array_fc instances.
is \ref api-tir-fc-sarray-prop-len "given by its class".
</dd>
- <dt>Dynamic array field class</dt>
+ <dt>Dynamic array field</dt>
<dd>
A \bt_darray_fc instance.
/*! @} */
+/*!
+@name BLOB field
+@{
+*/
+
+/*!
+@brief
+ Returns the length (number of bytes) of the \bt_blob_field \bt_p{field}.
+
+@param[in] field
+ BLOB field of which to get the length.
+
+@returns
+ Length of \bt_p{field}.
+
+@bt_pre_not_null{field}
+@bt_pre_is_blob_field{field}
+@bt_pre_field_with_mip{field, 1}
+*/
+extern uint64_t bt_field_blob_get_length(const bt_field *field);
+
+/*!
+@brief
+ Returns the writable data of the \bt_blob_field \bt_p{field}.
+
+@attention
+ If \bt_p{field} is a dynamic BLOB field, then it must have a length
+ (call bt_field_blob_dynamic_set_length()) before you call this
+ function.
+
+@param[in] field
+ BLOB field from which to get the writable data.
+
+@returns
+ @parblock
+ Writable data of \bt_p{field}.
+
+ The returned pointer remains valid until \bt_p{field} is modified.
+ @endparblock
+
+@bt_pre_not_null{field}
+@bt_pre_is_blob_field{field}
+@bt_pre_hot{field}
+@bt_pre_field_with_mip{field, 1}
+
+@sa bt_field_blob_get_data_const() —
+ Returns the readable data of a BLOB field.
+*/
+extern uint8_t *bt_field_blob_get_data(bt_field *field);
+
+/*!
+@brief
+ Returns the readable data of the \bt_blob_field \bt_p{field}.
+
+@param[in] field
+ BLOB field from which to get the readable data.
+
+@returns
+ @parblock
+ Readable data of \bt_p{field}.
+
+ The returned pointer remains valid until \bt_p{field} is modified.
+ @endparblock
+
+@bt_pre_not_null{field}
+@bt_pre_is_blob_field{field}
+@bt_pre_field_with_mip{field, 1}
+
+@sa bt_field_blob_get_data() —
+ Returns the writable data of a BLOB field.
+*/
+extern const uint8_t *bt_field_blob_get_data_const(const bt_field *field);
+
+/*!
+@brief
+ Status codes for bt_field_blob_dynamic_set_length().
+*/
+typedef enum bt_field_blob_dynamic_set_length_status {
+ /*!
+ @brief
+ Success.
+ */
+ BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_OK = __BT_FUNC_STATUS_OK,
+
+ /*!
+ @brief
+ Out of memory.
+ */
+ BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_MEMORY_ERROR = __BT_FUNC_STATUS_MEMORY_ERROR,
+} bt_field_blob_dynamic_set_length_status;
+
+/*!
+@brief
+ Sets the length (number of bytes) of the
+ \bt_dblob_field \bt_p{field}.
+
+@param[in] field
+ Dynamic BLOB field of which to set the length (number of bytes).
+@param[in] length
+ New length of \bt_p{field}.
+
+@retval #BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_OK
+ Success.
+@retval #BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_MEMORY_ERROR
+ Out of memory.
+
+@bt_pre_not_null{field}
+@bt_pre_is_dblob_field{field}
+@bt_pre_hot{field}
+@bt_pre_field_with_mip{field, 1}
+*/
+extern bt_field_blob_dynamic_set_length_status bt_field_blob_dynamic_set_length(
+ bt_field *field, uint64_t length);
+
+/*! @} */
+
/*!
@name Array field
@{
\bt_p{field}.
@attention
- If \bt_p{field} is a dynamic array field, it must have a length
+ If \bt_p{field} is a dynamic array field, then it must have a length
(call bt_field_array_dynamic_set_length()) before you call this
function.
return "VARIANT_WITH_UNSIGNED_INTEGER_SELECTOR_FIELD";
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
return "VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD";
+ case BT_FIELD_CLASS_TYPE_BLOB:
+ return "BT_FIELD_CLASS_TYPE_BLOB";
+ case BT_FIELD_CLASS_TYPE_STATIC_BLOB:
+ return "BT_FIELD_CLASS_TYPE_STATIC_BLOB";
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB:
+ return "BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB";
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD:
+ return "BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD";
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD:
+ return "BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD";
case __BT_FIELD_CLASS_TYPE_BIG_VALUE:
bt_common_abort ();
}
#define _BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_ID(_fc_id) \
"is-variant-field-class-with-selector:" _fc_id
+#define _BT_ASSERT_PRE_FC_IS_BLOB_ID(_fc_id) \
+ "is-blob-field-class:" _fc_id
+
+#define _BT_ASSERT_PRE_FC_IS_BLOB_COND(_fc) \
+ bt_field_class_type_is((_fc)->type, BT_FIELD_CLASS_TYPE_BLOB)
+
+#define _BT_ASSERT_PRE_FC_IS_BLOB_FMT(_name) \
+ _name " is not a BLOB field class: %![fc-]+F"
+
#define _BT_ASSERT_PRE_FC_HAS_TYPE_COND(_fc, _type) \
(((const struct bt_field_class *) (_fc))->type == (_type))
_BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_COND(_fc), \
_BT_ASSERT_PRE_FC_IS_VARIANT_WITH_SEL_FMT(_name), (_fc))
+#define BT_ASSERT_PRE_FC_IS_BLOB(_fc_id, _fc, _name) \
+ BT_ASSERT_PRE( \
+ _BT_ASSERT_PRE_FC_IS_BLOB_ID(_fc_id), \
+ _BT_ASSERT_PRE_FC_IS_BLOB_COND(_fc), \
+ _BT_ASSERT_PRE_FC_IS_BLOB_FMT(_name), (_fc))
+
#define BT_ASSERT_PRE_FC_HAS_TYPE_FROM_FUNC(_func, _fc_id, _fc, _type_id, _type, _name) \
BT_ASSERT_PRE_FROM_FUNC(_func, \
_BT_ASSERT_PRE_FC_HAS_TYPE_ID(_fc_id, _type_id), \
((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD, \
_name " is not a variant field: %![field-]+f", (_field))
+#define BT_ASSERT_PRE_DEV_FIELD_IS_BLOB(_field_id, _field, _name) \
+ BT_ASSERT_PRE_DEV( \
+ "is-blob-field:" _field_id, \
+ bt_field_class_type_is(_field->class->type, BT_FIELD_CLASS_TYPE_BLOB), \
+ _name "is not a BLOB field: %![field-]+f", (_field))
+
+#define BT_ASSERT_PRE_DEV_FIELD_IS_DYNAMIC_BLOB(_field_id, _field, _name) \
+ BT_ASSERT_PRE_DEV( \
+ "is-dynamic-blob-field:" _field_id, \
+ bt_field_class_type_is(_field->class->type, BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB), \
+ _name "is not a dynamic BLOB field: %![field-]+f", (_field))
+
#define BT_ASSERT_PRE_DEV_FIELD_IS_SET(_field_id, _field) \
BT_ASSERT_PRE_DEV("is-field-set:" _field_id, \
bt_field_is_set(_field), \
PRFIELD(bt_common_field_class_type_string(array_fc->element_fc->type)));
}
+static inline void format_blob_field_class(char **buf_ch, const char *prefix,
+ const struct bt_field_class_blob *field_class)
+{
+ BUF_APPEND(", %smedia-type=\"%s\"",
+ PRFIELD(field_class->media_type->str));
+}
+
static inline void format_field_class(char **buf_ch, bool extended,
const char *prefix, const struct bt_field_class *field_class)
{
break;
}
+ case BT_FIELD_CLASS_TYPE_STATIC_BLOB:
+ {
+ const struct bt_field_class_blob_static *blob_fc =
+ (const void *) field_class;
+
+ format_blob_field_class(buf_ch, prefix, (const void *) blob_fc);
+ BUF_APPEND(", %slength=%" PRIu64, PRFIELD(blob_fc->length));
+ break;
+ }
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD:
+ {
+ const struct bt_field_class_blob_dynamic *blob_fc =
+ (const void *) field_class;
+
+ format_blob_field_class(buf_ch, prefix, (const void *) blob_fc);
+
+ if (field_class->type == BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD) {
+ BT_ASSERT(blob_fc->length_fl);
+ SET_TMP_PREFIX("length-fl-");
+ format_field_location(buf_ch, extended, tmp_prefix,
+ blob_fc->length_fl);
+ break;
+ }
+
+ break;
+ }
default:
break;
}
user_attributes, __func__);
}
+BT_EXPORT
+bt_field_class_blob_set_media_type_status bt_field_class_blob_set_media_type(
+ struct bt_field_class *fc, const char *media_type)
+{
+ struct bt_field_class_blob *fc_blob = (void *) fc;
+
+ BT_ASSERT_PRE_FC_NON_NULL(fc);
+ BT_ASSERT_PRE_FC_IS_BLOB("field-class", fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HOT(fc);
+ BT_ASSERT_PRE_NON_NULL("media-type", media_type, "Media type");
+
+ g_string_assign(fc_blob->media_type, media_type);
+
+ return BT_FIELD_CLASS_BLOB_SET_MEDIA_TYPE_STATUS_OK;
+}
+
+BT_EXPORT
+const char *bt_field_class_blob_get_media_type(
+ const bt_field_class *fc)
+{
+ struct bt_field_class_blob *fc_blob = (void *) fc;
+
+ BT_ASSERT_PRE_FC_NON_NULL(fc);
+ BT_ASSERT_PRE_FC_IS_BLOB("field-class", fc, "Field class");
+
+ return fc_blob->media_type->str;
+}
+
+static
+int init_blob_field_class(struct bt_field_class_blob *fc,
+ enum bt_field_class_type type,
+ bt_object_release_func release_func,
+ bt_trace_class *trace_class)
+{
+ int ret;
+
+ ret = init_field_class((void *) fc, type, release_func,
+ trace_class);
+ if (ret) {
+ goto end;
+ }
+
+ fc->media_type = g_string_new("application/octet-stream");
+
+end:
+ return ret;
+}
+
+static
+void destroy_blob_field_class(struct bt_object *obj)
+{
+ struct bt_field_class_blob *blob = (void *) obj;
+
+ BT_ASSERT(obj);
+ g_string_free(blob->media_type, TRUE);
+ finalize_field_class((void *) obj);
+ g_free(obj);
+}
+
+static
+void destroy_static_blob_field_class(struct bt_object *obj)
+{
+ struct bt_field_class_blob_static *fc = (void *) obj;
+
+ BT_ASSERT(fc);
+ BT_LIB_LOGD("Destroying static BLOB field class object: %!+F", fc);
+
+ destroy_blob_field_class(obj);
+}
+
+BT_EXPORT
+struct bt_field_class *bt_field_class_blob_static_create(
+ struct bt_trace_class *trace_class, uint64_t length)
+{
+ struct bt_field_class_blob_static *blob_fc = NULL;
+ int ret;
+
+ BT_ASSERT_PRE_NO_ERROR();
+ BT_ASSERT_PRE_TC_NON_NULL(trace_class);
+ BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
+
+ BT_LOGD_STR("Creating default static BLOB field class object.");
+ blob_fc = g_new0(struct bt_field_class_blob_static, 1);
+ if (!blob_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one static BLOB field class.");
+ goto error;
+ }
+
+ ret = init_blob_field_class((void *) blob_fc,
+ BT_FIELD_CLASS_TYPE_STATIC_BLOB,
+ destroy_static_blob_field_class,
+ trace_class);
+ if (ret) {
+ goto end;
+ }
+
+ blob_fc->length = length;
+ BT_LIB_LOGD("Created static BLOB field class object: %!+F", blob_fc);
+ goto end;
+
+error:
+ BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
+
+end:
+ return (void *) blob_fc;
+}
+
+BT_EXPORT
+uint64_t bt_field_class_blob_static_get_length(
+ const bt_field_class *fc)
+{
+ const struct bt_field_class_blob_static *blob_fc = (const void *) fc;
+
+ BT_ASSERT_PRE_DEV_FC_NON_NULL(fc);
+ BT_ASSERT_PRE_DEV_FC_HAS_TYPE("field-class", fc,
+ "static-blob-field-class", BT_FIELD_CLASS_TYPE_STATIC_BLOB,
+ "Field class");
+
+ return blob_fc->length;
+}
+
+static
+void destroy_dynamic_blob_field_class(struct bt_object *obj)
+{
+ struct bt_field_class_blob_dynamic *fc = (void *) obj;
+
+ BT_ASSERT(fc);
+ BT_LIB_LOGD("Destroying dynamic BLOB field class object: %!+F", fc);
+
+ bt_object_put_ref(fc->length_fl);
+ fc->length_fl = NULL;
+
+ destroy_blob_field_class(obj);
+}
+
+static
+struct bt_field_class_blob_dynamic *create_dynamic_blob_field_class(
+ struct bt_trace_class *trace_class, enum bt_field_class_type type)
+{
+ struct bt_field_class_blob_dynamic *blob_fc = NULL;
+ int ret;
+
+ BT_LOGD_STR("Creating default dynamic BLOB field class object.");
+ blob_fc = g_new0(struct bt_field_class_blob_dynamic, 1);
+ if (!blob_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one dynamic BLOB field class.");
+ goto error;
+ }
+
+ ret = init_blob_field_class((void *) blob_fc, type,
+ destroy_dynamic_blob_field_class, trace_class);
+ if (ret) {
+ goto error;
+ }
+
+ goto end;
+
+error:
+ BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
+
+end:
+ return blob_fc;
+}
+
+BT_EXPORT
+struct bt_field_class *bt_field_class_blob_dynamic_without_length_field_location_create(
+ struct bt_trace_class *trace_class)
+{
+ struct bt_field_class_blob_dynamic *blob_fc = NULL;
+
+ BT_ASSERT_PRE_NO_ERROR();
+ BT_ASSERT_PRE_TC_NON_NULL(trace_class);
+ BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
+
+ blob_fc = create_dynamic_blob_field_class(trace_class,
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD);
+ if (!blob_fc) {
+ goto error;
+ }
+
+ BT_LIB_LOGD("Created dynamic BLOB field class without field location object: %!+F",
+ blob_fc);
+
+ goto end;
+
+error:
+ BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
+
+end:
+ return (void *) blob_fc;
+}
+
+BT_EXPORT
+struct bt_field_class *bt_field_class_blob_dynamic_with_length_field_location_create(
+ bt_trace_class *trace_class,
+ const bt_field_location *length_field_location)
+{
+ struct bt_field_class_blob_dynamic *blob_fc = NULL;
+
+ BT_ASSERT_PRE_NO_ERROR();
+ BT_ASSERT_PRE_TC_NON_NULL(trace_class);
+ BT_ASSERT_PRE_FL_NON_NULL(length_field_location);
+ BT_ASSERT_PRE_TC_MIP_VERSION_GE(trace_class, 1);
+
+ blob_fc = create_dynamic_blob_field_class(trace_class,
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD);
+ if (!blob_fc) {
+ goto error;
+ }
+
+ blob_fc->length_fl = length_field_location;
+ bt_object_get_ref_no_null_check(length_field_location);
+
+ BT_LIB_LOGD("Created dynamic BLOB field class with field location object: %!+F",
+ blob_fc);
+
+ goto end;
+
+error:
+ BT_OBJECT_PUT_REF_AND_RESET(blob_fc);
+
+end:
+ return (void *) blob_fc;
+}
+
+BT_EXPORT
+const bt_field_location *
+bt_field_class_blob_dynamic_with_length_field_borrow_length_field_location_const(
+ const bt_field_class *fc)
+{
+ const struct bt_field_class_blob_dynamic *blob_fc = (const void *) fc;
+
+ BT_ASSERT_PRE_NO_ERROR();
+ BT_ASSERT_PRE_FC_NON_NULL(fc);
+ BT_ASSERT_PRE_FC_HAS_TYPE("field-class", fc,
+ "dynamic-blob-field-class-with-length-field",
+ BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD,
+ "Field class");
+ BT_ASSERT_PRE_FC_MIP_VERSION_GE(fc, 1);
+ BT_ASSERT(blob_fc->length_fl);
+
+ return blob_fc->length_fl;
+}
+
BT_EXPORT
void bt_field_class_get_ref(const struct bt_field_class *field_class)
{
} selector_field;
};
+struct bt_field_class_blob {
+ struct bt_field_class common;
+
+ GString *media_type;
+};
+
+struct bt_field_class_blob_static {
+ struct bt_field_class_blob common;
+ uint64_t length;
+};
+
+struct bt_field_class_blob_dynamic {
+ struct bt_field_class_blob common;
+ const struct bt_field_location *length_fl;
+};
+
void _bt_field_class_freeze(const struct bt_field_class *field_class);
#ifdef BT_DEV_MODE
.reset = reset_variant_field,
};
+static
+struct bt_field_methods blob_field_methods = {
+ .set_is_frozen = set_single_field_is_frozen,
+ .is_set = single_field_is_set,
+ .reset = reset_single_field,
+};
+
static
struct bt_field *create_bool_field(struct bt_field_class *);
static
struct bt_field *create_variant_field(struct bt_field_class *);
+static
+struct bt_field *create_blob_field(struct bt_field_class *);
+
static
void destroy_bool_field(struct bt_field *field);
static
void destroy_variant_field(struct bt_field *field);
+static
+void destroy_blob_field(struct bt_field *field);
+
BT_EXPORT
struct bt_field_class *bt_field_borrow_class(struct bt_field *field)
{
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
field = create_variant_field(fc);
break;
+ case BT_FIELD_CLASS_TYPE_STATIC_BLOB:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD:
+ field = create_blob_field(fc);
+ break;
default:
bt_common_abort();
}
return (void *) var_field;
}
+static
+struct bt_field *create_blob_field(struct bt_field_class *fc)
+{
+ struct bt_field_blob *blob_field;
+
+ BT_LIB_LOGD("Creating BLOB field object: %![fc-]+F", fc);
+ blob_field = g_new0(struct bt_field_blob, 1);
+ if (!blob_field) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one BLOB field.");
+ goto end;
+ }
+
+ init_field((void *) blob_field, fc, &blob_field_methods);
+
+ if (bt_field_class_type_is(fc->type, BT_FIELD_CLASS_TYPE_STATIC_BLOB)) {
+ struct bt_field_class_blob_static *blob_static_fc =
+ (void *) fc;
+ blob_field->length = blob_static_fc->length;
+ blob_field->data = g_malloc(blob_field->length);
+ if (!blob_field->data) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate BLOB field data: %![fc-]+F",
+ fc);
+ goto error;
+ }
+ }
+
+ goto end;
+error:
+ bt_field_destroy((void *) blob_field);
+ blob_field = NULL;
+
+end:
+ return (void *) blob_field;
+}
+
static inline
int init_array_field_fields(struct bt_field_array *array_field)
{
return var_field->selected_index;
}
+BT_EXPORT
+uint8_t *bt_field_blob_get_data(struct bt_field *field)
+{
+ const struct bt_field_blob *blob_field = (const void *) field;
+
+ BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
+ BT_ASSERT_PRE_DEV_FIELD_IS_BLOB("field", field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HOT(field);
+ BT_ASSERT_PRE_DEV("blob-field-length-is-set",
+ blob_field->length > 0,
+ "BLOB field length is not set: %!+f", field);
+
+ /* Assume that the user will fill the bytes. */
+ bt_field_set_single(field, true);
+
+ return blob_field->data;
+}
+
+BT_EXPORT
+const uint8_t *bt_field_blob_get_data_const(const struct bt_field *field)
+{
+ const struct bt_field_blob *blob_field = (const void *) field;
+
+ BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
+ BT_ASSERT_PRE_DEV_FIELD_IS_BLOB("field", field, "Field");
+
+ return blob_field->data;
+}
+
+BT_EXPORT
+enum bt_field_blob_dynamic_set_length_status bt_field_blob_dynamic_set_length(
+ struct bt_field *field, uint64_t length)
+{
+ int ret;
+ struct bt_field_blob *blob_field = (void *) field;
+
+ BT_ASSERT_PRE_DEV_NO_ERROR();
+ BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
+ BT_ASSERT_PRE_DEV_FIELD_IS_DYNAMIC_BLOB("field", field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HOT(field);
+
+ if (G_UNLIKELY(length > blob_field->length)) {
+ /* Make more room */
+ uint8_t *data = g_realloc(blob_field->data, length);
+
+ if (!data) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to reallocate BLOB field data: %!+f",
+ field);
+ ret = BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_MEMORY_ERROR;
+ goto end;
+ }
+
+ blob_field->data = data;
+ }
+
+ blob_field->length = length;
+ ret = BT_FIELD_DYNAMIC_BLOB_SET_LENGTH_STATUS_OK;
+
+end:
+ return ret;
+}
+
+BT_EXPORT
+uint64_t bt_field_blob_get_length(const struct bt_field *field)
+{
+ const struct bt_field_blob *blob_field = (const void *) field;
+
+ BT_ASSERT_PRE_DEV_FIELD_NON_NULL(field);
+ BT_ASSERT_PRE_DEV_FIELD_IS_BLOB("field", field, "Field");
+
+ return blob_field->length;
+}
+
+
static inline
void bt_field_finalize(struct bt_field *field)
{
g_free(field);
}
+static
+void destroy_blob_field(struct bt_field *field)
+{
+ struct bt_field_blob *blob_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying BLOB field object: %!+f", field);
+ bt_field_finalize(field);
+
+ g_free(blob_field->data);
+
+ g_free(field);
+}
+
static
void destroy_array_field(struct bt_field *field)
{
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_INTEGER_SELECTOR_FIELD:
destroy_variant_field(field);
break;
+ case BT_FIELD_CLASS_TYPE_STATIC_BLOB:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITHOUT_LENGTH_FIELD:
+ case BT_FIELD_CLASS_TYPE_DYNAMIC_BLOB_WITH_LENGTH_FIELD:
+ destroy_blob_field(field);
+ break;
default:
bt_common_abort();
}
GPtrArray *fields;
};
+struct bt_field_blob {
+ struct bt_field common;
+
+ uint64_t length;
+ uint8_t *data;
+};
+
struct bt_field_array {
struct bt_field common;