From: Philippe Proulx Date: Fri, 7 Dec 2018 21:23:29 +0000 (-0500) Subject: lib: rename plural file names to singular X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=c6bd8523ba4a37b61a1591c03e23614112b155ba lib: rename plural file names to singular For example, the object is `struct bt_value` so name the header file `value.h`. Signed-off-by: Philippe Proulx --- diff --git a/cli/babeltrace-cfg-cli-args-connect.h b/cli/babeltrace-cfg-cli-args-connect.h index 5c5f1ff5..7814bcd5 100644 --- a/cli/babeltrace-cfg-cli-args-connect.h +++ b/cli/babeltrace-cfg-cli-args-connect.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include "babeltrace-cfg.h" diff --git a/cli/babeltrace-cfg-cli-args.h b/cli/babeltrace-cfg-cli-args.h index e6afb375..fd222724 100644 --- a/cli/babeltrace-cfg-cli-args.h +++ b/cli/babeltrace-cfg-cli-args.h @@ -25,7 +25,7 @@ #include #include -#include +#include #include #include #include diff --git a/cli/babeltrace-cfg.h b/cli/babeltrace-cfg.h index 9bcc1858..e7e98372 100644 --- a/cli/babeltrace-cfg.h +++ b/cli/babeltrace-cfg.h @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/Makefile.am b/include/Makefile.am index da92f90b..fa75c7c3 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -76,8 +76,8 @@ babeltraceinclude_HEADERS = \ babeltrace/object.h \ babeltrace/property.h \ babeltrace/types.h \ - babeltrace/values-const.h \ - babeltrace/values.h \ + babeltrace/value-const.h \ + babeltrace/value.h \ babeltrace/version.h # Legacy API (for CTF writer) @@ -126,11 +126,11 @@ babeltracetraceirinclude_HEADERS = \ babeltrace/trace-ir/event-const.h \ babeltrace/trace-ir/event-header-field.h \ babeltrace/trace-ir/event.h \ - babeltrace/trace-ir/field-classes-const.h \ - babeltrace/trace-ir/field-classes.h \ + babeltrace/trace-ir/field-class-const.h \ + babeltrace/trace-ir/field-class.h \ babeltrace/trace-ir/field-path-const.h \ - babeltrace/trace-ir/fields-const.h \ - babeltrace/trace-ir/fields.h \ + babeltrace/trace-ir/field-const.h \ + babeltrace/trace-ir/field.h \ babeltrace/trace-ir/packet-const.h \ babeltrace/trace-ir/packet-context-field.h \ babeltrace/trace-ir/packet-header-field.h \ @@ -219,7 +219,7 @@ noinst_HEADERS = \ babeltrace/plugin/plugin-so-internal.h \ babeltrace/plugin/python-plugin-provider-internal.h \ babeltrace/assert-internal.h \ - babeltrace/values-internal.h \ + babeltrace/value-internal.h \ babeltrace/ctf-writer/attributes-internal.h \ babeltrace/ctf-writer/clock-class-internal.h \ babeltrace/ctf-writer/clock-internal.h \ @@ -249,9 +249,9 @@ noinst_HEADERS = \ babeltrace/trace-ir/clock-value-set-internal.h \ babeltrace/trace-ir/event-class-internal.h \ babeltrace/trace-ir/event-internal.h \ - babeltrace/trace-ir/field-classes-internal.h \ + babeltrace/trace-ir/field-class-internal.h \ babeltrace/trace-ir/field-path-internal.h \ - babeltrace/trace-ir/fields-internal.h \ + babeltrace/trace-ir/field-internal.h \ babeltrace/trace-ir/field-wrapper-internal.h \ babeltrace/trace-ir/packet-internal.h \ babeltrace/trace-ir/resolve-field-path-internal.h \ diff --git a/include/babeltrace/babeltrace.h b/include/babeltrace/babeltrace.h index 23e86821..a1fb21d9 100644 --- a/include/babeltrace/babeltrace.h +++ b/include/babeltrace/babeltrace.h @@ -30,8 +30,8 @@ #include #include #include -#include -#include +#include +#include #include /* Legacy API (for CTF writer) */ @@ -72,11 +72,11 @@ #include #include #include -#include -#include +#include +#include +#include #include -#include -#include +#include #include #include #include diff --git a/include/babeltrace/common-internal.h b/include/babeltrace/common-internal.h index d27f8967..eebe5926 100644 --- a/include/babeltrace/common-internal.h +++ b/include/babeltrace/common-internal.h @@ -27,10 +27,10 @@ #include #include #include -#include +#include #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/ctf-writer/event-class-internal.h b/include/babeltrace/ctf-writer/event-class-internal.h index 3a7b8617..1a12ac11 100644 --- a/include/babeltrace/ctf-writer/event-class-internal.h +++ b/include/babeltrace/ctf-writer/event-class-internal.h @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include struct bt_ctf_event_class_common { diff --git a/include/babeltrace/ctf-writer/event-internal.h b/include/babeltrace/ctf-writer/event-internal.h index d6297570..deecbf31 100644 --- a/include/babeltrace/ctf-writer/event-internal.h +++ b/include/babeltrace/ctf-writer/event-internal.h @@ -42,7 +42,7 @@ #include #include #include -#include +#include struct bt_ctf_stream_class; struct bt_ctf_stream_pos; diff --git a/include/babeltrace/ctf-writer/trace-internal.h b/include/babeltrace/ctf-writer/trace-internal.h index b1104256..fbfd2e03 100644 --- a/include/babeltrace/ctf-writer/trace-internal.h +++ b/include/babeltrace/ctf-writer/trace-internal.h @@ -39,8 +39,8 @@ #include #include #include +#include #include -#include #include #include diff --git a/include/babeltrace/ctf-writer/validation-internal.h b/include/babeltrace/ctf-writer/validation-internal.h index 235a2623..996126bd 100644 --- a/include/babeltrace/ctf-writer/validation-internal.h +++ b/include/babeltrace/ctf-writer/validation-internal.h @@ -24,7 +24,7 @@ */ #include -#include +#include struct bt_ctf_trace_common; struct bt_ctf_stream_class_common; diff --git a/include/babeltrace/trace-ir/attributes-internal.h b/include/babeltrace/trace-ir/attributes-internal.h index a0d7d358..b679e122 100644 --- a/include/babeltrace/trace-ir/attributes-internal.h +++ b/include/babeltrace/trace-ir/attributes-internal.h @@ -30,7 +30,7 @@ extern "C" { #include #include -#include +#include BT_HIDDEN struct bt_value *bt_attributes_create(void); diff --git a/include/babeltrace/trace-ir/event-class-internal.h b/include/babeltrace/trace-ir/event-class-internal.h index 28f8d785..2bbb4243 100644 --- a/include/babeltrace/trace-ir/event-class-internal.h +++ b/include/babeltrace/trace-ir/event-class-internal.h @@ -26,10 +26,10 @@ */ #include -#include -#include +#include +#include #include -#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/event-internal.h b/include/babeltrace/trace-ir/event-internal.h index eedceaea..12928dd2 100644 --- a/include/babeltrace/trace-ir/event-internal.h +++ b/include/babeltrace/trace-ir/event-internal.h @@ -32,15 +32,15 @@ #include #include -#include +#include #include #include #include #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/field-class-const.h b/include/babeltrace/trace-ir/field-class-const.h new file mode 100644 index 00000000..87992c1b --- /dev/null +++ b/include/babeltrace/trace-ir/field-class-const.h @@ -0,0 +1,166 @@ +#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H +#define BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +/* For bt_bool */ +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_field_class; +struct bt_field_path; +struct bt_field_class_signed_enumeration_mapping_ranges; +struct bt_field_class_unsigned_enumeration_mapping_ranges; + +typedef const char * const *bt_field_class_enumeration_mapping_label_array; + +enum bt_field_class_type { + BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER, + BT_FIELD_CLASS_TYPE_SIGNED_INTEGER, + BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, + BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, + BT_FIELD_CLASS_TYPE_REAL, + BT_FIELD_CLASS_TYPE_STRING, + BT_FIELD_CLASS_TYPE_STRUCTURE, + BT_FIELD_CLASS_TYPE_STATIC_ARRAY, + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, + BT_FIELD_CLASS_TYPE_VARIANT, +}; + +enum bt_field_class_integer_preferred_display_base { + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, + BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, +}; + +extern enum bt_field_class_type bt_field_class_get_type( + const struct bt_field_class *field_class); + +extern uint64_t bt_field_class_integer_get_field_value_range( + const struct bt_field_class *field_class); + +extern enum bt_field_class_integer_preferred_display_base +bt_field_class_integer_get_preferred_display_base( + const struct bt_field_class *field_class); + +extern bt_bool bt_field_class_real_is_single_precision( + const struct bt_field_class *field_class); + +extern uint64_t bt_field_class_enumeration_get_mapping_count( + const struct bt_field_class *field_class); + +extern void bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const( + const struct bt_field_class *field_class, uint64_t index, + const char **label, + const struct bt_field_class_unsigned_enumeration_mapping_ranges **ranges); + +extern void bt_field_class_signed_enumeration_borrow_mapping_by_index_const( + const struct bt_field_class *field_class, uint64_t index, + const char **label, + const struct bt_field_class_signed_enumeration_mapping_ranges **ranges); + +extern uint64_t +bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges); + +extern uint64_t +bt_field_class_signed_enumeration_mapping_ranges_get_range_count( + const struct bt_field_class_signed_enumeration_mapping_ranges *ranges); + +extern void +bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, + uint64_t index, uint64_t *lower, uint64_t *upper); + +extern void +bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, + uint64_t index, int64_t *lower, int64_t *upper); + +extern int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( + const struct bt_field_class *field_class, uint64_t value, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count); + +extern int bt_field_class_signed_enumeration_get_mapping_labels_by_value( + const struct bt_field_class *field_class, int64_t value, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count); + +extern uint64_t bt_field_class_structure_get_member_count( + const struct bt_field_class *field_class); + +extern void bt_field_class_structure_borrow_member_by_index_const( + const struct bt_field_class *struct_field_class, uint64_t index, + const char **name, const struct bt_field_class **field_class); + +extern +const struct bt_field_class * +bt_field_class_structure_borrow_member_field_class_by_name_const( + const struct bt_field_class *field_class, const char *name); + +extern const struct bt_field_class * +bt_field_class_array_borrow_element_field_class_const( + const struct bt_field_class *field_class); + +extern uint64_t bt_field_class_static_array_get_length( + const struct bt_field_class *field_class); + +extern const struct bt_field_path * +bt_field_class_dynamic_array_borrow_length_field_path_const( + const struct bt_field_class *field_class); + +extern const struct bt_field_path * +bt_field_class_variant_borrow_selector_field_path_const( + const struct bt_field_class *field_class); + +extern uint64_t bt_field_class_variant_get_option_count( + const struct bt_field_class *field_class); + +extern void bt_field_class_variant_borrow_option_by_index_const( + const struct bt_field_class *variant_field_class, uint64_t index, + const char **name, const struct bt_field_class **field_class); + +extern +const struct bt_field_class * +bt_field_class_variant_borrow_option_field_class_by_name_const( + const struct bt_field_class *field_class, + const char *name); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H */ diff --git a/include/babeltrace/trace-ir/field-class-internal.h b/include/babeltrace/trace-ir/field-class-internal.h new file mode 100644 index 00000000..ea1e3a8b --- /dev/null +++ b/include/babeltrace/trace-ir/field-class-internal.h @@ -0,0 +1,254 @@ +#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H +#define BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BT_ASSERT_PRE_FC_IS_INT(_fc, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ + _name " is not an integer field class: %![fc-]+F", (_fc)) + +#define BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(_fc, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, \ + _name " is not an unsigned integer field class: %![fc-]+F", (_fc)) + +#define BT_ASSERT_PRE_FC_IS_ENUM(_fc, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ + _name " is not an enumeration field class: %![fc-]+F", (_fc)) + +#define BT_ASSERT_PRE_FC_IS_ARRAY(_fc, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY || \ + ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, \ + _name " is not an array field class: %![fc-]+F", (_fc)) + +#define BT_ASSERT_PRE_FC_HAS_ID(_fc, _type, _name) \ + BT_ASSERT_PRE(((const struct bt_field_class *) (_fc))->type == (_type), \ + _name " has the wrong type: expected-type=%s, " \ + "%![fc-]+F", bt_common_field_class_type_string(_type), (_fc)) + +#define BT_ASSERT_PRE_FC_HOT(_fc, _name) \ + BT_ASSERT_PRE_HOT((const struct bt_field_class *) (_fc), \ + (_name), ": %!+F", (_fc)) + +#define BT_FIELD_CLASS_NAMED_FC_AT_INDEX(_fc, _index) \ + (&g_array_index(((struct bt_field_class_named_field_class_container *) (_fc))->named_fcs, \ + struct bt_named_field_class, (_index))) + +#define BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(_fc, _index) \ + (&g_array_index(((struct bt_field_class_enumeration *) (_fc))->mappings, \ + struct bt_field_class_enumeration_mapping, (_index))) + +#define BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index) \ + (&g_array_index((_mapping)->ranges, \ + struct bt_field_class_enumeration_mapping_range, (_index))) + +struct bt_field; +struct bt_field_class; + +struct bt_field_class { + struct bt_object base; + enum bt_field_class_type type; + bool frozen; + + /* + * Only used in developer mode, this flag indicates whether or + * not this field class is part of a trace class. + */ + bool part_of_trace_class; +}; + +struct bt_field_class_integer { + struct bt_field_class common; + + /* + * Value range of fields built from this integer field class: + * this is an equivalent integer size in bits. More formally, + * `range` is `n` in: + * + * Unsigned range: [0, 2^n - 1] + * Signed range: [-2^(n - 1), 2^(n - 1) - 1] + */ + uint64_t range; + + enum bt_field_class_integer_preferred_display_base base; +}; + +struct bt_field_class_enumeration_mapping_range { + union { + uint64_t u; + int64_t i; + } lower; + + union { + uint64_t u; + int64_t i; + } upper; +}; + +struct bt_field_class_enumeration_mapping { + GString *label; + + /* Array of `struct bt_field_class_enumeration_mapping_range` */ + GArray *ranges; +}; + +struct bt_field_class_enumeration { + struct bt_field_class_integer common; + + /* Array of `struct bt_field_class_enumeration_mapping *` */ + GArray *mappings; + + /* + * This is an array of `const char *` which acts as a temporary + * (potentially growing) buffer for + * bt_field_class_unsigned_enumeration_get_mapping_labels_by_value() + * and + * bt_field_class_signed_enumeration_get_mapping_labels_by_value(). + * + * The actual strings are owned by the mappings above. + */ + GPtrArray *label_buf; +}; + +struct bt_field_class_real { + struct bt_field_class common; + bool is_single_precision; +}; + +struct bt_field_class_string { + struct bt_field_class common; +}; + +/* A named field class is a (name, field class) pair */ +struct bt_named_field_class { + GString *name; + + /* Owned by this */ + struct bt_field_class *fc; +}; + +/* + * This is the base field class for a container of named field classes. + * Structure and variant field classes inherit this. + */ +struct bt_field_class_named_field_class_container { + struct bt_field_class common; + + /* + * Key: `const char *`, not owned by this (owned by named field + * type objects contained in `named_fcs` below). + */ + GHashTable *name_to_index; + + /* Array of `struct bt_named_field_class` */ + GArray *named_fcs; +}; + +struct bt_field_class_structure { + struct bt_field_class_named_field_class_container common; +}; + +struct bt_field_class_array { + struct bt_field_class common; + + /* Owned by this */ + struct bt_field_class *element_fc; +}; + +struct bt_field_class_static_array { + struct bt_field_class_array common; + uint64_t length; +}; + +struct bt_field_class_dynamic_array { + struct bt_field_class_array common; + + /* Weak: never dereferenced, only use to find it elsewhere */ + struct bt_field_class *length_fc; + + /* Owned by this */ + struct bt_field_path *length_field_path; +}; + +struct bt_field_class_variant { + struct bt_field_class_named_field_class_container common; + + /* Weak: never dereferenced, only use to find it elsewhere */ + struct bt_field_class *selector_fc; + + /* Owned by this */ + struct bt_field_path *selector_field_path; +}; + +static inline +bool bt_field_class_has_known_type(const struct bt_field_class *fc) +{ + return fc->type >= BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER && + fc->type <= BT_FIELD_CLASS_TYPE_VARIANT; +} + +BT_HIDDEN +void _bt_field_class_freeze(const struct bt_field_class *field_class); + +#ifdef BT_DEV_MODE +# define bt_field_class_freeze _bt_field_class_freeze +#else +# define bt_field_class_freeze(_fc) +#endif + +/* + * This function recursively marks `field_class` and its children as + * being part of a trace. This is used to validate that all field classes + * are used at a single location within trace objects even if they are + * shared objects for other purposes. + */ +BT_HIDDEN +void _bt_field_class_make_part_of_trace_class( + const struct bt_field_class *field_class); + +#ifdef BT_DEV_MODE +# define bt_field_class_make_part_of_trace_class _bt_field_class_make_part_of_trace_class +#else +# define bt_field_class_make_part_of_trace_class(_fc) ((void) _fc) +#endif + +#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H */ diff --git a/include/babeltrace/trace-ir/field-class.h b/include/babeltrace/trace-ir/field-class.h new file mode 100644 index 00000000..79a1a159 --- /dev/null +++ b/include/babeltrace/trace-ir/field-class.h @@ -0,0 +1,107 @@ +#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_H +#define BABELTRACE_TRACE_IR_FIELD_CLASSES_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +/* For bt_bool */ +#include + +/* For enum bt_field_class_integer_preferred_display_base */ +#include + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_field_class; + +extern struct bt_field_class *bt_field_class_unsigned_integer_create(void); + +extern struct bt_field_class *bt_field_class_signed_integer_create(void); + +extern void bt_field_class_integer_set_field_value_range( + struct bt_field_class *field_class, uint64_t size); + +extern void bt_field_class_integer_set_preferred_display_base( + struct bt_field_class *field_class, + enum bt_field_class_integer_preferred_display_base base); + +extern struct bt_field_class *bt_field_class_real_create(void); + +extern void bt_field_class_real_set_is_single_precision( + struct bt_field_class *field_class, + bt_bool is_single_precision); + +extern struct bt_field_class *bt_field_class_unsigned_enumeration_create(void); + +extern struct bt_field_class *bt_field_class_signed_enumeration_create(void); + +extern int bt_field_class_unsigned_enumeration_map_range( + struct bt_field_class *field_class, const char *label, + uint64_t range_lower, uint64_t range_upper); + +extern int bt_field_class_signed_enumeration_map_range( + struct bt_field_class *field_class, const char *label, + int64_t range_lower, int64_t range_upper); + +extern struct bt_field_class *bt_field_class_string_create(void); + +extern struct bt_field_class *bt_field_class_structure_create(void); + +extern int bt_field_class_structure_append_member( + struct bt_field_class *struct_field_class, + const char *name, struct bt_field_class *field_class); + +extern struct bt_field_class *bt_field_class_static_array_create( + struct bt_field_class *elem_field_class, uint64_t length); + +extern struct bt_field_class *bt_field_class_dynamic_array_create( + struct bt_field_class *elem_field_class); + +extern int bt_field_class_dynamic_array_set_length_field_class( + struct bt_field_class *field_class, + struct bt_field_class *length_field_class); + +extern struct bt_field_class *bt_field_class_variant_create(void); + +extern int bt_field_class_variant_set_selector_field_class( + struct bt_field_class *field_class, + struct bt_field_class *selector_field_class); + +extern int bt_field_class_variant_append_option( + struct bt_field_class *var_field_class, + const char *name, struct bt_field_class *field_class); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_H */ diff --git a/include/babeltrace/trace-ir/field-classes-const.h b/include/babeltrace/trace-ir/field-classes-const.h deleted file mode 100644 index 87992c1b..00000000 --- a/include/babeltrace/trace-ir/field-classes-const.h +++ /dev/null @@ -1,166 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H -#define BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * The Common Trace Format (CTF) Specification is available at - * http://www.efficios.com/ctf - */ - -/* For bt_bool */ -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_field_class; -struct bt_field_path; -struct bt_field_class_signed_enumeration_mapping_ranges; -struct bt_field_class_unsigned_enumeration_mapping_ranges; - -typedef const char * const *bt_field_class_enumeration_mapping_label_array; - -enum bt_field_class_type { - BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER, - BT_FIELD_CLASS_TYPE_SIGNED_INTEGER, - BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, - BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, - BT_FIELD_CLASS_TYPE_REAL, - BT_FIELD_CLASS_TYPE_STRING, - BT_FIELD_CLASS_TYPE_STRUCTURE, - BT_FIELD_CLASS_TYPE_STATIC_ARRAY, - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, - BT_FIELD_CLASS_TYPE_VARIANT, -}; - -enum bt_field_class_integer_preferred_display_base { - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_BINARY, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_OCTAL, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL, - BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL, -}; - -extern enum bt_field_class_type bt_field_class_get_type( - const struct bt_field_class *field_class); - -extern uint64_t bt_field_class_integer_get_field_value_range( - const struct bt_field_class *field_class); - -extern enum bt_field_class_integer_preferred_display_base -bt_field_class_integer_get_preferred_display_base( - const struct bt_field_class *field_class); - -extern bt_bool bt_field_class_real_is_single_precision( - const struct bt_field_class *field_class); - -extern uint64_t bt_field_class_enumeration_get_mapping_count( - const struct bt_field_class *field_class); - -extern void bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const( - const struct bt_field_class *field_class, uint64_t index, - const char **label, - const struct bt_field_class_unsigned_enumeration_mapping_ranges **ranges); - -extern void bt_field_class_signed_enumeration_borrow_mapping_by_index_const( - const struct bt_field_class *field_class, uint64_t index, - const char **label, - const struct bt_field_class_signed_enumeration_mapping_ranges **ranges); - -extern uint64_t -bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges); - -extern uint64_t -bt_field_class_signed_enumeration_mapping_ranges_get_range_count( - const struct bt_field_class_signed_enumeration_mapping_ranges *ranges); - -extern void -bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, - uint64_t index, uint64_t *lower, uint64_t *upper); - -extern void -bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, - uint64_t index, int64_t *lower, int64_t *upper); - -extern int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( - const struct bt_field_class *field_class, uint64_t value, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count); - -extern int bt_field_class_signed_enumeration_get_mapping_labels_by_value( - const struct bt_field_class *field_class, int64_t value, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count); - -extern uint64_t bt_field_class_structure_get_member_count( - const struct bt_field_class *field_class); - -extern void bt_field_class_structure_borrow_member_by_index_const( - const struct bt_field_class *struct_field_class, uint64_t index, - const char **name, const struct bt_field_class **field_class); - -extern -const struct bt_field_class * -bt_field_class_structure_borrow_member_field_class_by_name_const( - const struct bt_field_class *field_class, const char *name); - -extern const struct bt_field_class * -bt_field_class_array_borrow_element_field_class_const( - const struct bt_field_class *field_class); - -extern uint64_t bt_field_class_static_array_get_length( - const struct bt_field_class *field_class); - -extern const struct bt_field_path * -bt_field_class_dynamic_array_borrow_length_field_path_const( - const struct bt_field_class *field_class); - -extern const struct bt_field_path * -bt_field_class_variant_borrow_selector_field_path_const( - const struct bt_field_class *field_class); - -extern uint64_t bt_field_class_variant_get_option_count( - const struct bt_field_class *field_class); - -extern void bt_field_class_variant_borrow_option_by_index_const( - const struct bt_field_class *variant_field_class, uint64_t index, - const char **name, const struct bt_field_class **field_class); - -extern -const struct bt_field_class * -bt_field_class_variant_borrow_option_field_class_by_name_const( - const struct bt_field_class *field_class, - const char *name); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_CONST_H */ diff --git a/include/babeltrace/trace-ir/field-classes-internal.h b/include/babeltrace/trace-ir/field-classes-internal.h deleted file mode 100644 index 94056c3e..00000000 --- a/include/babeltrace/trace-ir/field-classes-internal.h +++ /dev/null @@ -1,254 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H -#define BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define BT_ASSERT_PRE_FC_IS_INT(_fc, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ - _name " is not an integer field class: %![fc-]+F", (_fc)) - -#define BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(_fc, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, \ - _name " is not an unsigned integer field class: %![fc-]+F", (_fc)) - -#define BT_ASSERT_PRE_FC_IS_ENUM(_fc, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ - _name " is not an enumeration field class: %![fc-]+F", (_fc)) - -#define BT_ASSERT_PRE_FC_IS_ARRAY(_fc, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY || \ - ((const struct bt_field_class *) (_fc))->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, \ - _name " is not an array field class: %![fc-]+F", (_fc)) - -#define BT_ASSERT_PRE_FC_HAS_ID(_fc, _type, _name) \ - BT_ASSERT_PRE(((const struct bt_field_class *) (_fc))->type == (_type), \ - _name " has the wrong type: expected-type=%s, " \ - "%![fc-]+F", bt_common_field_class_type_string(_type), (_fc)) - -#define BT_ASSERT_PRE_FC_HOT(_fc, _name) \ - BT_ASSERT_PRE_HOT((const struct bt_field_class *) (_fc), \ - (_name), ": %!+F", (_fc)) - -#define BT_FIELD_CLASS_NAMED_FC_AT_INDEX(_fc, _index) \ - (&g_array_index(((struct bt_field_class_named_field_class_container *) (_fc))->named_fcs, \ - struct bt_named_field_class, (_index))) - -#define BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(_fc, _index) \ - (&g_array_index(((struct bt_field_class_enumeration *) (_fc))->mappings, \ - struct bt_field_class_enumeration_mapping, (_index))) - -#define BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(_mapping, _index) \ - (&g_array_index((_mapping)->ranges, \ - struct bt_field_class_enumeration_mapping_range, (_index))) - -struct bt_field; -struct bt_field_class; - -struct bt_field_class { - struct bt_object base; - enum bt_field_class_type type; - bool frozen; - - /* - * Only used in developer mode, this flag indicates whether or - * not this field class is part of a trace class. - */ - bool part_of_trace_class; -}; - -struct bt_field_class_integer { - struct bt_field_class common; - - /* - * Value range of fields built from this integer field class: - * this is an equivalent integer size in bits. More formally, - * `range` is `n` in: - * - * Unsigned range: [0, 2^n - 1] - * Signed range: [-2^(n - 1), 2^(n - 1) - 1] - */ - uint64_t range; - - enum bt_field_class_integer_preferred_display_base base; -}; - -struct bt_field_class_enumeration_mapping_range { - union { - uint64_t u; - int64_t i; - } lower; - - union { - uint64_t u; - int64_t i; - } upper; -}; - -struct bt_field_class_enumeration_mapping { - GString *label; - - /* Array of `struct bt_field_class_enumeration_mapping_range` */ - GArray *ranges; -}; - -struct bt_field_class_enumeration { - struct bt_field_class_integer common; - - /* Array of `struct bt_field_class_enumeration_mapping *` */ - GArray *mappings; - - /* - * This is an array of `const char *` which acts as a temporary - * (potentially growing) buffer for - * bt_field_class_unsigned_enumeration_get_mapping_labels_by_value() - * and - * bt_field_class_signed_enumeration_get_mapping_labels_by_value(). - * - * The actual strings are owned by the mappings above. - */ - GPtrArray *label_buf; -}; - -struct bt_field_class_real { - struct bt_field_class common; - bool is_single_precision; -}; - -struct bt_field_class_string { - struct bt_field_class common; -}; - -/* A named field class is a (name, field class) pair */ -struct bt_named_field_class { - GString *name; - - /* Owned by this */ - struct bt_field_class *fc; -}; - -/* - * This is the base field class for a container of named field classes. - * Structure and variant field classes inherit this. - */ -struct bt_field_class_named_field_class_container { - struct bt_field_class common; - - /* - * Key: `const char *`, not owned by this (owned by named field - * type objects contained in `named_fcs` below). - */ - GHashTable *name_to_index; - - /* Array of `struct bt_named_field_class` */ - GArray *named_fcs; -}; - -struct bt_field_class_structure { - struct bt_field_class_named_field_class_container common; -}; - -struct bt_field_class_array { - struct bt_field_class common; - - /* Owned by this */ - struct bt_field_class *element_fc; -}; - -struct bt_field_class_static_array { - struct bt_field_class_array common; - uint64_t length; -}; - -struct bt_field_class_dynamic_array { - struct bt_field_class_array common; - - /* Weak: never dereferenced, only use to find it elsewhere */ - struct bt_field_class *length_fc; - - /* Owned by this */ - struct bt_field_path *length_field_path; -}; - -struct bt_field_class_variant { - struct bt_field_class_named_field_class_container common; - - /* Weak: never dereferenced, only use to find it elsewhere */ - struct bt_field_class *selector_fc; - - /* Owned by this */ - struct bt_field_path *selector_field_path; -}; - -static inline -bool bt_field_class_has_known_type(const struct bt_field_class *fc) -{ - return fc->type >= BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER && - fc->type <= BT_FIELD_CLASS_TYPE_VARIANT; -} - -BT_HIDDEN -void _bt_field_class_freeze(const struct bt_field_class *field_class); - -#ifdef BT_DEV_MODE -# define bt_field_class_freeze _bt_field_class_freeze -#else -# define bt_field_class_freeze(_fc) -#endif - -/* - * This function recursively marks `field_class` and its children as - * being part of a trace. This is used to validate that all field classes - * are used at a single location within trace objects even if they are - * shared objects for other purposes. - */ -BT_HIDDEN -void _bt_field_class_make_part_of_trace_class( - const struct bt_field_class *field_class); - -#ifdef BT_DEV_MODE -# define bt_field_class_make_part_of_trace_class _bt_field_class_make_part_of_trace_class -#else -# define bt_field_class_make_part_of_trace_class(_fc) ((void) _fc) -#endif - -#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_INTERNAL_H */ diff --git a/include/babeltrace/trace-ir/field-classes.h b/include/babeltrace/trace-ir/field-classes.h deleted file mode 100644 index 91806629..00000000 --- a/include/babeltrace/trace-ir/field-classes.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELD_CLASSES_H -#define BABELTRACE_TRACE_IR_FIELD_CLASSES_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * The Common Trace Format (CTF) Specification is available at - * http://www.efficios.com/ctf - */ - -/* For bt_bool */ -#include - -/* For enum bt_field_class_integer_preferred_display_base */ -#include - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_field_class; - -extern struct bt_field_class *bt_field_class_unsigned_integer_create(void); - -extern struct bt_field_class *bt_field_class_signed_integer_create(void); - -extern void bt_field_class_integer_set_field_value_range( - struct bt_field_class *field_class, uint64_t size); - -extern void bt_field_class_integer_set_preferred_display_base( - struct bt_field_class *field_class, - enum bt_field_class_integer_preferred_display_base base); - -extern struct bt_field_class *bt_field_class_real_create(void); - -extern void bt_field_class_real_set_is_single_precision( - struct bt_field_class *field_class, - bt_bool is_single_precision); - -extern struct bt_field_class *bt_field_class_unsigned_enumeration_create(void); - -extern struct bt_field_class *bt_field_class_signed_enumeration_create(void); - -extern int bt_field_class_unsigned_enumeration_map_range( - struct bt_field_class *field_class, const char *label, - uint64_t range_lower, uint64_t range_upper); - -extern int bt_field_class_signed_enumeration_map_range( - struct bt_field_class *field_class, const char *label, - int64_t range_lower, int64_t range_upper); - -extern struct bt_field_class *bt_field_class_string_create(void); - -extern struct bt_field_class *bt_field_class_structure_create(void); - -extern int bt_field_class_structure_append_member( - struct bt_field_class *struct_field_class, - const char *name, struct bt_field_class *field_class); - -extern struct bt_field_class *bt_field_class_static_array_create( - struct bt_field_class *elem_field_class, uint64_t length); - -extern struct bt_field_class *bt_field_class_dynamic_array_create( - struct bt_field_class *elem_field_class); - -extern int bt_field_class_dynamic_array_set_length_field_class( - struct bt_field_class *field_class, - struct bt_field_class *length_field_class); - -extern struct bt_field_class *bt_field_class_variant_create(void); - -extern int bt_field_class_variant_set_selector_field_class( - struct bt_field_class *field_class, - struct bt_field_class *selector_field_class); - -extern int bt_field_class_variant_append_option( - struct bt_field_class *var_field_class, - const char *name, struct bt_field_class *field_class); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_TRACE_IR_FIELD_CLASSES_H */ diff --git a/include/babeltrace/trace-ir/field-const.h b/include/babeltrace/trace-ir/field-const.h new file mode 100644 index 00000000..d868c4e7 --- /dev/null +++ b/include/babeltrace/trace-ir/field-const.h @@ -0,0 +1,95 @@ +#ifndef BABELTRACE_TRACE_IR_FIELDS_CONST_H +#define BABELTRACE_TRACE_IR_FIELDS_CONST_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#include + +/* For enum bt_field_class_type */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_field; +struct bt_field_class; + +extern const struct bt_field_class *bt_field_borrow_class_const( + const struct bt_field *field); + +extern enum bt_field_class_type bt_field_get_class_type( + const struct bt_field *field); + +extern int64_t bt_field_signed_integer_get_value(const struct bt_field *field); + +extern uint64_t bt_field_unsigned_integer_get_value( + const struct bt_field *field); + +extern double bt_field_real_get_value(const struct bt_field *field); + +extern int bt_field_unsigned_enumeration_get_mapping_labels( + const struct bt_field *field, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count); + +extern int bt_field_signed_enumeration_get_mapping_labels( + const struct bt_field *field, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count); + +extern const char *bt_field_string_get_value(const struct bt_field *field); + +extern uint64_t bt_field_string_get_length(const struct bt_field *field); + +extern const struct bt_field * +bt_field_structure_borrow_member_field_by_index_const( + const struct bt_field *field, uint64_t index); + +extern const struct bt_field * +bt_field_structure_borrow_member_field_by_name_const( + const struct bt_field *field, const char *name); + +extern uint64_t bt_field_array_get_length(const struct bt_field *field); + +extern const struct bt_field * +bt_field_array_borrow_element_field_by_index_const( + const struct bt_field *field, uint64_t index); + +extern uint64_t bt_field_variant_get_selected_option_field_index( + const struct bt_field *field); + +extern const struct bt_field * +bt_field_variant_borrow_selected_option_field_const( + const struct bt_field *field); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_TRACE_IR_FIELDS_CONST_H */ diff --git a/include/babeltrace/trace-ir/field-internal.h b/include/babeltrace/trace-ir/field-internal.h new file mode 100644 index 00000000..492aeccd --- /dev/null +++ b/include/babeltrace/trace-ir/field-internal.h @@ -0,0 +1,204 @@ +#ifndef BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H +#define BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(_field, _cls_type, _name) \ + BT_ASSERT_PRE(((const struct bt_field *) (_field))->class->type == (_cls_type), \ + _name " has the wrong class type: expected-class-type=%s, " \ + "%![field-]+f", \ + bt_common_field_class_type_string(_cls_type), (_field)) + +#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, \ + _name " is not an unsigned integer field: %![field-]+f", \ + (_field)) + +#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ + _name " is not a signed integer field: %![field-]+f", \ + (_field)) + +#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name) \ + BT_ASSERT_PRE( \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY || \ + ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, \ + _name " is not an array field: %![field-]+f", (_field)) + +#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name) \ + BT_ASSERT_PRE(bt_field_is_set(_field), \ + _name " is not set: %!+f", (_field)) + +#define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \ + BT_ASSERT_PRE_HOT((const struct bt_field *) (_field), (_name), \ + ": %!+f", (_field)) + +struct bt_field; + +typedef struct bt_field *(* bt_field_create_func)(struct bt_field_class *); +typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool); +typedef bool (*bt_field_method_is_set)(const struct bt_field *); +typedef void (*bt_field_method_reset)(struct bt_field *); + +struct bt_field_methods { + bt_field_method_set_is_frozen set_is_frozen; + bt_field_method_is_set is_set; + bt_field_method_reset reset; +}; + +struct bt_field { + struct bt_object base; + + /* Owned by this */ + struct bt_field_class *class; + + /* Virtual table for slow path (dev mode) operations */ + struct bt_field_methods *methods; + + bool is_set; + bool frozen; +}; + +struct bt_field_integer { + struct bt_field common; + + union { + uint64_t u; + int64_t i; + } value; +}; + +struct bt_field_real { + struct bt_field common; + double value; +}; + +struct bt_field_structure { + struct bt_field common; + + /* Array of `struct bt_field *`, owned by this */ + GPtrArray *fields; +}; + +struct bt_field_variant { + struct bt_field common; + + /* Weak: belongs to `fields` below */ + struct bt_field *selected_field; + + /* Index of currently selected field */ + uint64_t selected_index; + + /* Array of `struct bt_field *`, owned by this */ + GPtrArray *fields; +}; + +struct bt_field_array { + struct bt_field common; + + /* Array of `struct bt_field *`, owned by this */ + GPtrArray *fields; + + /* Current effective length */ + uint64_t length; +}; + +struct bt_field_string { + struct bt_field common; + GArray *buf; + uint64_t length; +}; + +#ifdef BT_DEV_MODE +# define bt_field_set_is_frozen _bt_field_set_is_frozen +# define bt_field_is_set _bt_field_is_set +# define bt_field_reset _bt_field_reset +# define bt_field_set_single _bt_field_set_single +#else +# define bt_field_set_is_frozen(_field, _is_frozen) +# define bt_field_is_set(_field) (BT_FALSE) +# define bt_field_reset(_field) +# define bt_field_set_single(_field, _val) +#endif + +BT_HIDDEN +void _bt_field_set_is_frozen(const struct bt_field *field, bool is_frozen); + +static inline +void _bt_field_reset(const struct bt_field *field) +{ + BT_ASSERT(field); + BT_ASSERT(field->methods->reset); + field->methods->reset((void *) field); +} + +static inline +void _bt_field_set_single(struct bt_field *field, bool value) +{ + BT_ASSERT(field); + field->is_set = value; +} + +static inline +bt_bool _bt_field_is_set(const struct bt_field *field) +{ + bt_bool is_set = BT_FALSE; + + if (!field) { + goto end; + } + + BT_ASSERT(bt_field_class_has_known_type(field->class)); + BT_ASSERT(field->methods->is_set); + is_set = field->methods->is_set(field); + +end: + return is_set; +} + +BT_HIDDEN +struct bt_field *bt_field_create(struct bt_field_class *class); + +BT_HIDDEN +void bt_field_destroy(struct bt_field *field); + +#endif /* BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H */ diff --git a/include/babeltrace/trace-ir/field-wrapper-internal.h b/include/babeltrace/trace-ir/field-wrapper-internal.h index 732132f6..d1a7a9d8 100644 --- a/include/babeltrace/trace-ir/field-wrapper-internal.h +++ b/include/babeltrace/trace-ir/field-wrapper-internal.h @@ -23,7 +23,7 @@ * SOFTWARE. */ -#include +#include #include #include diff --git a/include/babeltrace/trace-ir/field.h b/include/babeltrace/trace-ir/field.h new file mode 100644 index 00000000..53a9da39 --- /dev/null +++ b/include/babeltrace/trace-ir/field.h @@ -0,0 +1,79 @@ +#ifndef BABELTRACE_TRACE_IR_FIELDS_H +#define BABELTRACE_TRACE_IR_FIELDS_H + +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * The Common Trace Format (CTF) Specification is available at + * http://www.efficios.com/ctf + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_field; +struct bt_field_class; + +extern void bt_field_signed_integer_set_value(struct bt_field *field, + int64_t value); + +extern void bt_field_unsigned_integer_set_value(struct bt_field *field, + uint64_t value); + +extern void bt_field_real_set_value(struct bt_field *field, double value); + +extern int bt_field_string_set_value(struct bt_field *field, const char *value); + +extern int bt_field_string_append(struct bt_field *field, const char *value); + +extern int bt_field_string_append_with_length(struct bt_field *field, + const char *value, uint64_t length); + +extern int bt_field_string_clear(struct bt_field *field); + +extern struct bt_field *bt_field_structure_borrow_member_field_by_index( + struct bt_field *field, uint64_t index); + +extern struct bt_field *bt_field_structure_borrow_member_field_by_name( + struct bt_field *field, const char *name); + +extern struct bt_field *bt_field_array_borrow_element_field_by_index( + struct bt_field *field, uint64_t index); + +extern int bt_field_dynamic_array_set_length(struct bt_field *field, + uint64_t length); + +extern int bt_field_variant_select_option_field(struct bt_field *field, + uint64_t index); + +extern struct bt_field *bt_field_variant_borrow_selected_option_field( + struct bt_field *field); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_TRACE_IR_FIELDS_H */ diff --git a/include/babeltrace/trace-ir/fields-const.h b/include/babeltrace/trace-ir/fields-const.h deleted file mode 100644 index 53188acb..00000000 --- a/include/babeltrace/trace-ir/fields-const.h +++ /dev/null @@ -1,95 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELDS_CONST_H -#define BABELTRACE_TRACE_IR_FIELDS_CONST_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * The Common Trace Format (CTF) Specification is available at - * http://www.efficios.com/ctf - */ - -#include - -/* For enum bt_field_class_type */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_field; -struct bt_field_class; - -extern const struct bt_field_class *bt_field_borrow_class_const( - const struct bt_field *field); - -extern enum bt_field_class_type bt_field_get_class_type( - const struct bt_field *field); - -extern int64_t bt_field_signed_integer_get_value(const struct bt_field *field); - -extern uint64_t bt_field_unsigned_integer_get_value( - const struct bt_field *field); - -extern double bt_field_real_get_value(const struct bt_field *field); - -extern int bt_field_unsigned_enumeration_get_mapping_labels( - const struct bt_field *field, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count); - -extern int bt_field_signed_enumeration_get_mapping_labels( - const struct bt_field *field, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count); - -extern const char *bt_field_string_get_value(const struct bt_field *field); - -extern uint64_t bt_field_string_get_length(const struct bt_field *field); - -extern const struct bt_field * -bt_field_structure_borrow_member_field_by_index_const( - const struct bt_field *field, uint64_t index); - -extern const struct bt_field * -bt_field_structure_borrow_member_field_by_name_const( - const struct bt_field *field, const char *name); - -extern uint64_t bt_field_array_get_length(const struct bt_field *field); - -extern const struct bt_field * -bt_field_array_borrow_element_field_by_index_const( - const struct bt_field *field, uint64_t index); - -extern uint64_t bt_field_variant_get_selected_option_field_index( - const struct bt_field *field); - -extern const struct bt_field * -bt_field_variant_borrow_selected_option_field_const( - const struct bt_field *field); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_TRACE_IR_FIELDS_CONST_H */ diff --git a/include/babeltrace/trace-ir/fields-internal.h b/include/babeltrace/trace-ir/fields-internal.h deleted file mode 100644 index 957293b7..00000000 --- a/include/babeltrace/trace-ir/fields-internal.h +++ /dev/null @@ -1,204 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H -#define BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(_field, _cls_type, _name) \ - BT_ASSERT_PRE(((const struct bt_field *) (_field))->class->type == (_cls_type), \ - _name " has the wrong class type: expected-class-type=%s, " \ - "%![field-]+f", \ - bt_common_field_class_type_string(_cls_type), (_field)) - -#define BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(_field, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, \ - _name " is not an unsigned integer field: %![field-]+f", \ - (_field)) - -#define BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(_field, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, \ - _name " is not a signed integer field: %![field-]+f", \ - (_field)) - -#define BT_ASSERT_PRE_FIELD_IS_ARRAY(_field, _name) \ - BT_ASSERT_PRE( \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY || \ - ((const struct bt_field *) (_field))->class->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, \ - _name " is not an array field: %![field-]+f", (_field)) - -#define BT_ASSERT_PRE_FIELD_IS_SET(_field, _name) \ - BT_ASSERT_PRE(bt_field_is_set(_field), \ - _name " is not set: %!+f", (_field)) - -#define BT_ASSERT_PRE_FIELD_HOT(_field, _name) \ - BT_ASSERT_PRE_HOT((const struct bt_field *) (_field), (_name), \ - ": %!+f", (_field)) - -struct bt_field; - -typedef struct bt_field *(* bt_field_create_func)(struct bt_field_class *); -typedef void (*bt_field_method_set_is_frozen)(struct bt_field *, bool); -typedef bool (*bt_field_method_is_set)(const struct bt_field *); -typedef void (*bt_field_method_reset)(struct bt_field *); - -struct bt_field_methods { - bt_field_method_set_is_frozen set_is_frozen; - bt_field_method_is_set is_set; - bt_field_method_reset reset; -}; - -struct bt_field { - struct bt_object base; - - /* Owned by this */ - struct bt_field_class *class; - - /* Virtual table for slow path (dev mode) operations */ - struct bt_field_methods *methods; - - bool is_set; - bool frozen; -}; - -struct bt_field_integer { - struct bt_field common; - - union { - uint64_t u; - int64_t i; - } value; -}; - -struct bt_field_real { - struct bt_field common; - double value; -}; - -struct bt_field_structure { - struct bt_field common; - - /* Array of `struct bt_field *`, owned by this */ - GPtrArray *fields; -}; - -struct bt_field_variant { - struct bt_field common; - - /* Weak: belongs to `fields` below */ - struct bt_field *selected_field; - - /* Index of currently selected field */ - uint64_t selected_index; - - /* Array of `struct bt_field *`, owned by this */ - GPtrArray *fields; -}; - -struct bt_field_array { - struct bt_field common; - - /* Array of `struct bt_field *`, owned by this */ - GPtrArray *fields; - - /* Current effective length */ - uint64_t length; -}; - -struct bt_field_string { - struct bt_field common; - GArray *buf; - uint64_t length; -}; - -#ifdef BT_DEV_MODE -# define bt_field_set_is_frozen _bt_field_set_is_frozen -# define bt_field_is_set _bt_field_is_set -# define bt_field_reset _bt_field_reset -# define bt_field_set_single _bt_field_set_single -#else -# define bt_field_set_is_frozen(_field, _is_frozen) -# define bt_field_is_set(_field) (BT_FALSE) -# define bt_field_reset(_field) -# define bt_field_set_single(_field, _val) -#endif - -BT_HIDDEN -void _bt_field_set_is_frozen(const struct bt_field *field, bool is_frozen); - -static inline -void _bt_field_reset(const struct bt_field *field) -{ - BT_ASSERT(field); - BT_ASSERT(field->methods->reset); - field->methods->reset((void *) field); -} - -static inline -void _bt_field_set_single(struct bt_field *field, bool value) -{ - BT_ASSERT(field); - field->is_set = value; -} - -static inline -bt_bool _bt_field_is_set(const struct bt_field *field) -{ - bt_bool is_set = BT_FALSE; - - if (!field) { - goto end; - } - - BT_ASSERT(bt_field_class_has_known_type(field->class)); - BT_ASSERT(field->methods->is_set); - is_set = field->methods->is_set(field); - -end: - return is_set; -} - -BT_HIDDEN -struct bt_field *bt_field_create(struct bt_field_class *class); - -BT_HIDDEN -void bt_field_destroy(struct bt_field *field); - -#endif /* BABELTRACE_TRACE_IR_FIELDS_INTERNAL_H */ diff --git a/include/babeltrace/trace-ir/fields.h b/include/babeltrace/trace-ir/fields.h deleted file mode 100644 index 53a9da39..00000000 --- a/include/babeltrace/trace-ir/fields.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef BABELTRACE_TRACE_IR_FIELDS_H -#define BABELTRACE_TRACE_IR_FIELDS_H - -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - * The Common Trace Format (CTF) Specification is available at - * http://www.efficios.com/ctf - */ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_field; -struct bt_field_class; - -extern void bt_field_signed_integer_set_value(struct bt_field *field, - int64_t value); - -extern void bt_field_unsigned_integer_set_value(struct bt_field *field, - uint64_t value); - -extern void bt_field_real_set_value(struct bt_field *field, double value); - -extern int bt_field_string_set_value(struct bt_field *field, const char *value); - -extern int bt_field_string_append(struct bt_field *field, const char *value); - -extern int bt_field_string_append_with_length(struct bt_field *field, - const char *value, uint64_t length); - -extern int bt_field_string_clear(struct bt_field *field); - -extern struct bt_field *bt_field_structure_borrow_member_field_by_index( - struct bt_field *field, uint64_t index); - -extern struct bt_field *bt_field_structure_borrow_member_field_by_name( - struct bt_field *field, const char *name); - -extern struct bt_field *bt_field_array_borrow_element_field_by_index( - struct bt_field *field, uint64_t index); - -extern int bt_field_dynamic_array_set_length(struct bt_field *field, - uint64_t length); - -extern int bt_field_variant_select_option_field(struct bt_field *field, - uint64_t index); - -extern struct bt_field *bt_field_variant_borrow_selected_option_field( - struct bt_field *field); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_TRACE_IR_FIELDS_H */ diff --git a/include/babeltrace/trace-ir/packet-internal.h b/include/babeltrace/trace-ir/packet-internal.h index 3623c6bb..9f963087 100644 --- a/include/babeltrace/trace-ir/packet-internal.h +++ b/include/babeltrace/trace-ir/packet-internal.h @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/resolve-field-path-internal.h b/include/babeltrace/trace-ir/resolve-field-path-internal.h index f7abb4e2..f6957811 100644 --- a/include/babeltrace/trace-ir/resolve-field-path-internal.h +++ b/include/babeltrace/trace-ir/resolve-field-path-internal.h @@ -27,7 +27,7 @@ */ #include -#include +#include #include #include diff --git a/include/babeltrace/trace-ir/stream-class-internal.h b/include/babeltrace/trace-ir/stream-class-internal.h index 8774db7a..9d5f0429 100644 --- a/include/babeltrace/trace-ir/stream-class-internal.h +++ b/include/babeltrace/trace-ir/stream-class-internal.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/trace-class-internal.h b/include/babeltrace/trace-ir/trace-class-internal.h index 46bf525f..b5e8fb3f 100644 --- a/include/babeltrace/trace-ir/trace-class-internal.h +++ b/include/babeltrace/trace-ir/trace-class-internal.h @@ -28,14 +28,14 @@ #include #include #include -#include -#include +#include +#include #include #include #include #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/trace-internal.h b/include/babeltrace/trace-ir/trace-internal.h index 3b6eb1c7..4154be6e 100644 --- a/include/babeltrace/trace-ir/trace-internal.h +++ b/include/babeltrace/trace-ir/trace-internal.h @@ -29,14 +29,14 @@ #include #include #include -#include -#include +#include +#include #include #include #include #include #include -#include +#include #include #include #include diff --git a/include/babeltrace/trace-ir/utils-internal.h b/include/babeltrace/trace-ir/utils-internal.h index 36cb2908..b828f399 100644 --- a/include/babeltrace/trace-ir/utils-internal.h +++ b/include/babeltrace/trace-ir/utils-internal.h @@ -22,7 +22,7 @@ */ #include -#include +#include #include #include diff --git a/include/babeltrace/value-const.h b/include/babeltrace/value-const.h new file mode 100644 index 00000000..6816d37d --- /dev/null +++ b/include/babeltrace/value-const.h @@ -0,0 +1,172 @@ +#ifndef BABELTRACE_VALUES_CONST_H +#define BABELTRACE_VALUES_CONST_H + +/* + * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation + * Copyright (c) 2015-2016 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +/* For bt_bool */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_value; + +enum bt_value_status { + /// Operation canceled. + BT_VALUE_STATUS_CANCELED = 125, + + /// Cannot allocate memory. + BT_VALUE_STATUS_NOMEM = -12, + + /// Okay, no error. + BT_VALUE_STATUS_OK = 0, +}; + +enum bt_value_type { + /// Null value object. + BT_VALUE_TYPE_NULL = 0, + + /// Boolean value object (holds #BT_TRUE or #BT_FALSE). + BT_VALUE_TYPE_BOOL = 1, + + /// Integer value object (holds a signed 64-bit integer raw value). + BT_VALUE_TYPE_INTEGER = 2, + + /// Floating point number value object (holds a \c double raw value). + BT_VALUE_TYPE_REAL = 3, + + /// String value object. + BT_VALUE_TYPE_STRING = 4, + + /// Array value object. + BT_VALUE_TYPE_ARRAY = 5, + + /// Map value object. + BT_VALUE_TYPE_MAP = 6, +}; + +extern enum bt_value_type bt_value_get_type(const struct bt_value *object); + +static inline +bt_bool bt_value_is_null(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_NULL; +} + +static inline +bt_bool bt_value_is_bool(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_BOOL; +} + +static inline +bt_bool bt_value_is_integer(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_INTEGER; +} + +static inline +bt_bool bt_value_is_real(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_REAL; +} + +static inline +bt_bool bt_value_is_string(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_STRING; +} + +static inline +bt_bool bt_value_is_array(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_ARRAY; +} + +static inline +bt_bool bt_value_is_map(const struct bt_value *object) +{ + return bt_value_get_type(object) == BT_VALUE_TYPE_MAP; +} + +extern enum bt_value_status bt_value_copy(const struct bt_value *object, + struct bt_value **copy); + +extern bt_bool bt_value_compare(const struct bt_value *object_a, + const struct bt_value *object_b); + +extern bt_bool bt_value_bool_get(const struct bt_value *bool_obj); + +extern int64_t bt_value_integer_get(const struct bt_value *integer_obj); + +extern double bt_value_real_get(const struct bt_value *real_obj); + +extern const char *bt_value_string_get(const struct bt_value *string_obj); + +extern uint64_t bt_value_array_get_size(const struct bt_value *array_obj); + +static inline +bt_bool bt_value_array_is_empty(const struct bt_value *array_obj) +{ + return bt_value_array_get_size(array_obj) == 0; +} + +extern const struct bt_value *bt_value_array_borrow_element_by_index_const( + const struct bt_value *array_obj, uint64_t index); + +extern uint64_t bt_value_map_get_size(const struct bt_value *map_obj); + +static inline +bt_bool bt_value_map_is_empty(const struct bt_value *map_obj) +{ + return bt_value_map_get_size(map_obj) == 0; +} + +extern const struct bt_value *bt_value_map_borrow_entry_value_const( + const struct bt_value *map_obj, const char *key); + +typedef bt_bool (* bt_value_map_foreach_entry_const_func)(const char *key, + const struct bt_value *object, void *data); + +extern enum bt_value_status bt_value_map_foreach_entry_const( + const struct bt_value *map_obj, + bt_value_map_foreach_entry_const_func func, void *data); + +extern bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, + const char *key); + +extern enum bt_value_status bt_value_map_extend( + const struct bt_value *base_map_obj, + const struct bt_value *extension_map_obj, + struct bt_value **extended_map_obj); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_VALUES_CONST_H */ diff --git a/include/babeltrace/value-internal.h b/include/babeltrace/value-internal.h new file mode 100644 index 00000000..81b2845f --- /dev/null +++ b/include/babeltrace/value-internal.h @@ -0,0 +1,39 @@ +#ifndef BABELTRACE_VALUES_INTERNAL_H +#define BABELTRACE_VALUES_INTERNAL_H + +/* + * Copyright (c) 2015-2017 EfficiOS Inc. and Linux Foundation + * Copyright (c) 2015-2017 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +BT_HIDDEN +enum bt_value_status _bt_value_freeze(const struct bt_value *object); + +#ifdef BT_DEV_MODE +# define bt_value_freeze _bt_value_freeze +#else +# define bt_value_freeze(_value) +#endif /* BT_DEV_MODE */ + +#endif /* BABELTRACE_VALUES_INTERNAL_H */ diff --git a/include/babeltrace/value.h b/include/babeltrace/value.h new file mode 100644 index 00000000..b0a6c077 --- /dev/null +++ b/include/babeltrace/value.h @@ -0,0 +1,140 @@ +#ifndef BABELTRACE_VALUES_H +#define BABELTRACE_VALUES_H + +/* + * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation + * Copyright (c) 2015-2018 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include + +/* For bt_bool */ +#include + +/* For enum bt_value_status, enum bt_value_type */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct bt_value; + +extern struct bt_value *bt_value_null; + +extern struct bt_value *bt_value_bool_create(void); + +extern struct bt_value *bt_value_bool_create_init(bt_bool val); + +extern void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val); + +extern struct bt_value *bt_value_integer_create(void); + +extern struct bt_value *bt_value_integer_create_init( + int64_t val); + +extern void bt_value_integer_set(struct bt_value *integer_obj, int64_t val); + +extern struct bt_value *bt_value_real_create(void); + +extern struct bt_value *bt_value_real_create_init(double val); + +extern void bt_value_real_set(struct bt_value *real_obj, double val); + +extern struct bt_value *bt_value_string_create(void); + +extern struct bt_value *bt_value_string_create_init(const char *val); + +extern enum bt_value_status bt_value_string_set(struct bt_value *string_obj, + const char *val); + +extern struct bt_value *bt_value_array_create(void); + +extern struct bt_value *bt_value_array_borrow_element_by_index( + struct bt_value *array_obj, uint64_t index); + +extern enum bt_value_status bt_value_array_append_element( + struct bt_value *array_obj, + struct bt_value *element_obj); + +extern enum bt_value_status bt_value_array_append_bool_element( + struct bt_value *array_obj, bt_bool val); + +extern enum bt_value_status bt_value_array_append_integer_element( + struct bt_value *array_obj, int64_t val); + +extern enum bt_value_status bt_value_array_append_real_element( + struct bt_value *array_obj, double val); + +extern enum bt_value_status bt_value_array_append_string_element( + struct bt_value *array_obj, const char *val); + +extern enum bt_value_status bt_value_array_append_empty_array_element( + struct bt_value *array_obj); + +extern enum bt_value_status bt_value_array_append_empty_map_element( + struct bt_value *array_obj); + +extern enum bt_value_status bt_value_array_set_element_by_index( + struct bt_value *array_obj, uint64_t index, + struct bt_value *element_obj); + +extern struct bt_value *bt_value_map_create(void); + +extern struct bt_value *bt_value_map_borrow_entry_value( + struct bt_value *map_obj, const char *key); + +typedef bt_bool (* bt_value_map_foreach_entry_func)(const char *key, + struct bt_value *object, void *data); + +extern enum bt_value_status bt_value_map_foreach_entry( + struct bt_value *map_obj, + bt_value_map_foreach_entry_func func, void *data); + +extern enum bt_value_status bt_value_map_insert_entry( + struct bt_value *map_obj, const char *key, + struct bt_value *element_obj); + +extern enum bt_value_status bt_value_map_insert_bool_entry( + struct bt_value *map_obj, const char *key, bt_bool val); + +extern enum bt_value_status bt_value_map_insert_integer_entry( + struct bt_value *map_obj, const char *key, int64_t val); + +extern enum bt_value_status bt_value_map_insert_real_entry( + struct bt_value *map_obj, const char *key, double val); + +extern enum bt_value_status bt_value_map_insert_string_entry( + struct bt_value *map_obj, const char *key, + const char *val); + +extern enum bt_value_status bt_value_map_insert_empty_array_entry( + struct bt_value *map_obj, const char *key); + +extern enum bt_value_status bt_value_map_insert_empty_map_entry( + struct bt_value *map_obj, const char *key); + +#ifdef __cplusplus +} +#endif + +#endif /* BABELTRACE_VALUES_H */ diff --git a/include/babeltrace/values-const.h b/include/babeltrace/values-const.h deleted file mode 100644 index 6816d37d..00000000 --- a/include/babeltrace/values-const.h +++ /dev/null @@ -1,172 +0,0 @@ -#ifndef BABELTRACE_VALUES_CONST_H -#define BABELTRACE_VALUES_CONST_H - -/* - * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation - * Copyright (c) 2015-2016 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include - -/* For bt_bool */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_value; - -enum bt_value_status { - /// Operation canceled. - BT_VALUE_STATUS_CANCELED = 125, - - /// Cannot allocate memory. - BT_VALUE_STATUS_NOMEM = -12, - - /// Okay, no error. - BT_VALUE_STATUS_OK = 0, -}; - -enum bt_value_type { - /// Null value object. - BT_VALUE_TYPE_NULL = 0, - - /// Boolean value object (holds #BT_TRUE or #BT_FALSE). - BT_VALUE_TYPE_BOOL = 1, - - /// Integer value object (holds a signed 64-bit integer raw value). - BT_VALUE_TYPE_INTEGER = 2, - - /// Floating point number value object (holds a \c double raw value). - BT_VALUE_TYPE_REAL = 3, - - /// String value object. - BT_VALUE_TYPE_STRING = 4, - - /// Array value object. - BT_VALUE_TYPE_ARRAY = 5, - - /// Map value object. - BT_VALUE_TYPE_MAP = 6, -}; - -extern enum bt_value_type bt_value_get_type(const struct bt_value *object); - -static inline -bt_bool bt_value_is_null(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_NULL; -} - -static inline -bt_bool bt_value_is_bool(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_BOOL; -} - -static inline -bt_bool bt_value_is_integer(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_INTEGER; -} - -static inline -bt_bool bt_value_is_real(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_REAL; -} - -static inline -bt_bool bt_value_is_string(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_STRING; -} - -static inline -bt_bool bt_value_is_array(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_ARRAY; -} - -static inline -bt_bool bt_value_is_map(const struct bt_value *object) -{ - return bt_value_get_type(object) == BT_VALUE_TYPE_MAP; -} - -extern enum bt_value_status bt_value_copy(const struct bt_value *object, - struct bt_value **copy); - -extern bt_bool bt_value_compare(const struct bt_value *object_a, - const struct bt_value *object_b); - -extern bt_bool bt_value_bool_get(const struct bt_value *bool_obj); - -extern int64_t bt_value_integer_get(const struct bt_value *integer_obj); - -extern double bt_value_real_get(const struct bt_value *real_obj); - -extern const char *bt_value_string_get(const struct bt_value *string_obj); - -extern uint64_t bt_value_array_get_size(const struct bt_value *array_obj); - -static inline -bt_bool bt_value_array_is_empty(const struct bt_value *array_obj) -{ - return bt_value_array_get_size(array_obj) == 0; -} - -extern const struct bt_value *bt_value_array_borrow_element_by_index_const( - const struct bt_value *array_obj, uint64_t index); - -extern uint64_t bt_value_map_get_size(const struct bt_value *map_obj); - -static inline -bt_bool bt_value_map_is_empty(const struct bt_value *map_obj) -{ - return bt_value_map_get_size(map_obj) == 0; -} - -extern const struct bt_value *bt_value_map_borrow_entry_value_const( - const struct bt_value *map_obj, const char *key); - -typedef bt_bool (* bt_value_map_foreach_entry_const_func)(const char *key, - const struct bt_value *object, void *data); - -extern enum bt_value_status bt_value_map_foreach_entry_const( - const struct bt_value *map_obj, - bt_value_map_foreach_entry_const_func func, void *data); - -extern bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, - const char *key); - -extern enum bt_value_status bt_value_map_extend( - const struct bt_value *base_map_obj, - const struct bt_value *extension_map_obj, - struct bt_value **extended_map_obj); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_VALUES_CONST_H */ diff --git a/include/babeltrace/values-internal.h b/include/babeltrace/values-internal.h deleted file mode 100644 index d505f0e4..00000000 --- a/include/babeltrace/values-internal.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef BABELTRACE_VALUES_INTERNAL_H -#define BABELTRACE_VALUES_INTERNAL_H - -/* - * Copyright (c) 2015-2017 EfficiOS Inc. and Linux Foundation - * Copyright (c) 2015-2017 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include - -BT_HIDDEN -enum bt_value_status _bt_value_freeze(const struct bt_value *object); - -#ifdef BT_DEV_MODE -# define bt_value_freeze _bt_value_freeze -#else -# define bt_value_freeze(_value) -#endif /* BT_DEV_MODE */ - -#endif /* BABELTRACE_VALUES_INTERNAL_H */ diff --git a/include/babeltrace/values.h b/include/babeltrace/values.h deleted file mode 100644 index 85a838e8..00000000 --- a/include/babeltrace/values.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef BABELTRACE_VALUES_H -#define BABELTRACE_VALUES_H - -/* - * Copyright (c) 2015-2016 EfficiOS Inc. and Linux Foundation - * Copyright (c) 2015-2018 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include -#include - -/* For bt_bool */ -#include - -/* For enum bt_value_status, enum bt_value_type */ -#include - -#ifdef __cplusplus -extern "C" { -#endif - -struct bt_value; - -extern struct bt_value *bt_value_null; - -extern struct bt_value *bt_value_bool_create(void); - -extern struct bt_value *bt_value_bool_create_init(bt_bool val); - -extern void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val); - -extern struct bt_value *bt_value_integer_create(void); - -extern struct bt_value *bt_value_integer_create_init( - int64_t val); - -extern void bt_value_integer_set(struct bt_value *integer_obj, int64_t val); - -extern struct bt_value *bt_value_real_create(void); - -extern struct bt_value *bt_value_real_create_init(double val); - -extern void bt_value_real_set(struct bt_value *real_obj, double val); - -extern struct bt_value *bt_value_string_create(void); - -extern struct bt_value *bt_value_string_create_init(const char *val); - -extern enum bt_value_status bt_value_string_set(struct bt_value *string_obj, - const char *val); - -extern struct bt_value *bt_value_array_create(void); - -extern struct bt_value *bt_value_array_borrow_element_by_index( - struct bt_value *array_obj, uint64_t index); - -extern enum bt_value_status bt_value_array_append_element( - struct bt_value *array_obj, - struct bt_value *element_obj); - -extern enum bt_value_status bt_value_array_append_bool_element( - struct bt_value *array_obj, bt_bool val); - -extern enum bt_value_status bt_value_array_append_integer_element( - struct bt_value *array_obj, int64_t val); - -extern enum bt_value_status bt_value_array_append_real_element( - struct bt_value *array_obj, double val); - -extern enum bt_value_status bt_value_array_append_string_element( - struct bt_value *array_obj, const char *val); - -extern enum bt_value_status bt_value_array_append_empty_array_element( - struct bt_value *array_obj); - -extern enum bt_value_status bt_value_array_append_empty_map_element( - struct bt_value *array_obj); - -extern enum bt_value_status bt_value_array_set_element_by_index( - struct bt_value *array_obj, uint64_t index, - struct bt_value *element_obj); - -extern struct bt_value *bt_value_map_create(void); - -extern struct bt_value *bt_value_map_borrow_entry_value( - struct bt_value *map_obj, const char *key); - -typedef bt_bool (* bt_value_map_foreach_entry_func)(const char *key, - struct bt_value *object, void *data); - -extern enum bt_value_status bt_value_map_foreach_entry( - struct bt_value *map_obj, - bt_value_map_foreach_entry_func func, void *data); - -extern enum bt_value_status bt_value_map_insert_entry( - struct bt_value *map_obj, const char *key, - struct bt_value *element_obj); - -extern enum bt_value_status bt_value_map_insert_bool_entry( - struct bt_value *map_obj, const char *key, bt_bool val); - -extern enum bt_value_status bt_value_map_insert_integer_entry( - struct bt_value *map_obj, const char *key, int64_t val); - -extern enum bt_value_status bt_value_map_insert_real_entry( - struct bt_value *map_obj, const char *key, double val); - -extern enum bt_value_status bt_value_map_insert_string_entry( - struct bt_value *map_obj, const char *key, - const char *val); - -extern enum bt_value_status bt_value_map_insert_empty_array_entry( - struct bt_value *map_obj, const char *key); - -extern enum bt_value_status bt_value_map_insert_empty_map_entry( - struct bt_value *map_obj, const char *key); - -#ifdef __cplusplus -} -#endif - -#endif /* BABELTRACE_VALUES_H */ diff --git a/lib/Makefile.am b/lib/Makefile.am index ab1aa771..01187650 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -4,7 +4,7 @@ lib_LTLIBRARIES = libbabeltrace.la libbabeltrace-ctf.la libbabeltrace_la_SOURCES = \ babeltrace.c \ - values.c \ + value.c \ object.c \ lib-logging.c \ logging.c \ diff --git a/lib/graph/component-filter.c b/lib/graph/component-filter.c index 869c3d77..4c9917df 100644 --- a/lib/graph/component-filter.c +++ b/lib/graph/component-filter.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/graph/component-sink.c b/lib/graph/component-sink.c index 033c8e6e..42814822 100644 --- a/lib/graph/component-sink.c +++ b/lib/graph/component-sink.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/graph/component.c b/lib/graph/component.c index 2d3460a0..81c573b1 100644 --- a/lib/graph/component.c +++ b/lib/graph/component.c @@ -43,8 +43,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/graph/graph.c b/lib/graph/graph.c index db88e333..4f888b7a 100644 --- a/lib/graph/graph.c +++ b/lib/graph/graph.c @@ -39,9 +39,9 @@ #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/lib/graph/iterator.c b/lib/graph/iterator.c index 54ce07dc..64d8cfa3 100644 --- a/lib/graph/iterator.c +++ b/lib/graph/iterator.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/graph/query-executor.c b/lib/graph/query-executor.c index a24b093d..d7216529 100644 --- a/lib/graph/query-executor.c +++ b/lib/graph/query-executor.c @@ -28,8 +28,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/lib-logging.c b/lib/lib-logging.c index d58996b0..46ac3a54 100644 --- a/lib/lib-logging.c +++ b/lib/lib-logging.c @@ -32,11 +32,11 @@ #include #include #include -#include -#include +#include +#include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/trace-ir/Makefile.am b/lib/trace-ir/Makefile.am index 5ddcb37a..f51103b1 100644 --- a/lib/trace-ir/Makefile.am +++ b/lib/trace-ir/Makefile.am @@ -8,8 +8,8 @@ libtrace_ir_la_SOURCES = \ event-class.c \ event-header-field.c \ field-wrapper.c \ - fields.c \ - field-classes.c \ + field.c \ + field-class.c \ field-path.c \ packet.c \ packet-context-field.c \ diff --git a/lib/trace-ir/attributes.c b/lib/trace-ir/attributes.c index c158c7dc..af8a4936 100644 --- a/lib/trace-ir/attributes.c +++ b/lib/trace-ir/attributes.c @@ -26,9 +26,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/lib/trace-ir/event-class.c b/lib/trace-ir/event-class.c index 76a35e8d..cf4cbf88 100644 --- a/lib/trace-ir/event-class.c +++ b/lib/trace-ir/event-class.c @@ -27,9 +27,9 @@ #include #include -#include -#include -#include +#include +#include +#include #include #include #include @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/trace-ir/event-header-field.c b/lib/trace-ir/event-header-field.c index 22d8a692..da7e8c94 100644 --- a/lib/trace-ir/event-header-field.c +++ b/lib/trace-ir/event-header-field.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/lib/trace-ir/event.c b/lib/trace-ir/event.c index 47ff78bf..2ac29609 100644 --- a/lib/trace-ir/event.c +++ b/lib/trace-ir/event.c @@ -26,8 +26,8 @@ #include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/trace-ir/field-class.c b/lib/trace-ir/field-class.c new file mode 100644 index 00000000..6515804f --- /dev/null +++ b/lib/trace-ir/field-class.c @@ -0,0 +1,1199 @@ +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BT_LOG_TAG "FIELD-CLASSES" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum bt_field_class_type bt_field_class_get_type( + const struct bt_field_class *fc) +{ + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + return fc->type; +} + +static +void init_field_class(struct bt_field_class *fc, enum bt_field_class_type type, + bt_object_release_func release_func) +{ + BT_ASSERT(fc); + BT_ASSERT(bt_field_class_has_known_type(fc)); + BT_ASSERT(release_func); + bt_object_init_shared(&fc->base, release_func); + fc->type = type; +} + +static +void init_integer_field_class(struct bt_field_class_integer *fc, + enum bt_field_class_type type, + bt_object_release_func release_func) +{ + init_field_class((void *) fc, type, release_func); + fc->range = 64; + fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; +} + +static +void destroy_integer_field_class(struct bt_object *obj) +{ + BT_ASSERT(obj); + BT_LIB_LOGD("Destroying integer field class object: %!+F", obj); + g_free(obj); +} + +static inline +struct bt_field_class *create_integer_field_class(enum bt_field_class_type type) +{ + struct bt_field_class_integer *int_fc = NULL; + + BT_LOGD("Creating default integer field class object: type=%s", + bt_common_field_class_type_string(type)); + int_fc = g_new0(struct bt_field_class_integer, 1); + if (!int_fc) { + BT_LOGE_STR("Failed to allocate one integer field class."); + goto error; + } + + init_integer_field_class(int_fc, type, destroy_integer_field_class); + BT_LIB_LOGD("Created integer field class object: %!+F", int_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(int_fc); + +end: + return (void *) int_fc; +} + +struct bt_field_class * +bt_field_class_unsigned_integer_create(void) +{ + return create_integer_field_class( + BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER); +} + +struct bt_field_class *bt_field_class_signed_integer_create(void) +{ + return create_integer_field_class( + BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); +} + +uint64_t bt_field_class_integer_get_field_value_range( + const struct bt_field_class *fc) +{ + const struct bt_field_class_integer *int_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); + return int_fc->range; +} + +BT_ASSERT_PRE_FUNC +static +bool size_is_valid_for_enumeration_field_class(struct bt_field_class *fc, + uint64_t size) +{ + // TODO + return true; +} + +void bt_field_class_integer_set_field_value_range( + struct bt_field_class *fc, uint64_t size) +{ + struct bt_field_class_integer *int_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); + BT_ASSERT_PRE_FC_HOT(fc, "Field class"); + BT_ASSERT_PRE(size <= 64, + "Unsupported size for integer field class's field value range " + "(maximum is 64): size=%" PRIu64, size); + BT_ASSERT_PRE( + int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || + int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || + size_is_valid_for_enumeration_field_class(fc, size), + "Invalid field value range for enumeration field class: " + "at least one of the current mapping ranges contains values " + "which are outside this range: %!+F, size=%" PRIu64, fc, size); + int_fc->range = size; + BT_LIB_LOGV("Set integer field class's field value range: %!+F", fc); +} + +enum bt_field_class_integer_preferred_display_base +bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc) +{ + const struct bt_field_class_integer *int_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); + return int_fc->base; +} + +void bt_field_class_integer_set_preferred_display_base( + struct bt_field_class *fc, + enum bt_field_class_integer_preferred_display_base base) +{ + struct bt_field_class_integer *int_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); + BT_ASSERT_PRE_FC_HOT(fc, "Field class"); + int_fc->base = base; + BT_LIB_LOGV("Set integer field class's preferred display base: %!+F", fc); +} + +static +void finalize_enumeration_field_class_mapping( + struct bt_field_class_enumeration_mapping *mapping) +{ + BT_ASSERT(mapping); + + if (mapping->label) { + g_string_free(mapping->label, TRUE); + } + + if (mapping->ranges) { + g_array_free(mapping->ranges, TRUE); + } +} + +static +void destroy_enumeration_field_class(struct bt_object *obj) +{ + struct bt_field_class_enumeration *fc = (void *) obj; + + BT_ASSERT(fc); + BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc); + + if (fc->mappings) { + uint64_t i; + + for (i = 0; i < fc->mappings->len; i++) { + finalize_enumeration_field_class_mapping( + BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i)); + } + + g_array_free(fc->mappings, TRUE); + fc->mappings = NULL; + } + + if (fc->label_buf) { + g_ptr_array_free(fc->label_buf, TRUE); + fc->label_buf = NULL; + } + + g_free(fc); +} + +static +struct bt_field_class *create_enumeration_field_class( + enum bt_field_class_type type) +{ + struct bt_field_class_enumeration *enum_fc = NULL; + + BT_LOGD("Creating default enumeration field class object: type=%s", + bt_common_field_class_type_string(type)); + enum_fc = g_new0(struct bt_field_class_enumeration, 1); + if (!enum_fc) { + BT_LOGE_STR("Failed to allocate one enumeration field class."); + goto error; + } + + init_integer_field_class((void *) enum_fc, type, + destroy_enumeration_field_class); + enum_fc->mappings = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_class_enumeration_mapping)); + if (!enum_fc->mappings) { + BT_LOGE_STR("Failed to allocate a GArray."); + goto error; + } + + enum_fc->label_buf = g_ptr_array_new(); + if (!enum_fc->label_buf) { + BT_LOGE_STR("Failed to allocate a GArray."); + goto error; + } + + BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(enum_fc); + +end: + return (void *) enum_fc; +} + +struct bt_field_class *bt_field_class_unsigned_enumeration_create(void) +{ + return create_enumeration_field_class( + BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION); +} + +struct bt_field_class *bt_field_class_signed_enumeration_create(void) +{ + return create_enumeration_field_class( + BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION); +} + +uint64_t bt_field_class_enumeration_get_mapping_count( + const struct bt_field_class *fc) +{ + const struct bt_field_class_enumeration *enum_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_ENUM(fc, "Field class"); + return (uint64_t) enum_fc->mappings->len; +} + +void bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const( + const struct bt_field_class *fc, uint64_t index, + const char **name, + const struct bt_field_class_unsigned_enumeration_mapping_ranges **ranges) +{ + const struct bt_field_class_enumeration *enum_fc = (const void *) fc; + const struct bt_field_class_enumeration_mapping *mapping; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_NON_NULL(name, "Name (output)"); + BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)"); + BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, + "Field class"); + mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index); + *name = mapping->label->str; + *ranges = (void *) mapping; +} + +void bt_field_class_signed_enumeration_borrow_mapping_by_index_const( + const struct bt_field_class *fc, uint64_t index, + const char **name, + const struct bt_field_class_signed_enumeration_mapping_ranges **ranges) +{ + const struct bt_field_class_enumeration *enum_fc = (const void *) fc; + const struct bt_field_class_enumeration_mapping *mapping; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_NON_NULL(name, "Name (output)"); + BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)"); + BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, + "Field class"); + mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index); + *name = mapping->label->str; + *ranges = (void *) mapping; +} + +static inline +uint64_t get_enumeration_field_class_mapping_range_count( + const struct bt_field_class_enumeration_mapping *mapping) +{ + BT_ASSERT_PRE_NON_NULL(mapping, "Ranges"); + return (uint64_t) mapping->ranges->len; +} + +uint64_t bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges) +{ + return get_enumeration_field_class_mapping_range_count( + (const void *) ranges); +} + +uint64_t bt_field_class_signed_enumeration_mapping_ranges_get_range_count( + const struct bt_field_class_signed_enumeration_mapping_ranges *ranges) +{ + return get_enumeration_field_class_mapping_range_count( + (const void *) ranges); +} + +static inline +void get_enumeration_field_class_mapping_range_at_index( + const struct bt_field_class_enumeration_mapping *mapping, + uint64_t index, uint64_t *lower, uint64_t *upper) +{ + const struct bt_field_class_enumeration_mapping_range *range; + + BT_ASSERT_PRE_NON_NULL(mapping, "Ranges"); + BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)"); + BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)"); + BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len); + range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index); + *lower = range->lower.u; + *upper = range->upper.u; +} + +void bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, + uint64_t index, uint64_t *lower, uint64_t *upper) +{ + get_enumeration_field_class_mapping_range_at_index( + (const void *) ranges, index, lower, upper); +} + +void bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index( + const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, + uint64_t index, int64_t *lower, int64_t *upper) +{ + get_enumeration_field_class_mapping_range_at_index( + (const void *) ranges, index, + (uint64_t *) lower, (uint64_t *) upper); +} + + + +int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( + const struct bt_field_class *fc, uint64_t value, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count) +{ + const struct bt_field_class_enumeration *enum_fc = (const void *) fc; + uint64_t i; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); + BT_ASSERT_PRE_NON_NULL(count, "Count (output)"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, + "Field class"); + g_ptr_array_set_size(enum_fc->label_buf, 0); + + for (i = 0; i < enum_fc->mappings->len; i++) { + uint64_t j; + const struct bt_field_class_enumeration_mapping *mapping = + BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); + + for (j = 0; j < mapping->ranges->len; j++) { + const struct bt_field_class_enumeration_mapping_range *range = + BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX( + mapping, j); + + if (value >= range->lower.u && + value <= range->upper.u) { + g_ptr_array_add(enum_fc->label_buf, + mapping->label->str); + break; + } + } + } + + *label_array = (void *) enum_fc->label_buf->pdata; + *count = (uint64_t) enum_fc->label_buf->len; + return 0; +} + +int bt_field_class_signed_enumeration_get_mapping_labels_by_value( + const struct bt_field_class *fc, int64_t value, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count) +{ + const struct bt_field_class_enumeration *enum_fc = (const void *) fc; + uint64_t i; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); + BT_ASSERT_PRE_NON_NULL(count, "Count (output)"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, + "Field class"); + g_ptr_array_set_size(enum_fc->label_buf, 0); + + for (i = 0; i < enum_fc->mappings->len; i++) { + uint64_t j; + const struct bt_field_class_enumeration_mapping *mapping = + BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); + + for (j = 0; j < mapping->ranges->len; j++) { + const struct bt_field_class_enumeration_mapping_range *range = + BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX( + mapping, j); + + if (value >= range->lower.i && + value <= range->upper.i) { + g_ptr_array_add(enum_fc->label_buf, + mapping->label->str); + break; + } + } + } + + *label_array = (void *) enum_fc->label_buf->pdata; + *count = (uint64_t) enum_fc->label_buf->len; + return 0; +} + +static inline +int add_mapping_to_enumeration_field_class(struct bt_field_class *fc, + const char *label, uint64_t lower, uint64_t upper) +{ + int ret = 0; + uint64_t i; + struct bt_field_class_enumeration *enum_fc = (void *) fc; + struct bt_field_class_enumeration_mapping *mapping = NULL; + struct bt_field_class_enumeration_mapping_range *range; + + BT_ASSERT(fc); + BT_ASSERT_PRE_NON_NULL(label, "Label"); + + /* Find existing mapping identified by this label */ + for (i = 0; i < enum_fc->mappings->len; i++) { + struct bt_field_class_enumeration_mapping *mapping_candidate = + BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); + + if (strcmp(mapping_candidate->label->str, label) == 0) { + mapping = mapping_candidate; + break; + } + } + + if (!mapping) { + /* Create new mapping for this label */ + g_array_set_size(enum_fc->mappings, enum_fc->mappings->len + 1); + mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, + enum_fc->mappings->len - 1); + mapping->ranges = g_array_new(FALSE, TRUE, + sizeof(struct bt_field_class_enumeration_mapping_range)); + if (!mapping->ranges) { + finalize_enumeration_field_class_mapping(mapping); + g_array_set_size(enum_fc->mappings, + enum_fc->mappings->len - 1); + ret = -1; + goto end; + } + + mapping->label = g_string_new(label); + if (!mapping->label) { + finalize_enumeration_field_class_mapping(mapping); + g_array_set_size(enum_fc->mappings, + enum_fc->mappings->len - 1); + ret = -1; + goto end; + } + } + + /* Add range */ + BT_ASSERT(mapping); + g_array_set_size(mapping->ranges, mapping->ranges->len + 1); + range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, + mapping->ranges->len - 1); + range->lower.u = lower; + range->upper.u = upper; + BT_LIB_LOGV("Added mapping to enumeration field class: " + "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", " + "upper-unsigned=%" PRIu64, fc, label, lower, upper); + +end: + return ret; +} + +int bt_field_class_unsigned_enumeration_map_range( + struct bt_field_class *fc, const char *label, + uint64_t range_lower, uint64_t range_upper) +{ + struct bt_field_class_enumeration *enum_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, + "Field class"); + BT_ASSERT_PRE(range_lower <= range_upper, + "Range's upper bound is less than lower bound: " + "upper=%" PRIu64 ", lower=%" PRIu64, + range_lower, range_upper); + BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range, + range_lower), + "Range's lower bound is outside the enumeration field class's value range: " + "%![fc-]+F, lower=%" PRIu64, fc, range_lower); + BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range, + range_upper), + "Range's upper bound is outside the enumeration field class's value range: " + "%![fc-]+F, upper=%" PRIu64, fc, range_upper); + return add_mapping_to_enumeration_field_class(fc, label, range_lower, + range_upper); +} + +int bt_field_class_signed_enumeration_map_range( + struct bt_field_class *fc, const char *label, + int64_t range_lower, int64_t range_upper) +{ + struct bt_field_class_enumeration *enum_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, + "Field class"); + BT_ASSERT_PRE(range_lower <= range_upper, + "Range's upper bound is less than lower bound: " + "upper=%" PRId64 ", lower=%" PRId64, + range_lower, range_upper); + BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range, + range_lower), + "Range's lower bound is outside the enumeration field class's value range: " + "%![fc-]+F, lower=%" PRId64, fc, range_lower); + BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range, + range_upper), + "Range's upper bound is outside the enumeration field class's value range: " + "%![fc-]+F, upper=%" PRId64, fc, range_upper); + return add_mapping_to_enumeration_field_class(fc, label, range_lower, + range_upper); +} + +static +void destroy_real_field_class(struct bt_object *obj) +{ + BT_ASSERT(obj); + BT_LIB_LOGD("Destroying real field class object: %!+F", obj); + g_free(obj); +} + +struct bt_field_class *bt_field_class_real_create(void) +{ + struct bt_field_class_real *real_fc = NULL; + + BT_LOGD_STR("Creating default real field class object."); + real_fc = g_new0(struct bt_field_class_real, 1); + if (!real_fc) { + BT_LOGE_STR("Failed to allocate one real field class."); + goto error; + } + + init_field_class((void *) real_fc, BT_FIELD_CLASS_TYPE_REAL, + destroy_real_field_class); + BT_LIB_LOGD("Created real field class object: %!+F", real_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(real_fc); + +end: + return (void *) real_fc; +} + +bt_bool bt_field_class_real_is_single_precision(const struct bt_field_class *fc) +{ + const struct bt_field_class_real *real_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class"); + return real_fc->is_single_precision; +} + +void bt_field_class_real_set_is_single_precision(struct bt_field_class *fc, + bt_bool is_single_precision) +{ + struct bt_field_class_real *real_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class"); + BT_ASSERT_PRE_FC_HOT(fc, "Field class"); + real_fc->is_single_precision = (bool) is_single_precision; + BT_LIB_LOGV("Set real field class's \"is single precision\" property: " + "%!+F", fc); +} + +static +int init_named_field_classes_container( + struct bt_field_class_named_field_class_container *fc, + enum bt_field_class_type type, + bt_object_release_func release_func) +{ + int ret = 0; + + init_field_class((void *) fc, type, release_func); + fc->named_fcs = g_array_new(FALSE, TRUE, + sizeof(struct bt_named_field_class)); + if (!fc->named_fcs) { + BT_LOGE_STR("Failed to allocate a GArray."); + ret = -1; + goto end; + } + + fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal); + if (!fc->name_to_index) { + BT_LOGE_STR("Failed to allocate a GHashTable."); + ret = -1; + goto end; + } + +end: + return ret; +} + +static +void finalize_named_field_class(struct bt_named_field_class *named_fc) +{ + BT_ASSERT(named_fc); + BT_LIB_LOGD("Finalizing named field class: " + "addr=%p, name=\"%s\", %![fc-]+F", + named_fc, named_fc->name ? named_fc->name->str : NULL, + named_fc->fc); + + if (named_fc->name) { + g_string_free(named_fc->name, TRUE); + } + + BT_LOGD_STR("Putting named field class's field class."); + BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc); +} + +static +void finalize_named_field_classes_container( + struct bt_field_class_named_field_class_container *fc) +{ + uint64_t i; + + BT_ASSERT(fc); + + if (fc->named_fcs) { + for (i = 0; i < fc->named_fcs->len; i++) { + finalize_named_field_class( + &g_array_index(fc->named_fcs, + struct bt_named_field_class, i)); + } + + g_array_free(fc->named_fcs, TRUE); + } + + if (fc->name_to_index) { + g_hash_table_destroy(fc->name_to_index); + } +} + +static +void destroy_structure_field_class(struct bt_object *obj) +{ + BT_ASSERT(obj); + BT_LIB_LOGD("Destroying string field class object: %!+F", obj); + finalize_named_field_classes_container((void *) obj); + g_free(obj); +} + +struct bt_field_class *bt_field_class_structure_create(void) +{ + int ret; + struct bt_field_class_structure *struct_fc = NULL; + + BT_LOGD_STR("Creating default structure field class object."); + struct_fc = g_new0(struct bt_field_class_structure, 1); + if (!struct_fc) { + BT_LOGE_STR("Failed to allocate one structure field class."); + goto error; + } + + ret = init_named_field_classes_container((void *) struct_fc, + BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class); + if (ret) { + goto error; + } + + BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(struct_fc); + +end: + return (void *) struct_fc; +} + +static +int append_named_field_class_to_container_field_class( + struct bt_field_class_named_field_class_container *container_fc, + const char *name, struct bt_field_class *fc) +{ + int ret = 0; + struct bt_named_field_class *named_fc; + GString *name_str; + + BT_ASSERT(container_fc); + BT_ASSERT_PRE_FC_HOT(container_fc, "Field class"); + BT_ASSERT_PRE_NON_NULL(name, "Name"); + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc->name_to_index, + name), + "Duplicate member/option name in structure/variant field class: " + "%![container-fc-]+F, name=\"%s\"", container_fc, name); + name_str = g_string_new(name); + if (!name_str) { + BT_LOGE_STR("Failed to allocate a GString."); + ret = -1; + goto end; + } + + g_array_set_size(container_fc->named_fcs, + container_fc->named_fcs->len + 1); + named_fc = &g_array_index(container_fc->named_fcs, + struct bt_named_field_class, container_fc->named_fcs->len - 1); + named_fc->name = name_str; + named_fc->fc = fc; + bt_object_get_no_null_check(fc); + g_hash_table_insert(container_fc->name_to_index, named_fc->name->str, + GUINT_TO_POINTER(container_fc->named_fcs->len - 1)); + bt_field_class_freeze(fc); + +end: + return ret; +} + +int bt_field_class_structure_append_member(struct bt_field_class *fc, + const char *name, struct bt_field_class *member_fc) +{ + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); + return append_named_field_class_to_container_field_class((void *) fc, + name, member_fc); +} + +uint64_t bt_field_class_structure_get_member_count( + const struct bt_field_class *fc) +{ + struct bt_field_class_structure *struct_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); + return (uint64_t) struct_fc->common.named_fcs->len; +} + +static +void borrow_named_field_class_from_container_field_class_at_index_const( + const struct bt_field_class_named_field_class_container *fc, + uint64_t index, const char **name, + const struct bt_field_class **out_fc) +{ + const struct bt_named_field_class *named_fc; + + BT_ASSERT(fc); + BT_ASSERT_PRE_NON_NULL(name, "Name"); + BT_ASSERT_PRE_NON_NULL(out_fc, "Field class (output)"); + BT_ASSERT_PRE_VALID_INDEX(index, fc->named_fcs->len); + named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, index); + *name = named_fc->name->str; + *out_fc = named_fc->fc; +} + +void bt_field_class_structure_borrow_member_by_index_const( + const struct bt_field_class *fc, uint64_t index, + const char **name, const struct bt_field_class **out_fc) +{ + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); + borrow_named_field_class_from_container_field_class_at_index_const( + (void *) fc, index, name, out_fc); +} + +static +const struct bt_field_class * +borrow_field_class_from_container_field_class_by_name_const( + const struct bt_field_class_named_field_class_container *fc, + const char *name) +{ + const struct bt_field_class *ret_fc = NULL; + const struct bt_named_field_class *named_fc; + gpointer orig_key; + gpointer value; + + BT_ASSERT(fc); + BT_ASSERT_PRE_NON_NULL(name, "Name"); + if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key, + &value)) { + goto end; + } + + named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, + GPOINTER_TO_UINT(value)); + ret_fc = named_fc->fc; + +end: + return ret_fc; +} + +const struct bt_field_class * +bt_field_class_structure_borrow_member_field_class_by_name( + const struct bt_field_class *fc, const char *name) +{ + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); + return borrow_field_class_from_container_field_class_by_name_const( + (void *) fc, name); +} + +static +void destroy_variant_field_class(struct bt_object *obj) +{ + struct bt_field_class_variant *fc = (void *) obj; + + BT_ASSERT(fc); + BT_LIB_LOGD("Destroying variant field class object: %!+F", fc); + finalize_named_field_classes_container((void *) fc); + BT_LOGD_STR("Putting selector field path."); + BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path); + BT_LOGD_STR("Putting selector field class."); + BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc); + g_free(fc); +} + +struct bt_field_class *bt_field_class_variant_create(void) +{ + int ret; + struct bt_field_class_variant *var_fc = NULL; + + BT_LOGD_STR("Creating default variant field class object."); + var_fc = g_new0(struct bt_field_class_variant, 1); + if (!var_fc) { + BT_LOGE_STR("Failed to allocate one variant field class."); + goto error; + } + + ret = init_named_field_classes_container((void *) var_fc, + BT_FIELD_CLASS_TYPE_VARIANT, destroy_variant_field_class); + if (ret) { + goto error; + } + + BT_LIB_LOGD("Created variant field class object: %!+F", var_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(var_fc); + +end: + return (void *) var_fc; +} + +int bt_field_class_variant_set_selector_field_class( + struct bt_field_class *fc, + struct bt_field_class *selector_fc) +{ + struct bt_field_class_variant *var_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Variant field class"); + BT_ASSERT_PRE_NON_NULL(selector_fc, "Selector field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); + BT_ASSERT_PRE_FC_IS_ENUM(selector_fc, "Selector field class"); + BT_ASSERT_PRE_FC_HOT(fc, "Variant field class"); + var_fc->selector_fc = selector_fc; + bt_object_get_no_null_check(selector_fc); + bt_field_class_freeze(selector_fc); + return 0; +} + +int bt_field_class_variant_append_option( + struct bt_field_class *fc, + const char *name, struct bt_field_class *option_fc) +{ + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); + return append_named_field_class_to_container_field_class((void *) fc, + name, option_fc); +} + +const struct bt_field_class * +bt_field_class_variant_borrow_option_field_class_by_name_const( + const struct bt_field_class *fc, const char *name) +{ + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); + return borrow_field_class_from_container_field_class_by_name_const( + (void *) fc, name); +} + +uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc) +{ + const struct bt_field_class_variant *var_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); + return (uint64_t) var_fc->common.named_fcs->len; +} + +void bt_field_class_variant_borrow_option_by_index_const( + const struct bt_field_class *fc, uint64_t index, + const char **name, const struct bt_field_class **out_fc) +{ + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); + borrow_named_field_class_from_container_field_class_at_index_const( + (void *) fc, index, name, out_fc); +} + +const struct bt_field_path * +bt_field_class_variant_borrow_selector_field_path_const( + const struct bt_field_class *fc) +{ + const struct bt_field_class_variant *var_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, + "Field class"); + return var_fc->selector_field_path; +} + +static +void init_array_field_class(struct bt_field_class_array *fc, + enum bt_field_class_type type, bt_object_release_func release_func, + struct bt_field_class *element_fc) +{ + BT_ASSERT(element_fc); + init_field_class((void *) fc, type, release_func); + fc->element_fc = element_fc; + bt_object_get_no_null_check(element_fc); + bt_field_class_freeze(element_fc); +} + +static +void finalize_array_field_class(struct bt_field_class_array *array_fc) +{ + BT_ASSERT(array_fc); + BT_LOGD_STR("Putting element field class."); + BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc); +} + +static +void destroy_static_array_field_class(struct bt_object *obj) +{ + BT_ASSERT(obj); + BT_LIB_LOGD("Destroying static array field class object: %!+F", obj); + finalize_array_field_class((void *) obj); + g_free(obj); +} + +struct bt_field_class * +bt_field_class_static_array_create(struct bt_field_class *element_fc, + uint64_t length) +{ + struct bt_field_class_static_array *array_fc = NULL; + + BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class"); + BT_LOGD_STR("Creating default static array field class object."); + array_fc = g_new0(struct bt_field_class_static_array, 1); + if (!array_fc) { + BT_LOGE_STR("Failed to allocate one static array field class."); + goto error; + } + + init_array_field_class((void *) array_fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY, + destroy_static_array_field_class, element_fc); + array_fc->length = length; + BT_LIB_LOGD("Created static array field class object: %!+F", array_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(array_fc); + +end: + return (void *) array_fc; +} + +const struct bt_field_class * +bt_field_class_array_borrow_element_field_class_const( + const struct bt_field_class *fc) +{ + const struct bt_field_class_array *array_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_IS_ARRAY(fc, "Field class"); + return array_fc->element_fc; +} + +uint64_t bt_field_class_static_array_get_length(const struct bt_field_class *fc) +{ + const struct bt_field_class_static_array *array_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY, + "Field class"); + return (uint64_t) array_fc->length; +} + +static +void destroy_dynamic_array_field_class(struct bt_object *obj) +{ + struct bt_field_class_dynamic_array *fc = (void *) obj; + + BT_ASSERT(fc); + BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc); + finalize_array_field_class((void *) fc); + BT_LOGD_STR("Putting length field path."); + BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path); + BT_LOGD_STR("Putting length field class."); + BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc); + g_free(fc); +} + +struct bt_field_class *bt_field_class_dynamic_array_create( + struct bt_field_class *element_fc) +{ + struct bt_field_class_dynamic_array *array_fc = NULL; + + BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class"); + BT_LOGD_STR("Creating default dynamic array field class object."); + array_fc = g_new0(struct bt_field_class_dynamic_array, 1); + if (!array_fc) { + BT_LOGE_STR("Failed to allocate one dynamic array field class."); + goto error; + } + + init_array_field_class((void *) array_fc, + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, + destroy_dynamic_array_field_class, element_fc); + BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(array_fc); + +end: + return (void *) array_fc; +} + +int bt_field_class_dynamic_array_set_length_field_class( + struct bt_field_class *fc, + struct bt_field_class *length_fc) +{ + struct bt_field_class_dynamic_array *array_fc = (void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Dynamic array field class"); + BT_ASSERT_PRE_NON_NULL(length_fc, "Length field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, + "Field class"); + BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc, "Length field class"); + BT_ASSERT_PRE_FC_HOT(fc, "Dynamic array field class"); + array_fc->length_fc = length_fc; + bt_object_get_no_null_check(length_fc); + bt_field_class_freeze(length_fc); + return 0; +} + +const struct bt_field_path * +bt_field_class_dynamic_array_borrow_length_field_path_const( + const struct bt_field_class *fc) +{ + const struct bt_field_class_dynamic_array *seq_fc = (const void *) fc; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, + "Field class"); + return seq_fc->length_field_path; +} + +static +void destroy_string_field_class(struct bt_object *obj) +{ + BT_ASSERT(obj); + BT_LIB_LOGD("Destroying string field class object: %!+F", obj); + g_free(obj); +} + +struct bt_field_class *bt_field_class_string_create(void) +{ + struct bt_field_class_string *string_fc = NULL; + + BT_LOGD_STR("Creating default string field class object."); + string_fc = g_new0(struct bt_field_class_string, 1); + if (!string_fc) { + BT_LOGE_STR("Failed to allocate one string field class."); + goto error; + } + + init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING, + destroy_string_field_class); + BT_LIB_LOGD("Created string field class object: %!+F", string_fc); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(string_fc); + +end: + return (void *) string_fc; +} + +BT_HIDDEN +void _bt_field_class_freeze(const struct bt_field_class *fc) +{ + /* + * Element/member/option field classes are frozen when added to + * their owner. + */ + BT_ASSERT(fc); + ((struct bt_field_class *) fc)->frozen = true; +} + +BT_HIDDEN +void _bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc) +{ + struct bt_field_class *fc = (void *) c_fc; + + BT_ASSERT(fc); + BT_ASSERT_PRE(!fc->part_of_trace_class, + "Field class is already part of a trace: %!+F", fc); + fc->part_of_trace_class = true; + + switch (fc->type) { + case BT_FIELD_CLASS_TYPE_STRUCTURE: + case BT_FIELD_CLASS_TYPE_VARIANT: + { + struct bt_field_class_named_field_class_container *container_fc = + (void *) fc; + uint64_t i; + + for (i = 0; i < container_fc->named_fcs->len; i++) { + struct bt_named_field_class *named_fc = + BT_FIELD_CLASS_NAMED_FC_AT_INDEX( + container_fc, i); + + bt_field_class_make_part_of_trace_class(named_fc->fc); + } + + break; + } + case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: + case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: + { + struct bt_field_class_array *array_fc = (void *) fc; + + bt_field_class_make_part_of_trace_class(array_fc->element_fc); + break; + } + default: + break; + } +} diff --git a/lib/trace-ir/field-classes.c b/lib/trace-ir/field-classes.c deleted file mode 100644 index 31f67b1d..00000000 --- a/lib/trace-ir/field-classes.c +++ /dev/null @@ -1,1199 +0,0 @@ -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define BT_LOG_TAG "FIELD-CLASSES" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -enum bt_field_class_type bt_field_class_get_type( - const struct bt_field_class *fc) -{ - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - return fc->type; -} - -static -void init_field_class(struct bt_field_class *fc, enum bt_field_class_type type, - bt_object_release_func release_func) -{ - BT_ASSERT(fc); - BT_ASSERT(bt_field_class_has_known_type(fc)); - BT_ASSERT(release_func); - bt_object_init_shared(&fc->base, release_func); - fc->type = type; -} - -static -void init_integer_field_class(struct bt_field_class_integer *fc, - enum bt_field_class_type type, - bt_object_release_func release_func) -{ - init_field_class((void *) fc, type, release_func); - fc->range = 64; - fc->base = BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_DECIMAL; -} - -static -void destroy_integer_field_class(struct bt_object *obj) -{ - BT_ASSERT(obj); - BT_LIB_LOGD("Destroying integer field class object: %!+F", obj); - g_free(obj); -} - -static inline -struct bt_field_class *create_integer_field_class(enum bt_field_class_type type) -{ - struct bt_field_class_integer *int_fc = NULL; - - BT_LOGD("Creating default integer field class object: type=%s", - bt_common_field_class_type_string(type)); - int_fc = g_new0(struct bt_field_class_integer, 1); - if (!int_fc) { - BT_LOGE_STR("Failed to allocate one integer field class."); - goto error; - } - - init_integer_field_class(int_fc, type, destroy_integer_field_class); - BT_LIB_LOGD("Created integer field class object: %!+F", int_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(int_fc); - -end: - return (void *) int_fc; -} - -struct bt_field_class * -bt_field_class_unsigned_integer_create(void) -{ - return create_integer_field_class( - BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER); -} - -struct bt_field_class *bt_field_class_signed_integer_create(void) -{ - return create_integer_field_class( - BT_FIELD_CLASS_TYPE_SIGNED_INTEGER); -} - -uint64_t bt_field_class_integer_get_field_value_range( - const struct bt_field_class *fc) -{ - const struct bt_field_class_integer *int_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); - return int_fc->range; -} - -BT_ASSERT_PRE_FUNC -static -bool size_is_valid_for_enumeration_field_class(struct bt_field_class *fc, - uint64_t size) -{ - // TODO - return true; -} - -void bt_field_class_integer_set_field_value_range( - struct bt_field_class *fc, uint64_t size) -{ - struct bt_field_class_integer *int_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); - BT_ASSERT_PRE_FC_HOT(fc, "Field class"); - BT_ASSERT_PRE(size <= 64, - "Unsupported size for integer field class's field value range " - "(maximum is 64): size=%" PRIu64, size); - BT_ASSERT_PRE( - int_fc->common.type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER || - int_fc->common.type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER || - size_is_valid_for_enumeration_field_class(fc, size), - "Invalid field value range for enumeration field class: " - "at least one of the current mapping ranges contains values " - "which are outside this range: %!+F, size=%" PRIu64, fc, size); - int_fc->range = size; - BT_LIB_LOGV("Set integer field class's field value range: %!+F", fc); -} - -enum bt_field_class_integer_preferred_display_base -bt_field_class_integer_get_preferred_display_base(const struct bt_field_class *fc) -{ - const struct bt_field_class_integer *int_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); - return int_fc->base; -} - -void bt_field_class_integer_set_preferred_display_base( - struct bt_field_class *fc, - enum bt_field_class_integer_preferred_display_base base) -{ - struct bt_field_class_integer *int_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_INT(fc, "Field class"); - BT_ASSERT_PRE_FC_HOT(fc, "Field class"); - int_fc->base = base; - BT_LIB_LOGV("Set integer field class's preferred display base: %!+F", fc); -} - -static -void finalize_enumeration_field_class_mapping( - struct bt_field_class_enumeration_mapping *mapping) -{ - BT_ASSERT(mapping); - - if (mapping->label) { - g_string_free(mapping->label, TRUE); - } - - if (mapping->ranges) { - g_array_free(mapping->ranges, TRUE); - } -} - -static -void destroy_enumeration_field_class(struct bt_object *obj) -{ - struct bt_field_class_enumeration *fc = (void *) obj; - - BT_ASSERT(fc); - BT_LIB_LOGD("Destroying enumeration field class object: %!+F", fc); - - if (fc->mappings) { - uint64_t i; - - for (i = 0; i < fc->mappings->len; i++) { - finalize_enumeration_field_class_mapping( - BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, i)); - } - - g_array_free(fc->mappings, TRUE); - fc->mappings = NULL; - } - - if (fc->label_buf) { - g_ptr_array_free(fc->label_buf, TRUE); - fc->label_buf = NULL; - } - - g_free(fc); -} - -static -struct bt_field_class *create_enumeration_field_class( - enum bt_field_class_type type) -{ - struct bt_field_class_enumeration *enum_fc = NULL; - - BT_LOGD("Creating default enumeration field class object: type=%s", - bt_common_field_class_type_string(type)); - enum_fc = g_new0(struct bt_field_class_enumeration, 1); - if (!enum_fc) { - BT_LOGE_STR("Failed to allocate one enumeration field class."); - goto error; - } - - init_integer_field_class((void *) enum_fc, type, - destroy_enumeration_field_class); - enum_fc->mappings = g_array_new(FALSE, TRUE, - sizeof(struct bt_field_class_enumeration_mapping)); - if (!enum_fc->mappings) { - BT_LOGE_STR("Failed to allocate a GArray."); - goto error; - } - - enum_fc->label_buf = g_ptr_array_new(); - if (!enum_fc->label_buf) { - BT_LOGE_STR("Failed to allocate a GArray."); - goto error; - } - - BT_LIB_LOGD("Created enumeration field class object: %!+F", enum_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(enum_fc); - -end: - return (void *) enum_fc; -} - -struct bt_field_class *bt_field_class_unsigned_enumeration_create(void) -{ - return create_enumeration_field_class( - BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION); -} - -struct bt_field_class *bt_field_class_signed_enumeration_create(void) -{ - return create_enumeration_field_class( - BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION); -} - -uint64_t bt_field_class_enumeration_get_mapping_count( - const struct bt_field_class *fc) -{ - const struct bt_field_class_enumeration *enum_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_ENUM(fc, "Field class"); - return (uint64_t) enum_fc->mappings->len; -} - -void bt_field_class_unsigned_enumeration_borrow_mapping_by_index_const( - const struct bt_field_class *fc, uint64_t index, - const char **name, - const struct bt_field_class_unsigned_enumeration_mapping_ranges **ranges) -{ - const struct bt_field_class_enumeration *enum_fc = (const void *) fc; - const struct bt_field_class_enumeration_mapping *mapping; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_NON_NULL(name, "Name (output)"); - BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)"); - BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, - "Field class"); - mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index); - *name = mapping->label->str; - *ranges = (void *) mapping; -} - -void bt_field_class_signed_enumeration_borrow_mapping_by_index_const( - const struct bt_field_class *fc, uint64_t index, - const char **name, - const struct bt_field_class_signed_enumeration_mapping_ranges **ranges) -{ - const struct bt_field_class_enumeration *enum_fc = (const void *) fc; - const struct bt_field_class_enumeration_mapping *mapping; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_NON_NULL(name, "Name (output)"); - BT_ASSERT_PRE_NON_NULL(ranges, "Ranges (output)"); - BT_ASSERT_PRE_VALID_INDEX(index, enum_fc->mappings->len); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, - "Field class"); - mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(fc, index); - *name = mapping->label->str; - *ranges = (void *) mapping; -} - -static inline -uint64_t get_enumeration_field_class_mapping_range_count( - const struct bt_field_class_enumeration_mapping *mapping) -{ - BT_ASSERT_PRE_NON_NULL(mapping, "Ranges"); - return (uint64_t) mapping->ranges->len; -} - -uint64_t bt_field_class_unsigned_enumeration_mapping_ranges_get_range_count( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges) -{ - return get_enumeration_field_class_mapping_range_count( - (const void *) ranges); -} - -uint64_t bt_field_class_signed_enumeration_mapping_ranges_get_range_count( - const struct bt_field_class_signed_enumeration_mapping_ranges *ranges) -{ - return get_enumeration_field_class_mapping_range_count( - (const void *) ranges); -} - -static inline -void get_enumeration_field_class_mapping_range_at_index( - const struct bt_field_class_enumeration_mapping *mapping, - uint64_t index, uint64_t *lower, uint64_t *upper) -{ - const struct bt_field_class_enumeration_mapping_range *range; - - BT_ASSERT_PRE_NON_NULL(mapping, "Ranges"); - BT_ASSERT_PRE_NON_NULL(lower, "Range's lower (output)"); - BT_ASSERT_PRE_NON_NULL(upper, "Range's upper (output)"); - BT_ASSERT_PRE_VALID_INDEX(index, mapping->ranges->len); - range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, index); - *lower = range->lower.u; - *upper = range->upper.u; -} - -void bt_field_class_unsigned_enumeration_mapping_ranges_get_range_by_index( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, - uint64_t index, uint64_t *lower, uint64_t *upper) -{ - get_enumeration_field_class_mapping_range_at_index( - (const void *) ranges, index, lower, upper); -} - -void bt_field_class_signed_enumeration_mapping_ranges_get_range_by_index( - const struct bt_field_class_unsigned_enumeration_mapping_ranges *ranges, - uint64_t index, int64_t *lower, int64_t *upper) -{ - get_enumeration_field_class_mapping_range_at_index( - (const void *) ranges, index, - (uint64_t *) lower, (uint64_t *) upper); -} - - - -int bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( - const struct bt_field_class *fc, uint64_t value, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count) -{ - const struct bt_field_class_enumeration *enum_fc = (const void *) fc; - uint64_t i; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); - BT_ASSERT_PRE_NON_NULL(count, "Count (output)"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, - "Field class"); - g_ptr_array_set_size(enum_fc->label_buf, 0); - - for (i = 0; i < enum_fc->mappings->len; i++) { - uint64_t j; - const struct bt_field_class_enumeration_mapping *mapping = - BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); - - for (j = 0; j < mapping->ranges->len; j++) { - const struct bt_field_class_enumeration_mapping_range *range = - BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX( - mapping, j); - - if (value >= range->lower.u && - value <= range->upper.u) { - g_ptr_array_add(enum_fc->label_buf, - mapping->label->str); - break; - } - } - } - - *label_array = (void *) enum_fc->label_buf->pdata; - *count = (uint64_t) enum_fc->label_buf->len; - return 0; -} - -int bt_field_class_signed_enumeration_get_mapping_labels_by_value( - const struct bt_field_class *fc, int64_t value, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count) -{ - const struct bt_field_class_enumeration *enum_fc = (const void *) fc; - uint64_t i; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); - BT_ASSERT_PRE_NON_NULL(count, "Count (output)"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, - "Field class"); - g_ptr_array_set_size(enum_fc->label_buf, 0); - - for (i = 0; i < enum_fc->mappings->len; i++) { - uint64_t j; - const struct bt_field_class_enumeration_mapping *mapping = - BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); - - for (j = 0; j < mapping->ranges->len; j++) { - const struct bt_field_class_enumeration_mapping_range *range = - BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX( - mapping, j); - - if (value >= range->lower.i && - value <= range->upper.i) { - g_ptr_array_add(enum_fc->label_buf, - mapping->label->str); - break; - } - } - } - - *label_array = (void *) enum_fc->label_buf->pdata; - *count = (uint64_t) enum_fc->label_buf->len; - return 0; -} - -static inline -int add_mapping_to_enumeration_field_class(struct bt_field_class *fc, - const char *label, uint64_t lower, uint64_t upper) -{ - int ret = 0; - uint64_t i; - struct bt_field_class_enumeration *enum_fc = (void *) fc; - struct bt_field_class_enumeration_mapping *mapping = NULL; - struct bt_field_class_enumeration_mapping_range *range; - - BT_ASSERT(fc); - BT_ASSERT_PRE_NON_NULL(label, "Label"); - - /* Find existing mapping identified by this label */ - for (i = 0; i < enum_fc->mappings->len; i++) { - struct bt_field_class_enumeration_mapping *mapping_candidate = - BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, i); - - if (strcmp(mapping_candidate->label->str, label) == 0) { - mapping = mapping_candidate; - break; - } - } - - if (!mapping) { - /* Create new mapping for this label */ - g_array_set_size(enum_fc->mappings, enum_fc->mappings->len + 1); - mapping = BT_FIELD_CLASS_ENUM_MAPPING_AT_INDEX(enum_fc, - enum_fc->mappings->len - 1); - mapping->ranges = g_array_new(FALSE, TRUE, - sizeof(struct bt_field_class_enumeration_mapping_range)); - if (!mapping->ranges) { - finalize_enumeration_field_class_mapping(mapping); - g_array_set_size(enum_fc->mappings, - enum_fc->mappings->len - 1); - ret = -1; - goto end; - } - - mapping->label = g_string_new(label); - if (!mapping->label) { - finalize_enumeration_field_class_mapping(mapping); - g_array_set_size(enum_fc->mappings, - enum_fc->mappings->len - 1); - ret = -1; - goto end; - } - } - - /* Add range */ - BT_ASSERT(mapping); - g_array_set_size(mapping->ranges, mapping->ranges->len + 1); - range = BT_FIELD_CLASS_ENUM_MAPPING_RANGE_AT_INDEX(mapping, - mapping->ranges->len - 1); - range->lower.u = lower; - range->upper.u = upper; - BT_LIB_LOGV("Added mapping to enumeration field class: " - "%![fc-]+F, label=\"%s\", lower-unsigned=%" PRIu64 ", " - "upper-unsigned=%" PRIu64, fc, label, lower, upper); - -end: - return ret; -} - -int bt_field_class_unsigned_enumeration_map_range( - struct bt_field_class *fc, const char *label, - uint64_t range_lower, uint64_t range_upper) -{ - struct bt_field_class_enumeration *enum_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, - "Field class"); - BT_ASSERT_PRE(range_lower <= range_upper, - "Range's upper bound is less than lower bound: " - "upper=%" PRIu64 ", lower=%" PRIu64, - range_lower, range_upper); - BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range, - range_lower), - "Range's lower bound is outside the enumeration field class's value range: " - "%![fc-]+F, lower=%" PRIu64, fc, range_lower); - BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned(enum_fc->common.range, - range_upper), - "Range's upper bound is outside the enumeration field class's value range: " - "%![fc-]+F, upper=%" PRIu64, fc, range_upper); - return add_mapping_to_enumeration_field_class(fc, label, range_lower, - range_upper); -} - -int bt_field_class_signed_enumeration_map_range( - struct bt_field_class *fc, const char *label, - int64_t range_lower, int64_t range_upper) -{ - struct bt_field_class_enumeration *enum_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, - "Field class"); - BT_ASSERT_PRE(range_lower <= range_upper, - "Range's upper bound is less than lower bound: " - "upper=%" PRId64 ", lower=%" PRId64, - range_lower, range_upper); - BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range, - range_lower), - "Range's lower bound is outside the enumeration field class's value range: " - "%![fc-]+F, lower=%" PRId64, fc, range_lower); - BT_ASSERT_PRE(bt_util_value_is_in_range_signed(enum_fc->common.range, - range_upper), - "Range's upper bound is outside the enumeration field class's value range: " - "%![fc-]+F, upper=%" PRId64, fc, range_upper); - return add_mapping_to_enumeration_field_class(fc, label, range_lower, - range_upper); -} - -static -void destroy_real_field_class(struct bt_object *obj) -{ - BT_ASSERT(obj); - BT_LIB_LOGD("Destroying real field class object: %!+F", obj); - g_free(obj); -} - -struct bt_field_class *bt_field_class_real_create(void) -{ - struct bt_field_class_real *real_fc = NULL; - - BT_LOGD_STR("Creating default real field class object."); - real_fc = g_new0(struct bt_field_class_real, 1); - if (!real_fc) { - BT_LOGE_STR("Failed to allocate one real field class."); - goto error; - } - - init_field_class((void *) real_fc, BT_FIELD_CLASS_TYPE_REAL, - destroy_real_field_class); - BT_LIB_LOGD("Created real field class object: %!+F", real_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(real_fc); - -end: - return (void *) real_fc; -} - -bt_bool bt_field_class_real_is_single_precision(const struct bt_field_class *fc) -{ - const struct bt_field_class_real *real_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class"); - return real_fc->is_single_precision; -} - -void bt_field_class_real_set_is_single_precision(struct bt_field_class *fc, - bt_bool is_single_precision) -{ - struct bt_field_class_real *real_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_REAL, "Field class"); - BT_ASSERT_PRE_FC_HOT(fc, "Field class"); - real_fc->is_single_precision = (bool) is_single_precision; - BT_LIB_LOGV("Set real field class's \"is single precision\" property: " - "%!+F", fc); -} - -static -int init_named_field_classes_container( - struct bt_field_class_named_field_class_container *fc, - enum bt_field_class_type type, - bt_object_release_func release_func) -{ - int ret = 0; - - init_field_class((void *) fc, type, release_func); - fc->named_fcs = g_array_new(FALSE, TRUE, - sizeof(struct bt_named_field_class)); - if (!fc->named_fcs) { - BT_LOGE_STR("Failed to allocate a GArray."); - ret = -1; - goto end; - } - - fc->name_to_index = g_hash_table_new(g_str_hash, g_str_equal); - if (!fc->name_to_index) { - BT_LOGE_STR("Failed to allocate a GHashTable."); - ret = -1; - goto end; - } - -end: - return ret; -} - -static -void finalize_named_field_class(struct bt_named_field_class *named_fc) -{ - BT_ASSERT(named_fc); - BT_LIB_LOGD("Finalizing named field class: " - "addr=%p, name=\"%s\", %![fc-]+F", - named_fc, named_fc->name ? named_fc->name->str : NULL, - named_fc->fc); - - if (named_fc->name) { - g_string_free(named_fc->name, TRUE); - } - - BT_LOGD_STR("Putting named field class's field class."); - BT_OBJECT_PUT_REF_AND_RESET(named_fc->fc); -} - -static -void finalize_named_field_classes_container( - struct bt_field_class_named_field_class_container *fc) -{ - uint64_t i; - - BT_ASSERT(fc); - - if (fc->named_fcs) { - for (i = 0; i < fc->named_fcs->len; i++) { - finalize_named_field_class( - &g_array_index(fc->named_fcs, - struct bt_named_field_class, i)); - } - - g_array_free(fc->named_fcs, TRUE); - } - - if (fc->name_to_index) { - g_hash_table_destroy(fc->name_to_index); - } -} - -static -void destroy_structure_field_class(struct bt_object *obj) -{ - BT_ASSERT(obj); - BT_LIB_LOGD("Destroying string field class object: %!+F", obj); - finalize_named_field_classes_container((void *) obj); - g_free(obj); -} - -struct bt_field_class *bt_field_class_structure_create(void) -{ - int ret; - struct bt_field_class_structure *struct_fc = NULL; - - BT_LOGD_STR("Creating default structure field class object."); - struct_fc = g_new0(struct bt_field_class_structure, 1); - if (!struct_fc) { - BT_LOGE_STR("Failed to allocate one structure field class."); - goto error; - } - - ret = init_named_field_classes_container((void *) struct_fc, - BT_FIELD_CLASS_TYPE_STRUCTURE, destroy_structure_field_class); - if (ret) { - goto error; - } - - BT_LIB_LOGD("Created structure field class object: %!+F", struct_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(struct_fc); - -end: - return (void *) struct_fc; -} - -static -int append_named_field_class_to_container_field_class( - struct bt_field_class_named_field_class_container *container_fc, - const char *name, struct bt_field_class *fc) -{ - int ret = 0; - struct bt_named_field_class *named_fc; - GString *name_str; - - BT_ASSERT(container_fc); - BT_ASSERT_PRE_FC_HOT(container_fc, "Field class"); - BT_ASSERT_PRE_NON_NULL(name, "Name"); - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE(!bt_g_hash_table_contains(container_fc->name_to_index, - name), - "Duplicate member/option name in structure/variant field class: " - "%![container-fc-]+F, name=\"%s\"", container_fc, name); - name_str = g_string_new(name); - if (!name_str) { - BT_LOGE_STR("Failed to allocate a GString."); - ret = -1; - goto end; - } - - g_array_set_size(container_fc->named_fcs, - container_fc->named_fcs->len + 1); - named_fc = &g_array_index(container_fc->named_fcs, - struct bt_named_field_class, container_fc->named_fcs->len - 1); - named_fc->name = name_str; - named_fc->fc = fc; - bt_object_get_no_null_check(fc); - g_hash_table_insert(container_fc->name_to_index, named_fc->name->str, - GUINT_TO_POINTER(container_fc->named_fcs->len - 1)); - bt_field_class_freeze(fc); - -end: - return ret; -} - -int bt_field_class_structure_append_member(struct bt_field_class *fc, - const char *name, struct bt_field_class *member_fc) -{ - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); - return append_named_field_class_to_container_field_class((void *) fc, - name, member_fc); -} - -uint64_t bt_field_class_structure_get_member_count( - const struct bt_field_class *fc) -{ - struct bt_field_class_structure *struct_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); - return (uint64_t) struct_fc->common.named_fcs->len; -} - -static -void borrow_named_field_class_from_container_field_class_at_index_const( - const struct bt_field_class_named_field_class_container *fc, - uint64_t index, const char **name, - const struct bt_field_class **out_fc) -{ - const struct bt_named_field_class *named_fc; - - BT_ASSERT(fc); - BT_ASSERT_PRE_NON_NULL(name, "Name"); - BT_ASSERT_PRE_NON_NULL(out_fc, "Field class (output)"); - BT_ASSERT_PRE_VALID_INDEX(index, fc->named_fcs->len); - named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, index); - *name = named_fc->name->str; - *out_fc = named_fc->fc; -} - -void bt_field_class_structure_borrow_member_by_index_const( - const struct bt_field_class *fc, uint64_t index, - const char **name, const struct bt_field_class **out_fc) -{ - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); - borrow_named_field_class_from_container_field_class_at_index_const( - (void *) fc, index, name, out_fc); -} - -static -const struct bt_field_class * -borrow_field_class_from_container_field_class_by_name_const( - const struct bt_field_class_named_field_class_container *fc, - const char *name) -{ - const struct bt_field_class *ret_fc = NULL; - const struct bt_named_field_class *named_fc; - gpointer orig_key; - gpointer value; - - BT_ASSERT(fc); - BT_ASSERT_PRE_NON_NULL(name, "Name"); - if (!g_hash_table_lookup_extended(fc->name_to_index, name, &orig_key, - &value)) { - goto end; - } - - named_fc = BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, - GPOINTER_TO_UINT(value)); - ret_fc = named_fc->fc; - -end: - return ret_fc; -} - -const struct bt_field_class * -bt_field_class_structure_borrow_member_field_class_by_name( - const struct bt_field_class *fc, const char *name) -{ - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STRUCTURE, "Field class"); - return borrow_field_class_from_container_field_class_by_name_const( - (void *) fc, name); -} - -static -void destroy_variant_field_class(struct bt_object *obj) -{ - struct bt_field_class_variant *fc = (void *) obj; - - BT_ASSERT(fc); - BT_LIB_LOGD("Destroying variant field class object: %!+F", fc); - finalize_named_field_classes_container((void *) fc); - BT_LOGD_STR("Putting selector field path."); - BT_OBJECT_PUT_REF_AND_RESET(fc->selector_field_path); - BT_LOGD_STR("Putting selector field class."); - BT_OBJECT_PUT_REF_AND_RESET(fc->selector_fc); - g_free(fc); -} - -struct bt_field_class *bt_field_class_variant_create(void) -{ - int ret; - struct bt_field_class_variant *var_fc = NULL; - - BT_LOGD_STR("Creating default variant field class object."); - var_fc = g_new0(struct bt_field_class_variant, 1); - if (!var_fc) { - BT_LOGE_STR("Failed to allocate one variant field class."); - goto error; - } - - ret = init_named_field_classes_container((void *) var_fc, - BT_FIELD_CLASS_TYPE_VARIANT, destroy_variant_field_class); - if (ret) { - goto error; - } - - BT_LIB_LOGD("Created variant field class object: %!+F", var_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(var_fc); - -end: - return (void *) var_fc; -} - -int bt_field_class_variant_set_selector_field_class( - struct bt_field_class *fc, - struct bt_field_class *selector_fc) -{ - struct bt_field_class_variant *var_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Variant field class"); - BT_ASSERT_PRE_NON_NULL(selector_fc, "Selector field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); - BT_ASSERT_PRE_FC_IS_ENUM(selector_fc, "Selector field class"); - BT_ASSERT_PRE_FC_HOT(fc, "Variant field class"); - var_fc->selector_fc = selector_fc; - bt_object_get_no_null_check(selector_fc); - bt_field_class_freeze(selector_fc); - return 0; -} - -int bt_field_class_variant_append_option( - struct bt_field_class *fc, - const char *name, struct bt_field_class *option_fc) -{ - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); - return append_named_field_class_to_container_field_class((void *) fc, - name, option_fc); -} - -const struct bt_field_class * -bt_field_class_variant_borrow_option_field_class_by_name_const( - const struct bt_field_class *fc, const char *name) -{ - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); - return borrow_field_class_from_container_field_class_by_name_const( - (void *) fc, name); -} - -uint64_t bt_field_class_variant_get_option_count(const struct bt_field_class *fc) -{ - const struct bt_field_class_variant *var_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); - return (uint64_t) var_fc->common.named_fcs->len; -} - -void bt_field_class_variant_borrow_option_by_index_const( - const struct bt_field_class *fc, uint64_t index, - const char **name, const struct bt_field_class **out_fc) -{ - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, "Field class"); - borrow_named_field_class_from_container_field_class_at_index_const( - (void *) fc, index, name, out_fc); -} - -const struct bt_field_path * -bt_field_class_variant_borrow_selector_field_path_const( - const struct bt_field_class *fc) -{ - const struct bt_field_class_variant *var_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_VARIANT, - "Field class"); - return var_fc->selector_field_path; -} - -static -void init_array_field_class(struct bt_field_class_array *fc, - enum bt_field_class_type type, bt_object_release_func release_func, - struct bt_field_class *element_fc) -{ - BT_ASSERT(element_fc); - init_field_class((void *) fc, type, release_func); - fc->element_fc = element_fc; - bt_object_get_no_null_check(element_fc); - bt_field_class_freeze(element_fc); -} - -static -void finalize_array_field_class(struct bt_field_class_array *array_fc) -{ - BT_ASSERT(array_fc); - BT_LOGD_STR("Putting element field class."); - BT_OBJECT_PUT_REF_AND_RESET(array_fc->element_fc); -} - -static -void destroy_static_array_field_class(struct bt_object *obj) -{ - BT_ASSERT(obj); - BT_LIB_LOGD("Destroying static array field class object: %!+F", obj); - finalize_array_field_class((void *) obj); - g_free(obj); -} - -struct bt_field_class * -bt_field_class_static_array_create(struct bt_field_class *element_fc, - uint64_t length) -{ - struct bt_field_class_static_array *array_fc = NULL; - - BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class"); - BT_LOGD_STR("Creating default static array field class object."); - array_fc = g_new0(struct bt_field_class_static_array, 1); - if (!array_fc) { - BT_LOGE_STR("Failed to allocate one static array field class."); - goto error; - } - - init_array_field_class((void *) array_fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY, - destroy_static_array_field_class, element_fc); - array_fc->length = length; - BT_LIB_LOGD("Created static array field class object: %!+F", array_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(array_fc); - -end: - return (void *) array_fc; -} - -const struct bt_field_class * -bt_field_class_array_borrow_element_field_class_const( - const struct bt_field_class *fc) -{ - const struct bt_field_class_array *array_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_IS_ARRAY(fc, "Field class"); - return array_fc->element_fc; -} - -uint64_t bt_field_class_static_array_get_length(const struct bt_field_class *fc) -{ - const struct bt_field_class_static_array *array_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_STATIC_ARRAY, - "Field class"); - return (uint64_t) array_fc->length; -} - -static -void destroy_dynamic_array_field_class(struct bt_object *obj) -{ - struct bt_field_class_dynamic_array *fc = (void *) obj; - - BT_ASSERT(fc); - BT_LIB_LOGD("Destroying dynamic array field class object: %!+F", fc); - finalize_array_field_class((void *) fc); - BT_LOGD_STR("Putting length field path."); - BT_OBJECT_PUT_REF_AND_RESET(fc->length_field_path); - BT_LOGD_STR("Putting length field class."); - BT_OBJECT_PUT_REF_AND_RESET(fc->length_fc); - g_free(fc); -} - -struct bt_field_class *bt_field_class_dynamic_array_create( - struct bt_field_class *element_fc) -{ - struct bt_field_class_dynamic_array *array_fc = NULL; - - BT_ASSERT_PRE_NON_NULL(element_fc, "Element field class"); - BT_LOGD_STR("Creating default dynamic array field class object."); - array_fc = g_new0(struct bt_field_class_dynamic_array, 1); - if (!array_fc) { - BT_LOGE_STR("Failed to allocate one dynamic array field class."); - goto error; - } - - init_array_field_class((void *) array_fc, - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, - destroy_dynamic_array_field_class, element_fc); - BT_LIB_LOGD("Created dynamic array field class object: %!+F", array_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(array_fc); - -end: - return (void *) array_fc; -} - -int bt_field_class_dynamic_array_set_length_field_class( - struct bt_field_class *fc, - struct bt_field_class *length_fc) -{ - struct bt_field_class_dynamic_array *array_fc = (void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Dynamic array field class"); - BT_ASSERT_PRE_NON_NULL(length_fc, "Length field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, - "Field class"); - BT_ASSERT_PRE_FC_IS_UNSIGNED_INT(length_fc, "Length field class"); - BT_ASSERT_PRE_FC_HOT(fc, "Dynamic array field class"); - array_fc->length_fc = length_fc; - bt_object_get_no_null_check(length_fc); - bt_field_class_freeze(length_fc); - return 0; -} - -const struct bt_field_path * -bt_field_class_dynamic_array_borrow_length_field_path_const( - const struct bt_field_class *fc) -{ - const struct bt_field_class_dynamic_array *seq_fc = (const void *) fc; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT_PRE_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, - "Field class"); - return seq_fc->length_field_path; -} - -static -void destroy_string_field_class(struct bt_object *obj) -{ - BT_ASSERT(obj); - BT_LIB_LOGD("Destroying string field class object: %!+F", obj); - g_free(obj); -} - -struct bt_field_class *bt_field_class_string_create(void) -{ - struct bt_field_class_string *string_fc = NULL; - - BT_LOGD_STR("Creating default string field class object."); - string_fc = g_new0(struct bt_field_class_string, 1); - if (!string_fc) { - BT_LOGE_STR("Failed to allocate one string field class."); - goto error; - } - - init_field_class((void *) string_fc, BT_FIELD_CLASS_TYPE_STRING, - destroy_string_field_class); - BT_LIB_LOGD("Created string field class object: %!+F", string_fc); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(string_fc); - -end: - return (void *) string_fc; -} - -BT_HIDDEN -void _bt_field_class_freeze(const struct bt_field_class *fc) -{ - /* - * Element/member/option field classes are frozen when added to - * their owner. - */ - BT_ASSERT(fc); - ((struct bt_field_class *) fc)->frozen = true; -} - -BT_HIDDEN -void _bt_field_class_make_part_of_trace_class(const struct bt_field_class *c_fc) -{ - struct bt_field_class *fc = (void *) c_fc; - - BT_ASSERT(fc); - BT_ASSERT_PRE(!fc->part_of_trace_class, - "Field class is already part of a trace: %!+F", fc); - fc->part_of_trace_class = true; - - switch (fc->type) { - case BT_FIELD_CLASS_TYPE_STRUCTURE: - case BT_FIELD_CLASS_TYPE_VARIANT: - { - struct bt_field_class_named_field_class_container *container_fc = - (void *) fc; - uint64_t i; - - for (i = 0; i < container_fc->named_fcs->len; i++) { - struct bt_named_field_class *named_fc = - BT_FIELD_CLASS_NAMED_FC_AT_INDEX( - container_fc, i); - - bt_field_class_make_part_of_trace_class(named_fc->fc); - } - - break; - } - case BT_FIELD_CLASS_TYPE_STATIC_ARRAY: - case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY: - { - struct bt_field_class_array *array_fc = (void *) fc; - - bt_field_class_make_part_of_trace_class(array_fc->element_fc); - break; - } - default: - break; - } -} diff --git a/lib/trace-ir/field-path.c b/lib/trace-ir/field-path.c index 1074e5ca..a767182e 100644 --- a/lib/trace-ir/field-path.c +++ b/lib/trace-ir/field-path.c @@ -25,8 +25,8 @@ #include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/trace-ir/field-wrapper.c b/lib/trace-ir/field-wrapper.c index efff4a1f..6d02b757 100644 --- a/lib/trace-ir/field-wrapper.c +++ b/lib/trace-ir/field-wrapper.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/trace-ir/field.c b/lib/trace-ir/field.c new file mode 100644 index 00000000..e57d867e --- /dev/null +++ b/lib/trace-ir/field.c @@ -0,0 +1,1170 @@ +/* + * Copyright 2013, 2014 Jérémie Galarneau + * + * Author: Jérémie Galarneau + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BT_LOG_TAG "FIELDS" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static +void reset_single_field(struct bt_field *field); + +static +void reset_array_field(struct bt_field *field); + +static +void reset_structure_field(struct bt_field *field); + +static +void reset_variant_field(struct bt_field *field); + +static +void set_single_field_is_frozen(struct bt_field *field, bool is_frozen); + +static +void set_array_field_is_frozen(struct bt_field *field, bool is_frozen); + +static +void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen); + +static +void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen); + +static +bool single_field_is_set(const struct bt_field *field); + +static +bool array_field_is_set(const struct bt_field *field); + +static +bool structure_field_is_set(const struct bt_field *field); + +static +bool variant_field_is_set(const struct bt_field *field); + +static +struct bt_field_methods integer_field_methods = { + .set_is_frozen = set_single_field_is_frozen, + .is_set = single_field_is_set, + .reset = reset_single_field, +}; + +static +struct bt_field_methods real_field_methods = { + .set_is_frozen = set_single_field_is_frozen, + .is_set = single_field_is_set, + .reset = reset_single_field, +}; + +static +struct bt_field_methods string_field_methods = { + .set_is_frozen = set_single_field_is_frozen, + .is_set = single_field_is_set, + .reset = reset_single_field, +}; + +static +struct bt_field_methods structure_field_methods = { + .set_is_frozen = set_structure_field_is_frozen, + .is_set = structure_field_is_set, + .reset = reset_structure_field, +}; + +static +struct bt_field_methods array_field_methods = { + .set_is_frozen = set_array_field_is_frozen, + .is_set = array_field_is_set, + .reset = reset_array_field, +}; + +static +struct bt_field_methods variant_field_methods = { + .set_is_frozen = set_variant_field_is_frozen, + .is_set = variant_field_is_set, + .reset = reset_variant_field, +}; + +static +struct bt_field *create_integer_field(struct bt_field_class *); + +static +struct bt_field *create_real_field(struct bt_field_class *); + +static +struct bt_field *create_string_field(struct bt_field_class *); + +static +struct bt_field *create_structure_field(struct bt_field_class *); + +static +struct bt_field *create_static_array_field(struct bt_field_class *); + +static +struct bt_field *create_dynamic_array_field(struct bt_field_class *); + +static +struct bt_field *create_variant_field(struct bt_field_class *); + +static +struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = { + [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = create_integer_field, + [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = create_integer_field, + [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = create_integer_field, + [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = create_integer_field, + [BT_FIELD_CLASS_TYPE_REAL] = create_real_field, + [BT_FIELD_CLASS_TYPE_STRING] = create_string_field, + [BT_FIELD_CLASS_TYPE_STRUCTURE] = create_structure_field, + [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = create_static_array_field, + [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = create_dynamic_array_field, + [BT_FIELD_CLASS_TYPE_VARIANT] = create_variant_field, +}; + +static +void destroy_integer_field(struct bt_field *field); + +static +void destroy_real_field(struct bt_field *field); + +static +void destroy_string_field(struct bt_field *field); + +static +void destroy_structure_field(struct bt_field *field); + +static +void destroy_array_field(struct bt_field *field); + +static +void destroy_variant_field(struct bt_field *field); + +static +void (* const field_destroy_funcs[])(struct bt_field *) = { + [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = destroy_integer_field, + [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = destroy_integer_field, + [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = destroy_integer_field, + [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = destroy_integer_field, + [BT_FIELD_CLASS_TYPE_REAL] = destroy_real_field, + [BT_FIELD_CLASS_TYPE_STRING] = destroy_string_field, + [BT_FIELD_CLASS_TYPE_STRUCTURE] = destroy_structure_field, + [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = destroy_array_field, + [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = destroy_array_field, + [BT_FIELD_CLASS_TYPE_VARIANT] = destroy_variant_field, +}; + +struct bt_field_class *bt_field_borrow_class(const struct bt_field *field) +{ + BT_ASSERT_PRE_NON_NULL(field, "Field"); + return field->class; +} + +const struct bt_field_class *bt_field_borrow_class_const( + const struct bt_field *field) +{ + BT_ASSERT_PRE_NON_NULL(field, "Field"); + return field->class; +} + +enum bt_field_class_type bt_field_get_class_type(const struct bt_field *field) +{ + BT_ASSERT_PRE_NON_NULL(field, "Field"); + return field->class->type; +} + +BT_HIDDEN +struct bt_field *bt_field_create(struct bt_field_class *fc) +{ + struct bt_field *field = NULL; + + BT_ASSERT_PRE_NON_NULL(fc, "Field class"); + BT_ASSERT(bt_field_class_has_known_type(fc)); + field = field_create_funcs[fc->type](fc); + if (!field) { + BT_LIB_LOGE("Cannot create field object from field class: " + "%![fc-]+F", fc); + goto end; + } + +end: + return field; +} + +static inline +void init_field(struct bt_field *field, struct bt_field_class *fc, + struct bt_field_methods *methods) +{ + BT_ASSERT(field); + BT_ASSERT(fc); + bt_object_init_unique(&field->base); + field->methods = methods; + field->class = fc; + bt_object_get_no_null_check(fc); +} + +static +struct bt_field *create_integer_field(struct bt_field_class *fc) +{ + struct bt_field_integer *int_field; + + BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc); + int_field = g_new0(struct bt_field_integer, 1); + if (!int_field) { + BT_LOGE_STR("Failed to allocate one integer field."); + goto end; + } + + init_field((void *) int_field, fc, &integer_field_methods); + BT_LIB_LOGD("Created integer field object: %!+f", int_field); + +end: + return (void *) int_field; +} + +static +struct bt_field *create_real_field(struct bt_field_class *fc) +{ + struct bt_field_real *real_field; + + BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc); + real_field = g_new0(struct bt_field_real, 1); + if (!real_field) { + BT_LOGE_STR("Failed to allocate one real field."); + goto end; + } + + init_field((void *) real_field, fc, &real_field_methods); + BT_LIB_LOGD("Created real field object: %!+f", real_field); + +end: + return (void *) real_field; +} + +static +struct bt_field *create_string_field(struct bt_field_class *fc) +{ + struct bt_field_string *string_field; + + BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc); + string_field = g_new0(struct bt_field_string, 1); + if (!string_field) { + BT_LOGE_STR("Failed to allocate one string field."); + goto end; + } + + init_field((void *) string_field, fc, &string_field_methods); + string_field->buf = g_array_sized_new(FALSE, FALSE, + sizeof(char), 1); + if (!string_field->buf) { + BT_LOGE_STR("Failed to allocate a GArray."); + BT_OBJECT_PUT_REF_AND_RESET(string_field); + goto end; + } + + g_array_index(string_field->buf, char, 0) = '\0'; + BT_LIB_LOGD("Created string field object: %!+f", string_field); + +end: + return (void *) string_field; +} + +static inline +int create_fields_from_named_field_classes( + struct bt_field_class_named_field_class_container *fc, + GPtrArray **fields) +{ + int ret = 0; + uint64_t i; + + *fields = g_ptr_array_new_with_free_func( + (GDestroyNotify) bt_field_destroy); + if (!*fields) { + BT_LOGE_STR("Failed to allocate a GPtrArray."); + ret = -1; + goto end; + } + + g_ptr_array_set_size(*fields, fc->named_fcs->len); + + for (i = 0; i < fc->named_fcs->len; i++) { + struct bt_field *field; + struct bt_named_field_class *named_fc = + BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, i); + + field = bt_field_create(named_fc->fc); + if (!field) { + BT_LIB_LOGE("Failed to create structure member or variant option field: " + "name=\"%s\", %![fc-]+F", + named_fc->name->str, named_fc->fc); + ret = -1; + goto end; + } + + g_ptr_array_index(*fields, i) = field; + } + +end: + return ret; +} + +static +struct bt_field *create_structure_field(struct bt_field_class *fc) +{ + struct bt_field_structure *struct_field; + + BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc); + struct_field = g_new0(struct bt_field_structure, 1); + if (!struct_field) { + BT_LOGE_STR("Failed to allocate one structure field."); + goto end; + } + + init_field((void *) struct_field, fc, &structure_field_methods); + + if (create_fields_from_named_field_classes((void *) fc, + &struct_field->fields)) { + BT_LIB_LOGE("Cannot create structure member fields: " + "%![fc-]+F", fc); + BT_OBJECT_PUT_REF_AND_RESET(struct_field); + goto end; + } + + BT_LIB_LOGD("Created structure field object: %!+f", struct_field); + +end: + return (void *) struct_field; +} + +static +struct bt_field *create_variant_field(struct bt_field_class *fc) +{ + struct bt_field_variant *var_field; + + BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc); + var_field = g_new0(struct bt_field_variant, 1); + if (!var_field) { + BT_LOGE_STR("Failed to allocate one variant field."); + goto end; + } + + init_field((void *) var_field, fc, &variant_field_methods); + + if (create_fields_from_named_field_classes((void *) fc, + &var_field->fields)) { + BT_LIB_LOGE("Cannot create variant member fields: " + "%![fc-]+F", fc); + BT_OBJECT_PUT_REF_AND_RESET(var_field); + goto end; + } + + BT_LIB_LOGD("Created variant field object: %!+f", var_field); + +end: + return (void *) var_field; +} + +static inline +int init_array_field_fields(struct bt_field_array *array_field) +{ + int ret = 0; + uint64_t i; + struct bt_field_class_array *array_fc; + + BT_ASSERT(array_field); + array_fc = (void *) array_field->common.class; + array_field->fields = g_ptr_array_sized_new(array_field->length); + if (!array_field->fields) { + BT_LOGE_STR("Failed to allocate a GPtrArray."); + ret = -1; + goto end; + } + + g_ptr_array_set_free_func(array_field->fields, + (GDestroyNotify) bt_field_destroy); + g_ptr_array_set_size(array_field->fields, array_field->length); + + for (i = 0; i < array_field->length; i++) { + array_field->fields->pdata[i] = bt_field_create( + array_fc->element_fc); + if (!array_field->fields->pdata[i]) { + BT_LIB_LOGE("Cannot create array field's element field: " + "index=%" PRIu64 ", %![fc-]+F", i, array_fc); + ret = -1; + goto end; + } + } + +end: + return ret; +} + +static +struct bt_field *create_static_array_field(struct bt_field_class *fc) +{ + struct bt_field_class_static_array *array_fc = (void *) fc; + struct bt_field_array *array_field; + + BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc); + array_field = g_new0(struct bt_field_array, 1); + if (!array_field) { + BT_LOGE_STR("Failed to allocate one static array field."); + goto end; + } + + init_field((void *) array_field, fc, &array_field_methods); + array_field->length = array_fc->length; + + if (init_array_field_fields(array_field)) { + BT_LIB_LOGE("Cannot create static array fields: " + "%![fc-]+F", fc); + BT_OBJECT_PUT_REF_AND_RESET(array_field); + goto end; + } + + BT_LIB_LOGD("Created static array field object: %!+f", array_field); + +end: + return (void *) array_field; +} + +static +struct bt_field *create_dynamic_array_field(struct bt_field_class *fc) +{ + struct bt_field_array *array_field; + + BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc); + array_field = g_new0(struct bt_field_array, 1); + if (!array_field) { + BT_LOGE_STR("Failed to allocate one dynamic array field."); + goto end; + } + + init_field((void *) array_field, fc, &array_field_methods); + + if (init_array_field_fields(array_field)) { + BT_LIB_LOGE("Cannot create dynamic array fields: " + "%![fc-]+F", fc); + BT_OBJECT_PUT_REF_AND_RESET(array_field); + goto end; + } + + BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field); + +end: + return (void *) array_field; +} + +int64_t bt_field_signed_integer_get_value(const struct bt_field *field) +{ + const struct bt_field_integer *int_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); + return int_field->value.i; +} + +void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value) +{ + struct bt_field_integer *int_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE(bt_util_value_is_in_range_signed( + ((struct bt_field_class_integer *) field->class)->range, value), + "Value is out of bounds: value=%" PRId64 ", %![field-]+f, " + "%![fc-]+F", value, field, field->class); + int_field->value.i = value; + bt_field_set_single(field, true); +} + +uint64_t bt_field_unsigned_integer_get_value(const struct bt_field *field) +{ + const struct bt_field_integer *int_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); + return int_field->value.u; +} + +void bt_field_unsigned_integer_set_value(struct bt_field *field, uint64_t value) +{ + struct bt_field_integer *int_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned( + ((struct bt_field_class_integer *) field->class)->range, value), + "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, " + "%![fc-]+F", value, field, field->class); + int_field->value.u = value; + bt_field_set_single(field, true); +} + +double bt_field_real_get_value(const struct bt_field *field) +{ + const struct bt_field_real *real_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); + return real_field->value; +} + +void bt_field_real_set_value(struct bt_field *field, double value) +{ + struct bt_field_real *real_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE( + !((struct bt_field_class_real *) field->class)->is_single_precision || + (double) (float) value == value, + "Invalid value for a single-precision real number: value=%f, " + "%![fc-]+F", value, field->class); + real_field->value = value; + bt_field_set_single(field, true); +} + +int bt_field_unsigned_enumeration_get_mapping_labels( + const struct bt_field *field, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count) +{ + const struct bt_field_integer *int_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); + BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field"); + return bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( + field->class, int_field->value.u, label_array, count); +} + +int bt_field_signed_enumeration_get_mapping_labels( + const struct bt_field *field, + bt_field_class_enumeration_mapping_label_array *label_array, + uint64_t *count) +{ + const struct bt_field_integer *int_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); + BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field"); + return bt_field_class_signed_enumeration_get_mapping_labels_by_value( + field->class, int_field->value.i, label_array, count); +} + +const char *bt_field_string_get_value(const struct bt_field *field) +{ + const struct bt_field_string *string_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, + "Field"); + return (const char *) string_field->buf->data; +} + +uint64_t bt_field_string_get_length(const struct bt_field *field) +{ + const struct bt_field_string *string_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, + "Field"); + return string_field->length; +} + +int bt_field_string_set_value(struct bt_field *field, const char *value) +{ + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, + "Field"); + bt_field_string_clear(field); + return bt_field_string_append_with_length(field, value, + (uint64_t) strlen(value)); +} + +int bt_field_string_append(struct bt_field *field, const char *value) +{ + return bt_field_string_append_with_length(field, + value, (uint64_t) strlen(value)); +} + +int bt_field_string_append_with_length(struct bt_field *field, + const char *value, uint64_t length) +{ + struct bt_field_string *string_field = (void *) field; + char *data; + uint64_t new_length; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_NON_NULL(value, "Value"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_STRING, "Field"); + + /* Make sure no null bytes are appended */ + BT_ASSERT_PRE(memchr(value, '\0', length) == NULL, + "String value to append contains a null character: " + "partial-value=\"%.32s\", length=%" PRIu64, value, length); + + new_length = length + string_field->length; + + if (unlikely(new_length + 1 > string_field->buf->len)) { + g_array_set_size(string_field->buf, new_length + 1); + } + + data = string_field->buf->data; + memcpy(data + string_field->length, value, length); + ((char *) string_field->buf->data)[new_length] = '\0'; + string_field->length = new_length; + bt_field_set_single(field, true); + return 0; +} + +int bt_field_string_clear(struct bt_field *field) +{ + struct bt_field_string *string_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_STRING, "Field"); + string_field->length = 0; + bt_field_set_single(field, true); + return 0; +} + +uint64_t bt_field_array_get_length(const struct bt_field *field) +{ + const struct bt_field_array *array_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); + return array_field->length; +} + +int bt_field_dynamic_array_set_length(struct bt_field *field, uint64_t length) +{ + int ret = 0; + struct bt_field_array *array_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + + if (unlikely(length > array_field->fields->len)) { + /* Make more room */ + struct bt_field_class_array *array_fc; + uint64_t cur_len = array_field->fields->len; + uint64_t i; + + g_ptr_array_set_size(array_field->fields, length); + array_fc = (void *) field->class; + + for (i = cur_len; i < array_field->fields->len; i++) { + struct bt_field *elem_field = bt_field_create( + array_fc->element_fc); + + if (!elem_field) { + BT_LIB_LOGE("Cannot create element field for " + "dynamic array field: " + "index=%" PRIu64 ", " + "%![array-field-]+f", i, field); + ret = -1; + goto end; + } + + BT_ASSERT(!array_field->fields->pdata[i]); + array_field->fields->pdata[i] = elem_field; + } + } + + array_field->length = length; + +end: + return ret; +} + +static inline +struct bt_field *borrow_array_field_element_field_by_index( + struct bt_field *field, uint64_t index) +{ + struct bt_field_array *array_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); + BT_ASSERT_PRE_VALID_INDEX(index, array_field->length); + return array_field->fields->pdata[index]; +} + +struct bt_field *bt_field_array_borrow_element_field_by_index( + struct bt_field *field, uint64_t index) +{ + return borrow_array_field_element_field_by_index(field, index); +} + +const struct bt_field * +bt_field_array_borrow_element_field_by_index_const( + const struct bt_field *field, uint64_t index) +{ + return borrow_array_field_element_field_by_index((void *) field, index); +} + +static inline +struct bt_field *borrow_structure_field_member_field_by_index( + struct bt_field *field, uint64_t index) +{ + struct bt_field_structure *struct_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); + BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len); + return struct_field->fields->pdata[index]; +} + +struct bt_field *bt_field_structure_borrow_member_field_by_index( + struct bt_field *field, uint64_t index) +{ + return borrow_structure_field_member_field_by_index(field, + index); +} + +const struct bt_field * +bt_field_structure_borrow_member_field_by_index_const( + const struct bt_field *field, uint64_t index) +{ + return borrow_structure_field_member_field_by_index( + (void *) field, index); +} + +static inline +struct bt_field *borrow_structure_field_member_field_by_name( + struct bt_field *field, const char *name) +{ + struct bt_field *ret_field = NULL; + struct bt_field_class_structure *struct_fc; + struct bt_field_structure *struct_field = (void *) field; + gpointer orig_key; + gpointer index; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_NON_NULL(name, "Field name"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); + struct_fc = (void *) field->class; + + if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name, + &orig_key, &index)) { + goto end; + } + + ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)]; + BT_ASSERT(ret_field); + +end: + return ret_field; +} + +struct bt_field *bt_field_structure_borrow_member_field_by_name( + struct bt_field *field, const char *name) +{ + return borrow_structure_field_member_field_by_name(field, name); +} + +const struct bt_field *bt_field_structure_borrow_member_field_by_name_const( + const struct bt_field *field, const char *name) +{ + return borrow_structure_field_member_field_by_name( + (void *) field, name); +} + +static inline +struct bt_field *borrow_variant_field_selected_option_field( + struct bt_field *field) +{ + struct bt_field_variant *var_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_VARIANT, "Field"); + BT_ASSERT_PRE(var_field->selected_field, + "Variant field has no selected field: %!+f", field); + return var_field->selected_field; +} + +struct bt_field *bt_field_variant_borrow_selected_option_field( + struct bt_field *field) +{ + return borrow_variant_field_selected_option_field(field); +} + +const struct bt_field *bt_field_variant_borrow_selected_option_field_const( + const struct bt_field *field) +{ + return borrow_variant_field_selected_option_field((void *) field); +} + +int bt_field_variant_select_option_field( + struct bt_field *field, uint64_t index) +{ + struct bt_field_variant *var_field = (void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_VARIANT, "Field"); + BT_ASSERT_PRE_FIELD_HOT(field, "Field"); + BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len); + var_field->selected_field = var_field->fields->pdata[index]; + var_field->selected_index = index; + return 0; +} + +uint64_t bt_field_variant_get_selected_option_field_index( + const struct bt_field *field) +{ + const struct bt_field_variant *var_field = (const void *) field; + + BT_ASSERT_PRE_NON_NULL(field, "Field"); + BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, + BT_FIELD_CLASS_TYPE_VARIANT, "Field"); + BT_ASSERT_PRE(var_field->selected_field, + "Variant field has no selected field: %!+f", field); + return var_field->selected_index; +} + +static inline +void bt_field_finalize(struct bt_field *field) +{ + BT_ASSERT(field); + BT_LOGD_STR("Putting field's class."); + BT_OBJECT_PUT_REF_AND_RESET(field->class); +} + +static +void destroy_integer_field(struct bt_field *field) +{ + BT_ASSERT(field); + BT_LIB_LOGD("Destroying integer field object: %!+f", field); + bt_field_finalize(field); + g_free(field); +} + +static +void destroy_real_field(struct bt_field *field) +{ + BT_ASSERT(field); + BT_LIB_LOGD("Destroying real field object: %!+f", field); + bt_field_finalize(field); + g_free(field); +} + +static +void destroy_structure_field(struct bt_field *field) +{ + struct bt_field_structure *struct_field = (void *) field; + + BT_ASSERT(field); + BT_LIB_LOGD("Destroying structure field object: %!+f", field); + bt_field_finalize(field); + + if (struct_field->fields) { + g_ptr_array_free(struct_field->fields, TRUE); + struct_field->fields = NULL; + } + + g_free(field); +} + +static +void destroy_variant_field(struct bt_field *field) +{ + struct bt_field_variant *var_field = (void *) field; + + BT_ASSERT(field); + BT_LIB_LOGD("Destroying variant field object: %!+f", field); + bt_field_finalize(field); + + if (var_field->fields) { + g_ptr_array_free(var_field->fields, TRUE); + var_field->fields = NULL; + } + + g_free(field); +} + +static +void destroy_array_field(struct bt_field *field) +{ + struct bt_field_array *array_field = (void *) field; + + BT_ASSERT(field); + BT_LIB_LOGD("Destroying array field object: %!+f", field); + bt_field_finalize(field); + + if (array_field->fields) { + g_ptr_array_free(array_field->fields, TRUE); + array_field->fields = NULL; + } + + g_free(field); +} + +static +void destroy_string_field(struct bt_field *field) +{ + struct bt_field_string *string_field = (void *) field; + + BT_ASSERT(field); + BT_LIB_LOGD("Destroying string field object: %!+f", field); + bt_field_finalize(field); + + if (string_field->buf) { + g_array_free(string_field->buf, TRUE); + string_field->buf = NULL; + } + + g_free(field); +} + +BT_HIDDEN +void bt_field_destroy(struct bt_field *field) +{ + BT_ASSERT(field); + BT_ASSERT(bt_field_class_has_known_type(field->class)); + field_destroy_funcs[field->class->type](field); +} + +static +void reset_single_field(struct bt_field *field) +{ + BT_ASSERT(field); + field->is_set = false; +} + +static +void reset_structure_field(struct bt_field *field) +{ + uint64_t i; + struct bt_field_structure *struct_field = (void *) field; + + BT_ASSERT(field); + + for (i = 0; i < struct_field->fields->len; i++) { + bt_field_reset(struct_field->fields->pdata[i]); + } +} + +static +void reset_variant_field(struct bt_field *field) +{ + uint64_t i; + struct bt_field_variant *var_field = (void *) field; + + BT_ASSERT(field); + + for (i = 0; i < var_field->fields->len; i++) { + bt_field_reset(var_field->fields->pdata[i]); + } +} + +static +void reset_array_field(struct bt_field *field) +{ + uint64_t i; + struct bt_field_array *array_field = (void *) field; + + BT_ASSERT(field); + + for (i = 0; i < array_field->fields->len; i++) { + bt_field_reset(array_field->fields->pdata[i]); + } +} + +static +void set_single_field_is_frozen(struct bt_field *field, bool is_frozen) +{ + field->frozen = is_frozen; +} + +static +void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen) +{ + uint64_t i; + struct bt_field_structure *struct_field = (void *) field; + + BT_LIB_LOGD("Setting structure field's frozen state: " + "%![field-]+f, is-frozen=%d", field, is_frozen); + + for (i = 0; i < struct_field->fields->len; i++) { + struct bt_field *member_field = struct_field->fields->pdata[i]; + + BT_LIB_LOGD("Setting structure field's member field's " + "frozen state: %![field-]+f, index=%" PRIu64, + member_field, i); + bt_field_set_is_frozen(member_field, is_frozen); + } + + set_single_field_is_frozen(field, is_frozen); +} + +static +void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen) +{ + uint64_t i; + struct bt_field_variant *var_field = (void *) field; + + BT_LIB_LOGD("Setting variant field's frozen state: " + "%![field-]+f, is-frozen=%d", field, is_frozen); + + for (i = 0; i < var_field->fields->len; i++) { + struct bt_field *option_field = var_field->fields->pdata[i]; + + BT_LIB_LOGD("Setting variant field's option field's " + "frozen state: %![field-]+f, index=%" PRIu64, + option_field, i); + bt_field_set_is_frozen(option_field, is_frozen); + } + + set_single_field_is_frozen(field, is_frozen); +} + +static +void set_array_field_is_frozen(struct bt_field *field, bool is_frozen) +{ + uint64_t i; + struct bt_field_array *array_field = (void *) field; + + BT_LIB_LOGD("Setting array field's frozen state: " + "%![field-]+f, is-frozen=%d", field, is_frozen); + + for (i = 0; i < array_field->fields->len; i++) { + struct bt_field *elem_field = array_field->fields->pdata[i]; + + BT_LIB_LOGD("Setting array field's element field's " + "frozen state: %![field-]+f, index=%" PRIu64, + elem_field, i); + bt_field_set_is_frozen(elem_field, is_frozen); + } + + set_single_field_is_frozen(field, is_frozen); +} + +BT_HIDDEN +void _bt_field_set_is_frozen(const struct bt_field *field, + bool is_frozen) +{ + BT_ASSERT(field); + BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d", + field, is_frozen); + BT_ASSERT(field->methods->set_is_frozen); + field->methods->set_is_frozen((void *) field, is_frozen); +} + +static +bool single_field_is_set(const struct bt_field *field) +{ + BT_ASSERT(field); + return field->is_set; +} + +static +bool structure_field_is_set(const struct bt_field *field) +{ + bool is_set = true; + uint64_t i; + const struct bt_field_structure *struct_field = (const void *) field; + + BT_ASSERT(field); + + for (i = 0; i < struct_field->fields->len; i++) { + is_set = bt_field_is_set(struct_field->fields->pdata[i]); + if (!is_set) { + goto end; + } + } + +end: + return is_set; +} + +static +bool variant_field_is_set(const struct bt_field *field) +{ + const struct bt_field_variant *var_field = (const void *) field; + bool is_set = false; + + BT_ASSERT(field); + + if (var_field->selected_field) { + is_set = bt_field_is_set(var_field->selected_field); + } + + return is_set; +} + +static +bool array_field_is_set(const struct bt_field *field) +{ + bool is_set = true; + uint64_t i; + const struct bt_field_array *array_field = (const void *) field; + + BT_ASSERT(field); + + for (i = 0; i < array_field->length; i++) { + is_set = bt_field_is_set(array_field->fields->pdata[i]); + if (!is_set) { + goto end; + } + } + +end: + return is_set; +} diff --git a/lib/trace-ir/fields.c b/lib/trace-ir/fields.c deleted file mode 100644 index 275c02b9..00000000 --- a/lib/trace-ir/fields.c +++ /dev/null @@ -1,1170 +0,0 @@ -/* - * Copyright 2013, 2014 Jérémie Galarneau - * - * Author: Jérémie Galarneau - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define BT_LOG_TAG "FIELDS" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static -void reset_single_field(struct bt_field *field); - -static -void reset_array_field(struct bt_field *field); - -static -void reset_structure_field(struct bt_field *field); - -static -void reset_variant_field(struct bt_field *field); - -static -void set_single_field_is_frozen(struct bt_field *field, bool is_frozen); - -static -void set_array_field_is_frozen(struct bt_field *field, bool is_frozen); - -static -void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen); - -static -void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen); - -static -bool single_field_is_set(const struct bt_field *field); - -static -bool array_field_is_set(const struct bt_field *field); - -static -bool structure_field_is_set(const struct bt_field *field); - -static -bool variant_field_is_set(const struct bt_field *field); - -static -struct bt_field_methods integer_field_methods = { - .set_is_frozen = set_single_field_is_frozen, - .is_set = single_field_is_set, - .reset = reset_single_field, -}; - -static -struct bt_field_methods real_field_methods = { - .set_is_frozen = set_single_field_is_frozen, - .is_set = single_field_is_set, - .reset = reset_single_field, -}; - -static -struct bt_field_methods string_field_methods = { - .set_is_frozen = set_single_field_is_frozen, - .is_set = single_field_is_set, - .reset = reset_single_field, -}; - -static -struct bt_field_methods structure_field_methods = { - .set_is_frozen = set_structure_field_is_frozen, - .is_set = structure_field_is_set, - .reset = reset_structure_field, -}; - -static -struct bt_field_methods array_field_methods = { - .set_is_frozen = set_array_field_is_frozen, - .is_set = array_field_is_set, - .reset = reset_array_field, -}; - -static -struct bt_field_methods variant_field_methods = { - .set_is_frozen = set_variant_field_is_frozen, - .is_set = variant_field_is_set, - .reset = reset_variant_field, -}; - -static -struct bt_field *create_integer_field(struct bt_field_class *); - -static -struct bt_field *create_real_field(struct bt_field_class *); - -static -struct bt_field *create_string_field(struct bt_field_class *); - -static -struct bt_field *create_structure_field(struct bt_field_class *); - -static -struct bt_field *create_static_array_field(struct bt_field_class *); - -static -struct bt_field *create_dynamic_array_field(struct bt_field_class *); - -static -struct bt_field *create_variant_field(struct bt_field_class *); - -static -struct bt_field *(* const field_create_funcs[])(struct bt_field_class *) = { - [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = create_integer_field, - [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = create_integer_field, - [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = create_integer_field, - [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = create_integer_field, - [BT_FIELD_CLASS_TYPE_REAL] = create_real_field, - [BT_FIELD_CLASS_TYPE_STRING] = create_string_field, - [BT_FIELD_CLASS_TYPE_STRUCTURE] = create_structure_field, - [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = create_static_array_field, - [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = create_dynamic_array_field, - [BT_FIELD_CLASS_TYPE_VARIANT] = create_variant_field, -}; - -static -void destroy_integer_field(struct bt_field *field); - -static -void destroy_real_field(struct bt_field *field); - -static -void destroy_string_field(struct bt_field *field); - -static -void destroy_structure_field(struct bt_field *field); - -static -void destroy_array_field(struct bt_field *field); - -static -void destroy_variant_field(struct bt_field *field); - -static -void (* const field_destroy_funcs[])(struct bt_field *) = { - [BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER] = destroy_integer_field, - [BT_FIELD_CLASS_TYPE_SIGNED_INTEGER] = destroy_integer_field, - [BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION] = destroy_integer_field, - [BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION] = destroy_integer_field, - [BT_FIELD_CLASS_TYPE_REAL] = destroy_real_field, - [BT_FIELD_CLASS_TYPE_STRING] = destroy_string_field, - [BT_FIELD_CLASS_TYPE_STRUCTURE] = destroy_structure_field, - [BT_FIELD_CLASS_TYPE_STATIC_ARRAY] = destroy_array_field, - [BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY] = destroy_array_field, - [BT_FIELD_CLASS_TYPE_VARIANT] = destroy_variant_field, -}; - -struct bt_field_class *bt_field_borrow_class(const struct bt_field *field) -{ - BT_ASSERT_PRE_NON_NULL(field, "Field"); - return field->class; -} - -const struct bt_field_class *bt_field_borrow_class_const( - const struct bt_field *field) -{ - BT_ASSERT_PRE_NON_NULL(field, "Field"); - return field->class; -} - -enum bt_field_class_type bt_field_get_class_type(const struct bt_field *field) -{ - BT_ASSERT_PRE_NON_NULL(field, "Field"); - return field->class->type; -} - -BT_HIDDEN -struct bt_field *bt_field_create(struct bt_field_class *fc) -{ - struct bt_field *field = NULL; - - BT_ASSERT_PRE_NON_NULL(fc, "Field class"); - BT_ASSERT(bt_field_class_has_known_type(fc)); - field = field_create_funcs[fc->type](fc); - if (!field) { - BT_LIB_LOGE("Cannot create field object from field class: " - "%![fc-]+F", fc); - goto end; - } - -end: - return field; -} - -static inline -void init_field(struct bt_field *field, struct bt_field_class *fc, - struct bt_field_methods *methods) -{ - BT_ASSERT(field); - BT_ASSERT(fc); - bt_object_init_unique(&field->base); - field->methods = methods; - field->class = fc; - bt_object_get_no_null_check(fc); -} - -static -struct bt_field *create_integer_field(struct bt_field_class *fc) -{ - struct bt_field_integer *int_field; - - BT_LIB_LOGD("Creating integer field object: %![fc-]+F", fc); - int_field = g_new0(struct bt_field_integer, 1); - if (!int_field) { - BT_LOGE_STR("Failed to allocate one integer field."); - goto end; - } - - init_field((void *) int_field, fc, &integer_field_methods); - BT_LIB_LOGD("Created integer field object: %!+f", int_field); - -end: - return (void *) int_field; -} - -static -struct bt_field *create_real_field(struct bt_field_class *fc) -{ - struct bt_field_real *real_field; - - BT_LIB_LOGD("Creating real field object: %![fc-]+F", fc); - real_field = g_new0(struct bt_field_real, 1); - if (!real_field) { - BT_LOGE_STR("Failed to allocate one real field."); - goto end; - } - - init_field((void *) real_field, fc, &real_field_methods); - BT_LIB_LOGD("Created real field object: %!+f", real_field); - -end: - return (void *) real_field; -} - -static -struct bt_field *create_string_field(struct bt_field_class *fc) -{ - struct bt_field_string *string_field; - - BT_LIB_LOGD("Creating string field object: %![fc-]+F", fc); - string_field = g_new0(struct bt_field_string, 1); - if (!string_field) { - BT_LOGE_STR("Failed to allocate one string field."); - goto end; - } - - init_field((void *) string_field, fc, &string_field_methods); - string_field->buf = g_array_sized_new(FALSE, FALSE, - sizeof(char), 1); - if (!string_field->buf) { - BT_LOGE_STR("Failed to allocate a GArray."); - BT_OBJECT_PUT_REF_AND_RESET(string_field); - goto end; - } - - g_array_index(string_field->buf, char, 0) = '\0'; - BT_LIB_LOGD("Created string field object: %!+f", string_field); - -end: - return (void *) string_field; -} - -static inline -int create_fields_from_named_field_classes( - struct bt_field_class_named_field_class_container *fc, - GPtrArray **fields) -{ - int ret = 0; - uint64_t i; - - *fields = g_ptr_array_new_with_free_func( - (GDestroyNotify) bt_field_destroy); - if (!*fields) { - BT_LOGE_STR("Failed to allocate a GPtrArray."); - ret = -1; - goto end; - } - - g_ptr_array_set_size(*fields, fc->named_fcs->len); - - for (i = 0; i < fc->named_fcs->len; i++) { - struct bt_field *field; - struct bt_named_field_class *named_fc = - BT_FIELD_CLASS_NAMED_FC_AT_INDEX(fc, i); - - field = bt_field_create(named_fc->fc); - if (!field) { - BT_LIB_LOGE("Failed to create structure member or variant option field: " - "name=\"%s\", %![fc-]+F", - named_fc->name->str, named_fc->fc); - ret = -1; - goto end; - } - - g_ptr_array_index(*fields, i) = field; - } - -end: - return ret; -} - -static -struct bt_field *create_structure_field(struct bt_field_class *fc) -{ - struct bt_field_structure *struct_field; - - BT_LIB_LOGD("Creating structure field object: %![fc-]+F", fc); - struct_field = g_new0(struct bt_field_structure, 1); - if (!struct_field) { - BT_LOGE_STR("Failed to allocate one structure field."); - goto end; - } - - init_field((void *) struct_field, fc, &structure_field_methods); - - if (create_fields_from_named_field_classes((void *) fc, - &struct_field->fields)) { - BT_LIB_LOGE("Cannot create structure member fields: " - "%![fc-]+F", fc); - BT_OBJECT_PUT_REF_AND_RESET(struct_field); - goto end; - } - - BT_LIB_LOGD("Created structure field object: %!+f", struct_field); - -end: - return (void *) struct_field; -} - -static -struct bt_field *create_variant_field(struct bt_field_class *fc) -{ - struct bt_field_variant *var_field; - - BT_LIB_LOGD("Creating variant field object: %![fc-]+F", fc); - var_field = g_new0(struct bt_field_variant, 1); - if (!var_field) { - BT_LOGE_STR("Failed to allocate one variant field."); - goto end; - } - - init_field((void *) var_field, fc, &variant_field_methods); - - if (create_fields_from_named_field_classes((void *) fc, - &var_field->fields)) { - BT_LIB_LOGE("Cannot create variant member fields: " - "%![fc-]+F", fc); - BT_OBJECT_PUT_REF_AND_RESET(var_field); - goto end; - } - - BT_LIB_LOGD("Created variant field object: %!+f", var_field); - -end: - return (void *) var_field; -} - -static inline -int init_array_field_fields(struct bt_field_array *array_field) -{ - int ret = 0; - uint64_t i; - struct bt_field_class_array *array_fc; - - BT_ASSERT(array_field); - array_fc = (void *) array_field->common.class; - array_field->fields = g_ptr_array_sized_new(array_field->length); - if (!array_field->fields) { - BT_LOGE_STR("Failed to allocate a GPtrArray."); - ret = -1; - goto end; - } - - g_ptr_array_set_free_func(array_field->fields, - (GDestroyNotify) bt_field_destroy); - g_ptr_array_set_size(array_field->fields, array_field->length); - - for (i = 0; i < array_field->length; i++) { - array_field->fields->pdata[i] = bt_field_create( - array_fc->element_fc); - if (!array_field->fields->pdata[i]) { - BT_LIB_LOGE("Cannot create array field's element field: " - "index=%" PRIu64 ", %![fc-]+F", i, array_fc); - ret = -1; - goto end; - } - } - -end: - return ret; -} - -static -struct bt_field *create_static_array_field(struct bt_field_class *fc) -{ - struct bt_field_class_static_array *array_fc = (void *) fc; - struct bt_field_array *array_field; - - BT_LIB_LOGD("Creating static array field object: %![fc-]+F", fc); - array_field = g_new0(struct bt_field_array, 1); - if (!array_field) { - BT_LOGE_STR("Failed to allocate one static array field."); - goto end; - } - - init_field((void *) array_field, fc, &array_field_methods); - array_field->length = array_fc->length; - - if (init_array_field_fields(array_field)) { - BT_LIB_LOGE("Cannot create static array fields: " - "%![fc-]+F", fc); - BT_OBJECT_PUT_REF_AND_RESET(array_field); - goto end; - } - - BT_LIB_LOGD("Created static array field object: %!+f", array_field); - -end: - return (void *) array_field; -} - -static -struct bt_field *create_dynamic_array_field(struct bt_field_class *fc) -{ - struct bt_field_array *array_field; - - BT_LIB_LOGD("Creating dynamic array field object: %![fc-]+F", fc); - array_field = g_new0(struct bt_field_array, 1); - if (!array_field) { - BT_LOGE_STR("Failed to allocate one dynamic array field."); - goto end; - } - - init_field((void *) array_field, fc, &array_field_methods); - - if (init_array_field_fields(array_field)) { - BT_LIB_LOGE("Cannot create dynamic array fields: " - "%![fc-]+F", fc); - BT_OBJECT_PUT_REF_AND_RESET(array_field); - goto end; - } - - BT_LIB_LOGD("Created dynamic array field object: %!+f", array_field); - -end: - return (void *) array_field; -} - -int64_t bt_field_signed_integer_get_value(const struct bt_field *field) -{ - const struct bt_field_integer *int_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); - return int_field->value.i; -} - -void bt_field_signed_integer_set_value(struct bt_field *field, int64_t value) -{ - struct bt_field_integer *int_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SIGNED_INT(field, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE(bt_util_value_is_in_range_signed( - ((struct bt_field_class_integer *) field->class)->range, value), - "Value is out of bounds: value=%" PRId64 ", %![field-]+f, " - "%![fc-]+F", value, field, field->class); - int_field->value.i = value; - bt_field_set_single(field, true); -} - -uint64_t bt_field_unsigned_integer_get_value(const struct bt_field *field) -{ - const struct bt_field_integer *int_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); - return int_field->value.u; -} - -void bt_field_unsigned_integer_set_value(struct bt_field *field, uint64_t value) -{ - struct bt_field_integer *int_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_UNSIGNED_INT(field, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE(bt_util_value_is_in_range_unsigned( - ((struct bt_field_class_integer *) field->class)->range, value), - "Value is out of bounds: value=%" PRIu64 ", %![field-]+f, " - "%![fc-]+F", value, field, field->class); - int_field->value.u = value; - bt_field_set_single(field, true); -} - -double bt_field_real_get_value(const struct bt_field *field) -{ - const struct bt_field_real *real_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); - return real_field->value; -} - -void bt_field_real_set_value(struct bt_field *field, double value) -{ - struct bt_field_real *real_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_REAL, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE( - !((struct bt_field_class_real *) field->class)->is_single_precision || - (double) (float) value == value, - "Invalid value for a single-precision real number: value=%f, " - "%![fc-]+F", value, field->class); - real_field->value = value; - bt_field_set_single(field, true); -} - -int bt_field_unsigned_enumeration_get_mapping_labels( - const struct bt_field *field, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count) -{ - const struct bt_field_integer *int_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); - BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION, "Field"); - return bt_field_class_unsigned_enumeration_get_mapping_labels_by_value( - field->class, int_field->value.u, label_array, count); -} - -int bt_field_signed_enumeration_get_mapping_labels( - const struct bt_field *field, - bt_field_class_enumeration_mapping_label_array *label_array, - uint64_t *count) -{ - const struct bt_field_integer *int_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_NON_NULL(label_array, "Label array (output)"); - BT_ASSERT_PRE_NON_NULL(label_array, "Count (output)"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION, "Field"); - return bt_field_class_signed_enumeration_get_mapping_labels_by_value( - field->class, int_field->value.i, label_array, count); -} - -const char *bt_field_string_get_value(const struct bt_field *field) -{ - const struct bt_field_string *string_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, - "Field"); - return (const char *) string_field->buf->data; -} - -uint64_t bt_field_string_get_length(const struct bt_field *field) -{ - const struct bt_field_string *string_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_SET(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, - "Field"); - return string_field->length; -} - -int bt_field_string_set_value(struct bt_field *field, const char *value) -{ - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_NON_NULL(value, "Value"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, BT_FIELD_CLASS_TYPE_STRING, - "Field"); - bt_field_string_clear(field); - return bt_field_string_append_with_length(field, value, - (uint64_t) strlen(value)); -} - -int bt_field_string_append(struct bt_field *field, const char *value) -{ - return bt_field_string_append_with_length(field, - value, (uint64_t) strlen(value)); -} - -int bt_field_string_append_with_length(struct bt_field *field, - const char *value, uint64_t length) -{ - struct bt_field_string *string_field = (void *) field; - char *data; - uint64_t new_length; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_NON_NULL(value, "Value"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_STRING, "Field"); - - /* Make sure no null bytes are appended */ - BT_ASSERT_PRE(memchr(value, '\0', length) == NULL, - "String value to append contains a null character: " - "partial-value=\"%.32s\", length=%" PRIu64, value, length); - - new_length = length + string_field->length; - - if (unlikely(new_length + 1 > string_field->buf->len)) { - g_array_set_size(string_field->buf, new_length + 1); - } - - data = string_field->buf->data; - memcpy(data + string_field->length, value, length); - ((char *) string_field->buf->data)[new_length] = '\0'; - string_field->length = new_length; - bt_field_set_single(field, true); - return 0; -} - -int bt_field_string_clear(struct bt_field *field) -{ - struct bt_field_string *string_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_STRING, "Field"); - string_field->length = 0; - bt_field_set_single(field, true); - return 0; -} - -uint64_t bt_field_array_get_length(const struct bt_field *field) -{ - const struct bt_field_array *array_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); - return array_field->length; -} - -int bt_field_dynamic_array_set_length(struct bt_field *field, uint64_t length) -{ - int ret = 0; - struct bt_field_array *array_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - - if (unlikely(length > array_field->fields->len)) { - /* Make more room */ - struct bt_field_class_array *array_fc; - uint64_t cur_len = array_field->fields->len; - uint64_t i; - - g_ptr_array_set_size(array_field->fields, length); - array_fc = (void *) field->class; - - for (i = cur_len; i < array_field->fields->len; i++) { - struct bt_field *elem_field = bt_field_create( - array_fc->element_fc); - - if (!elem_field) { - BT_LIB_LOGE("Cannot create element field for " - "dynamic array field: " - "index=%" PRIu64 ", " - "%![array-field-]+f", i, field); - ret = -1; - goto end; - } - - BT_ASSERT(!array_field->fields->pdata[i]); - array_field->fields->pdata[i] = elem_field; - } - } - - array_field->length = length; - -end: - return ret; -} - -static inline -struct bt_field *borrow_array_field_element_field_by_index( - struct bt_field *field, uint64_t index) -{ - struct bt_field_array *array_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_IS_ARRAY(field, "Field"); - BT_ASSERT_PRE_VALID_INDEX(index, array_field->length); - return array_field->fields->pdata[index]; -} - -struct bt_field *bt_field_array_borrow_element_field_by_index( - struct bt_field *field, uint64_t index) -{ - return borrow_array_field_element_field_by_index(field, index); -} - -const struct bt_field * -bt_field_array_borrow_element_field_by_index_const( - const struct bt_field *field, uint64_t index) -{ - return borrow_array_field_element_field_by_index((void *) field, index); -} - -static inline -struct bt_field *borrow_structure_field_member_field_by_index( - struct bt_field *field, uint64_t index) -{ - struct bt_field_structure *struct_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); - BT_ASSERT_PRE_VALID_INDEX(index, struct_field->fields->len); - return struct_field->fields->pdata[index]; -} - -struct bt_field *bt_field_structure_borrow_member_field_by_index( - struct bt_field *field, uint64_t index) -{ - return borrow_structure_field_member_field_by_index(field, - index); -} - -const struct bt_field * -bt_field_structure_borrow_member_field_by_index_const( - const struct bt_field *field, uint64_t index) -{ - return borrow_structure_field_member_field_by_index( - (void *) field, index); -} - -static inline -struct bt_field *borrow_structure_field_member_field_by_name( - struct bt_field *field, const char *name) -{ - struct bt_field *ret_field = NULL; - struct bt_field_class_structure *struct_fc; - struct bt_field_structure *struct_field = (void *) field; - gpointer orig_key; - gpointer index; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_NON_NULL(name, "Field name"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_STRUCTURE, "Field"); - struct_fc = (void *) field->class; - - if (!g_hash_table_lookup_extended(struct_fc->common.name_to_index, name, - &orig_key, &index)) { - goto end; - } - - ret_field = struct_field->fields->pdata[GPOINTER_TO_UINT(index)]; - BT_ASSERT(ret_field); - -end: - return ret_field; -} - -struct bt_field *bt_field_structure_borrow_member_field_by_name( - struct bt_field *field, const char *name) -{ - return borrow_structure_field_member_field_by_name(field, name); -} - -const struct bt_field *bt_field_structure_borrow_member_field_by_name_const( - const struct bt_field *field, const char *name) -{ - return borrow_structure_field_member_field_by_name( - (void *) field, name); -} - -static inline -struct bt_field *borrow_variant_field_selected_option_field( - struct bt_field *field) -{ - struct bt_field_variant *var_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_VARIANT, "Field"); - BT_ASSERT_PRE(var_field->selected_field, - "Variant field has no selected field: %!+f", field); - return var_field->selected_field; -} - -struct bt_field *bt_field_variant_borrow_selected_option_field( - struct bt_field *field) -{ - return borrow_variant_field_selected_option_field(field); -} - -const struct bt_field *bt_field_variant_borrow_selected_option_field_const( - const struct bt_field *field) -{ - return borrow_variant_field_selected_option_field((void *) field); -} - -int bt_field_variant_select_option_field( - struct bt_field *field, uint64_t index) -{ - struct bt_field_variant *var_field = (void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_VARIANT, "Field"); - BT_ASSERT_PRE_FIELD_HOT(field, "Field"); - BT_ASSERT_PRE_VALID_INDEX(index, var_field->fields->len); - var_field->selected_field = var_field->fields->pdata[index]; - var_field->selected_index = index; - return 0; -} - -uint64_t bt_field_variant_get_selected_option_field_index( - const struct bt_field *field) -{ - const struct bt_field_variant *var_field = (const void *) field; - - BT_ASSERT_PRE_NON_NULL(field, "Field"); - BT_ASSERT_PRE_FIELD_HAS_CLASS_TYPE(field, - BT_FIELD_CLASS_TYPE_VARIANT, "Field"); - BT_ASSERT_PRE(var_field->selected_field, - "Variant field has no selected field: %!+f", field); - return var_field->selected_index; -} - -static inline -void bt_field_finalize(struct bt_field *field) -{ - BT_ASSERT(field); - BT_LOGD_STR("Putting field's class."); - BT_OBJECT_PUT_REF_AND_RESET(field->class); -} - -static -void destroy_integer_field(struct bt_field *field) -{ - BT_ASSERT(field); - BT_LIB_LOGD("Destroying integer field object: %!+f", field); - bt_field_finalize(field); - g_free(field); -} - -static -void destroy_real_field(struct bt_field *field) -{ - BT_ASSERT(field); - BT_LIB_LOGD("Destroying real field object: %!+f", field); - bt_field_finalize(field); - g_free(field); -} - -static -void destroy_structure_field(struct bt_field *field) -{ - struct bt_field_structure *struct_field = (void *) field; - - BT_ASSERT(field); - BT_LIB_LOGD("Destroying structure field object: %!+f", field); - bt_field_finalize(field); - - if (struct_field->fields) { - g_ptr_array_free(struct_field->fields, TRUE); - struct_field->fields = NULL; - } - - g_free(field); -} - -static -void destroy_variant_field(struct bt_field *field) -{ - struct bt_field_variant *var_field = (void *) field; - - BT_ASSERT(field); - BT_LIB_LOGD("Destroying variant field object: %!+f", field); - bt_field_finalize(field); - - if (var_field->fields) { - g_ptr_array_free(var_field->fields, TRUE); - var_field->fields = NULL; - } - - g_free(field); -} - -static -void destroy_array_field(struct bt_field *field) -{ - struct bt_field_array *array_field = (void *) field; - - BT_ASSERT(field); - BT_LIB_LOGD("Destroying array field object: %!+f", field); - bt_field_finalize(field); - - if (array_field->fields) { - g_ptr_array_free(array_field->fields, TRUE); - array_field->fields = NULL; - } - - g_free(field); -} - -static -void destroy_string_field(struct bt_field *field) -{ - struct bt_field_string *string_field = (void *) field; - - BT_ASSERT(field); - BT_LIB_LOGD("Destroying string field object: %!+f", field); - bt_field_finalize(field); - - if (string_field->buf) { - g_array_free(string_field->buf, TRUE); - string_field->buf = NULL; - } - - g_free(field); -} - -BT_HIDDEN -void bt_field_destroy(struct bt_field *field) -{ - BT_ASSERT(field); - BT_ASSERT(bt_field_class_has_known_type(field->class)); - field_destroy_funcs[field->class->type](field); -} - -static -void reset_single_field(struct bt_field *field) -{ - BT_ASSERT(field); - field->is_set = false; -} - -static -void reset_structure_field(struct bt_field *field) -{ - uint64_t i; - struct bt_field_structure *struct_field = (void *) field; - - BT_ASSERT(field); - - for (i = 0; i < struct_field->fields->len; i++) { - bt_field_reset(struct_field->fields->pdata[i]); - } -} - -static -void reset_variant_field(struct bt_field *field) -{ - uint64_t i; - struct bt_field_variant *var_field = (void *) field; - - BT_ASSERT(field); - - for (i = 0; i < var_field->fields->len; i++) { - bt_field_reset(var_field->fields->pdata[i]); - } -} - -static -void reset_array_field(struct bt_field *field) -{ - uint64_t i; - struct bt_field_array *array_field = (void *) field; - - BT_ASSERT(field); - - for (i = 0; i < array_field->fields->len; i++) { - bt_field_reset(array_field->fields->pdata[i]); - } -} - -static -void set_single_field_is_frozen(struct bt_field *field, bool is_frozen) -{ - field->frozen = is_frozen; -} - -static -void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen) -{ - uint64_t i; - struct bt_field_structure *struct_field = (void *) field; - - BT_LIB_LOGD("Setting structure field's frozen state: " - "%![field-]+f, is-frozen=%d", field, is_frozen); - - for (i = 0; i < struct_field->fields->len; i++) { - struct bt_field *member_field = struct_field->fields->pdata[i]; - - BT_LIB_LOGD("Setting structure field's member field's " - "frozen state: %![field-]+f, index=%" PRIu64, - member_field, i); - bt_field_set_is_frozen(member_field, is_frozen); - } - - set_single_field_is_frozen(field, is_frozen); -} - -static -void set_variant_field_is_frozen(struct bt_field *field, bool is_frozen) -{ - uint64_t i; - struct bt_field_variant *var_field = (void *) field; - - BT_LIB_LOGD("Setting variant field's frozen state: " - "%![field-]+f, is-frozen=%d", field, is_frozen); - - for (i = 0; i < var_field->fields->len; i++) { - struct bt_field *option_field = var_field->fields->pdata[i]; - - BT_LIB_LOGD("Setting variant field's option field's " - "frozen state: %![field-]+f, index=%" PRIu64, - option_field, i); - bt_field_set_is_frozen(option_field, is_frozen); - } - - set_single_field_is_frozen(field, is_frozen); -} - -static -void set_array_field_is_frozen(struct bt_field *field, bool is_frozen) -{ - uint64_t i; - struct bt_field_array *array_field = (void *) field; - - BT_LIB_LOGD("Setting array field's frozen state: " - "%![field-]+f, is-frozen=%d", field, is_frozen); - - for (i = 0; i < array_field->fields->len; i++) { - struct bt_field *elem_field = array_field->fields->pdata[i]; - - BT_LIB_LOGD("Setting array field's element field's " - "frozen state: %![field-]+f, index=%" PRIu64, - elem_field, i); - bt_field_set_is_frozen(elem_field, is_frozen); - } - - set_single_field_is_frozen(field, is_frozen); -} - -BT_HIDDEN -void _bt_field_set_is_frozen(const struct bt_field *field, - bool is_frozen) -{ - BT_ASSERT(field); - BT_LIB_LOGD("Setting field object's frozen state: %!+f, is-frozen=%d", - field, is_frozen); - BT_ASSERT(field->methods->set_is_frozen); - field->methods->set_is_frozen((void *) field, is_frozen); -} - -static -bool single_field_is_set(const struct bt_field *field) -{ - BT_ASSERT(field); - return field->is_set; -} - -static -bool structure_field_is_set(const struct bt_field *field) -{ - bool is_set = true; - uint64_t i; - const struct bt_field_structure *struct_field = (const void *) field; - - BT_ASSERT(field); - - for (i = 0; i < struct_field->fields->len; i++) { - is_set = bt_field_is_set(struct_field->fields->pdata[i]); - if (!is_set) { - goto end; - } - } - -end: - return is_set; -} - -static -bool variant_field_is_set(const struct bt_field *field) -{ - const struct bt_field_variant *var_field = (const void *) field; - bool is_set = false; - - BT_ASSERT(field); - - if (var_field->selected_field) { - is_set = bt_field_is_set(var_field->selected_field); - } - - return is_set; -} - -static -bool array_field_is_set(const struct bt_field *field) -{ - bool is_set = true; - uint64_t i; - const struct bt_field_array *array_field = (const void *) field; - - BT_ASSERT(field); - - for (i = 0; i < array_field->length; i++) { - is_set = bt_field_is_set(array_field->fields->pdata[i]); - if (!is_set) { - goto end; - } - } - -end: - return is_set; -} diff --git a/lib/trace-ir/packet-context-field.c b/lib/trace-ir/packet-context-field.c index 1b2e7ef8..2df09f08 100644 --- a/lib/trace-ir/packet-context-field.c +++ b/lib/trace-ir/packet-context-field.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/lib/trace-ir/packet-header-field.c b/lib/trace-ir/packet-header-field.c index 3b7d89f5..8f72a42a 100644 --- a/lib/trace-ir/packet-header-field.c +++ b/lib/trace-ir/packet-header-field.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include struct bt_field *bt_packet_header_field_borrow_field( diff --git a/lib/trace-ir/packet.c b/lib/trace-ir/packet.c index 51bce30e..63177d7a 100644 --- a/lib/trace-ir/packet.c +++ b/lib/trace-ir/packet.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/trace-ir/resolve-field-path.c b/lib/trace-ir/resolve-field-path.c index 40bc7fcc..0254dd42 100644 --- a/lib/trace-ir/resolve-field-path.c +++ b/lib/trace-ir/resolve-field-path.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/trace-ir/stream-class.c b/lib/trace-ir/stream-class.c index dfef7436..763f81ab 100644 --- a/lib/trace-ir/stream-class.c +++ b/lib/trace-ir/stream-class.c @@ -28,8 +28,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/lib/trace-ir/trace-class.c b/lib/trace-ir/trace-class.c index 709810ef..1d2c8097 100644 --- a/lib/trace-ir/trace-class.c +++ b/lib/trace-ir/trace-class.c @@ -38,14 +38,14 @@ #include #include #include -#include +#include #include #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/lib/trace-ir/trace.c b/lib/trace-ir/trace.c index 94e88d3d..7cf2f2c4 100644 --- a/lib/trace-ir/trace.c +++ b/lib/trace-ir/trace.c @@ -39,14 +39,14 @@ #include #include #include -#include +#include #include #include #include #include -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/lib/trace-ir/utils.c b/lib/trace-ir/utils.c index 4addffc2..00dc7578 100644 --- a/lib/trace-ir/utils.c +++ b/lib/trace-ir/utils.c @@ -27,7 +27,7 @@ #include #include -#include +#include #include #include #include diff --git a/lib/value.c b/lib/value.c new file mode 100644 index 00000000..e4a0d1e4 --- /dev/null +++ b/lib/value.c @@ -0,0 +1,1302 @@ +/* + * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation + * Copyright (c) 2015 Philippe Proulx + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#define BT_LOG_TAG "VALUES" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BT_VALUE_FROM_CONCRETE(_concrete) ((struct bt_value *) (_concrete)) +#define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base)) +#define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base)) +#define BT_VALUE_TO_REAL(_base) ((struct bt_value_real *) (_base)) +#define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base)) +#define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base)) +#define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base)) + +#define BT_ASSERT_PRE_VALUE_IS_TYPE(_value, _type) \ + BT_ASSERT_PRE(((struct bt_value *) (_value))->type == (_type), \ + "Value has the wrong type ID: expected-type=%s, " \ + "%![value-]+v", bt_common_value_type_string(_type), \ + (_value)) + +#define BT_ASSERT_PRE_VALUE_HOT(_value, _name) \ + BT_ASSERT_PRE_HOT(((struct bt_value *) (_value)), (_name), \ + ": %!+v", (_value)) + +#define BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(_index, _count) \ + BT_ASSERT_PRE((_index) < (_count), \ + "Index is out of bound: " \ + "index=%" PRIu64 ", count=%u", (_index), (_count)); + +struct bt_value { + struct bt_object base; + enum bt_value_type type; + bt_bool frozen; +}; + +static +void bt_value_null_instance_release_func(struct bt_object *obj) +{ + BT_LOGW("Releasing the null value singleton: addr=%p", obj); +} + +static +struct bt_value bt_value_null_instance = { + .base = { + .is_shared = true, + .ref_count = 1, + .release_func = bt_value_null_instance_release_func, + .spec_release_func = NULL, + .parent_is_owner_listener_func = NULL, + .parent = NULL, + }, + .type = BT_VALUE_TYPE_NULL, + .frozen = BT_TRUE, +}; + +struct bt_value *bt_value_null = &bt_value_null_instance; + +struct bt_value_bool { + struct bt_value base; + bt_bool value; +}; + +struct bt_value_integer { + struct bt_value base; + int64_t value; +}; + +struct bt_value_real { + struct bt_value base; + double value; +}; + +struct bt_value_string { + struct bt_value base; + GString *gstr; +}; + +struct bt_value_array { + struct bt_value base; + GPtrArray *garray; +}; + +struct bt_value_map { + struct bt_value base; + GHashTable *ght; +}; + +static +void bt_value_destroy(struct bt_object *obj); + +static +void bt_value_string_destroy(struct bt_value *object) +{ + g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE); + BT_VALUE_TO_STRING(object)->gstr = NULL; +} + +static +void bt_value_array_destroy(struct bt_value *object) +{ + /* + * Pointer array's registered value destructor will take care + * of putting each contained object. + */ + g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE); + BT_VALUE_TO_ARRAY(object)->garray = NULL; +} + +static +void bt_value_map_destroy(struct bt_value *object) +{ + /* + * Hash table's registered value destructor will take care of + * putting each contained object. Keys are GQuarks and cannot + * be destroyed anyway. + */ + g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght); + BT_VALUE_TO_MAP(object)->ght = NULL; +} + +static +void (* const destroy_funcs[])(struct bt_value *) = { + [BT_VALUE_TYPE_NULL] = NULL, + [BT_VALUE_TYPE_BOOL] = NULL, + [BT_VALUE_TYPE_INTEGER] = NULL, + [BT_VALUE_TYPE_REAL] = NULL, + [BT_VALUE_TYPE_STRING] = bt_value_string_destroy, + [BT_VALUE_TYPE_ARRAY] = bt_value_array_destroy, + [BT_VALUE_TYPE_MAP] = bt_value_map_destroy, +}; + +static +struct bt_value *bt_value_null_copy(const struct bt_value *null_obj) +{ + return (void *) bt_value_null; +} + +static +struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj) +{ + return bt_value_bool_create_init( + BT_VALUE_TO_BOOL(bool_obj)->value); +} + +static +struct bt_value *bt_value_integer_copy( + const struct bt_value *integer_obj) +{ + return bt_value_integer_create_init( + BT_VALUE_TO_INTEGER(integer_obj)->value); +} + +static +struct bt_value *bt_value_real_copy(const struct bt_value *real_obj) +{ + return bt_value_real_create_init( + BT_VALUE_TO_REAL(real_obj)->value); +} + +static +struct bt_value *bt_value_string_copy(const struct bt_value *string_obj) +{ + return bt_value_string_create_init( + BT_VALUE_TO_STRING(string_obj)->gstr->str); +} + +static +struct bt_value *bt_value_array_copy(const struct bt_value *array_obj) +{ + int i; + int ret; + struct bt_value *copy_obj; + struct bt_value_array *typed_array_obj; + + BT_LOGD("Copying array value: addr=%p", array_obj); + typed_array_obj = BT_VALUE_TO_ARRAY(array_obj); + copy_obj = bt_value_array_create(); + if (!copy_obj) { + BT_LOGE_STR("Cannot create empty array value."); + goto end; + } + + for (i = 0; i < typed_array_obj->garray->len; ++i) { + struct bt_value *element_obj_copy = NULL; + const struct bt_value *element_obj = + bt_value_array_borrow_element_by_index_const( + array_obj, i); + + BT_ASSERT(element_obj); + BT_LOGD("Copying array value's element: element-addr=%p, " + "index=%d", element_obj, i); + ret = bt_value_copy(element_obj, &element_obj_copy); + if (ret) { + BT_LOGE("Cannot copy array value's element: " + "array-addr=%p, index=%d", + array_obj, i); + BT_OBJECT_PUT_REF_AND_RESET(copy_obj); + goto end; + } + + BT_ASSERT(element_obj_copy); + ret = bt_value_array_append_element(copy_obj, + (void *) element_obj_copy); + BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy); + if (ret) { + BT_LOGE("Cannot append to array value: addr=%p", + array_obj); + BT_OBJECT_PUT_REF_AND_RESET(copy_obj); + goto end; + } + } + + BT_LOGD("Copied array value: original-addr=%p, copy-addr=%p", + array_obj, copy_obj); + +end: + return copy_obj; +} + +static +struct bt_value *bt_value_map_copy(const struct bt_value *map_obj) +{ + int ret; + GHashTableIter iter; + gpointer key, element_obj; + struct bt_value *copy_obj; + struct bt_value *element_obj_copy = NULL; + struct bt_value_map *typed_map_obj; + + BT_LOGD("Copying map value: addr=%p", map_obj); + typed_map_obj = BT_VALUE_TO_MAP(map_obj); + copy_obj = bt_value_map_create(); + if (!copy_obj) { + goto end; + } + + g_hash_table_iter_init(&iter, typed_map_obj->ght); + + while (g_hash_table_iter_next(&iter, &key, &element_obj)) { + const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); + + BT_ASSERT(key_str); + BT_LOGD("Copying map value's element: element-addr=%p, " + "key=\"%s\"", element_obj, key_str); + ret = bt_value_copy(element_obj, &element_obj_copy); + if (ret) { + BT_LOGE("Cannot copy map value's element: " + "map-addr=%p, key=\"%s\"", + map_obj, key_str); + BT_OBJECT_PUT_REF_AND_RESET(copy_obj); + goto end; + } + + BT_ASSERT(element_obj_copy); + ret = bt_value_map_insert_entry(copy_obj, key_str, + (void *) element_obj_copy); + BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy); + if (ret) { + BT_LOGE("Cannot insert into map value: addr=%p, key=\"%s\"", + map_obj, key_str); + BT_OBJECT_PUT_REF_AND_RESET(copy_obj); + goto end; + } + } + + BT_LOGD("Copied map value: addr=%p", map_obj); + +end: + return copy_obj; +} + +static +struct bt_value *(* const copy_funcs[])(const struct bt_value *) = { + [BT_VALUE_TYPE_NULL] = bt_value_null_copy, + [BT_VALUE_TYPE_BOOL] = bt_value_bool_copy, + [BT_VALUE_TYPE_INTEGER] = bt_value_integer_copy, + [BT_VALUE_TYPE_REAL] = bt_value_real_copy, + [BT_VALUE_TYPE_STRING] = bt_value_string_copy, + [BT_VALUE_TYPE_ARRAY] = bt_value_array_copy, + [BT_VALUE_TYPE_MAP] = bt_value_map_copy, +}; + +static +bt_bool bt_value_null_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + /* + * Always BT_TRUE since bt_value_compare() already checks if both + * object_a and object_b have the same type, and in the case of + * null value objects, they're always the same if it is so. + */ + return BT_TRUE; +} + +static +bt_bool bt_value_bool_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + if (BT_VALUE_TO_BOOL(object_a)->value != + BT_VALUE_TO_BOOL(object_b)->value) { + BT_LOGV("Boolean value objects are different: " + "bool-a-val=%d, bool-b-val=%d", + BT_VALUE_TO_BOOL(object_a)->value, + BT_VALUE_TO_BOOL(object_b)->value); + return BT_FALSE; + } + + return BT_TRUE; +} + +static +bt_bool bt_value_integer_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + if (BT_VALUE_TO_INTEGER(object_a)->value != + BT_VALUE_TO_INTEGER(object_b)->value) { + BT_LOGV("Integer value objects are different: " + "int-a-val=%" PRId64 ", int-b-val=%" PRId64, + BT_VALUE_TO_INTEGER(object_a)->value, + BT_VALUE_TO_INTEGER(object_b)->value); + return BT_FALSE; + } + + return BT_TRUE; +} + +static +bt_bool bt_value_real_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + if (BT_VALUE_TO_REAL(object_a)->value != + BT_VALUE_TO_REAL(object_b)->value) { + BT_LOGV("Real number value objects are different: " + "real-a-val=%f, real-b-val=%f", + BT_VALUE_TO_REAL(object_a)->value, + BT_VALUE_TO_REAL(object_b)->value); + return BT_FALSE; + } + + return BT_TRUE; +} + +static +bt_bool bt_value_string_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + if (strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str, + BT_VALUE_TO_STRING(object_b)->gstr->str) != 0) { + BT_LOGV("String value objects are different: " + "string-a-val=\"%s\", string-b-val=\"%s\"", + BT_VALUE_TO_STRING(object_a)->gstr->str, + BT_VALUE_TO_STRING(object_b)->gstr->str); + return BT_FALSE; + } + + return BT_TRUE; +} + +static +bt_bool bt_value_array_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + int i; + bt_bool ret = BT_TRUE; + const struct bt_value_array *array_obj_a = + BT_VALUE_TO_ARRAY(object_a); + + if (bt_value_array_get_size(object_a) != + bt_value_array_get_size(object_b)) { + BT_LOGV("Array values are different: size mismatch " + "value-a-addr=%p, value-b-addr=%p, " + "value-a-size=%" PRId64 ", value-b-size=%" PRId64, + object_a, object_b, + bt_value_array_get_size(object_a), + bt_value_array_get_size(object_b)); + ret = BT_FALSE; + goto end; + } + + for (i = 0; i < array_obj_a->garray->len; ++i) { + const struct bt_value *element_obj_a; + const struct bt_value *element_obj_b; + + element_obj_a = bt_value_array_borrow_element_by_index_const( + object_a, i); + element_obj_b = bt_value_array_borrow_element_by_index_const( + object_b, i); + + if (!bt_value_compare(element_obj_a, element_obj_b)) { + BT_LOGV("Array values's elements are different: " + "value-a-addr=%p, value-b-addr=%p, index=%d", + element_obj_a, element_obj_b, i); + ret = BT_FALSE; + goto end; + } + } + +end: + return ret; +} + +static +bt_bool bt_value_map_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + bt_bool ret = BT_TRUE; + GHashTableIter iter; + gpointer key, element_obj_a; + const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a); + + if (bt_value_map_get_size(object_a) != + bt_value_map_get_size(object_b)) { + BT_LOGV("Map values are different: size mismatch " + "value-a-addr=%p, value-b-addr=%p, " + "value-a-size=%" PRId64 ", value-b-size=%" PRId64, + object_a, object_b, + bt_value_map_get_size(object_a), + bt_value_map_get_size(object_b)); + ret = BT_FALSE; + goto end; + } + + g_hash_table_iter_init(&iter, map_obj_a->ght); + + while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) { + const struct bt_value *element_obj_b; + const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); + + element_obj_b = bt_value_map_borrow_entry_value_const(object_b, + key_str); + + if (!bt_value_compare(element_obj_a, element_obj_b)) { + BT_LOGV("Map values's elements are different: " + "value-a-addr=%p, value-b-addr=%p, key=\"%s\"", + element_obj_a, element_obj_b, key_str); + ret = BT_FALSE; + goto end; + } + } + +end: + return ret; +} + +static +bt_bool (* const compare_funcs[])(const struct bt_value *, + const struct bt_value *) = { + [BT_VALUE_TYPE_NULL] = bt_value_null_compare, + [BT_VALUE_TYPE_BOOL] = bt_value_bool_compare, + [BT_VALUE_TYPE_INTEGER] = bt_value_integer_compare, + [BT_VALUE_TYPE_REAL] = bt_value_real_compare, + [BT_VALUE_TYPE_STRING] = bt_value_string_compare, + [BT_VALUE_TYPE_ARRAY] = bt_value_array_compare, + [BT_VALUE_TYPE_MAP] = bt_value_map_compare, +}; + +static +void bt_value_null_freeze(struct bt_value *object) +{ +} + +static +void bt_value_generic_freeze(struct bt_value *object) +{ + object->frozen = BT_TRUE; +} + +static +void bt_value_array_freeze(struct bt_value *object) +{ + int i; + struct bt_value_array *typed_array_obj = + BT_VALUE_TO_ARRAY(object); + + for (i = 0; i < typed_array_obj->garray->len; ++i) { + bt_value_freeze(g_ptr_array_index(typed_array_obj->garray, i)); + } + + bt_value_generic_freeze(object); +} + +static +void bt_value_map_freeze(struct bt_value *object) +{ + GHashTableIter iter; + gpointer key, element_obj; + const struct bt_value_map *map_obj = BT_VALUE_TO_MAP(object); + + g_hash_table_iter_init(&iter, map_obj->ght); + + while (g_hash_table_iter_next(&iter, &key, &element_obj)) { + bt_value_freeze(element_obj); + } + + bt_value_generic_freeze(object); +} + +static +void (* const freeze_funcs[])(struct bt_value *) = { + [BT_VALUE_TYPE_NULL] = bt_value_null_freeze, + [BT_VALUE_TYPE_BOOL] = bt_value_generic_freeze, + [BT_VALUE_TYPE_INTEGER] = bt_value_generic_freeze, + [BT_VALUE_TYPE_REAL] = bt_value_generic_freeze, + [BT_VALUE_TYPE_STRING] = bt_value_generic_freeze, + [BT_VALUE_TYPE_ARRAY] = bt_value_array_freeze, + [BT_VALUE_TYPE_MAP] = bt_value_map_freeze, +}; + +static +void bt_value_destroy(struct bt_object *obj) +{ + struct bt_value *value; + + value = container_of(obj, struct bt_value, base); + BT_LOGD("Destroying value: addr=%p", value); + + if (bt_value_is_null(value)) { + BT_LOGD_STR("Not destroying the null value singleton."); + return; + } + + if (destroy_funcs[value->type]) { + destroy_funcs[value->type](value); + } + + g_free(value); +} + +BT_HIDDEN +enum bt_value_status _bt_value_freeze(const struct bt_value *c_object) +{ + const struct bt_value *object = (void *) c_object; + enum bt_value_status ret = BT_VALUE_STATUS_OK; + + BT_ASSERT(object); + + if (object->frozen) { + goto end; + } + + BT_LOGD("Freezing value: addr=%p", object); + freeze_funcs[object->type]((void *) object); + +end: + return ret; +} + +enum bt_value_type bt_value_get_type(const struct bt_value *object) +{ + BT_ASSERT_PRE_NON_NULL(object, "Value object"); + return object->type; +} + +static +struct bt_value bt_value_create_base(enum bt_value_type type) +{ + struct bt_value value; + + value.type = type; + value.frozen = BT_FALSE; + bt_object_init_shared(&value.base, bt_value_destroy); + return value; +} + +struct bt_value *bt_value_bool_create_init(bt_bool val) +{ + struct bt_value_bool *bool_obj; + + BT_LOGD("Creating boolean value object: val=%d", val); + bool_obj = g_new0(struct bt_value_bool, 1); + if (!bool_obj) { + BT_LOGE_STR("Failed to allocate one boolean value object."); + goto end; + } + + bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL); + bool_obj->value = val; + BT_LOGD("Created boolean value object: addr=%p", bool_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(bool_obj); +} + +struct bt_value *bt_value_bool_create(void) +{ + return bt_value_bool_create_init(BT_FALSE); +} + +struct bt_value *bt_value_integer_create_init(int64_t val) +{ + struct bt_value_integer *integer_obj; + + BT_LOGD("Creating integer value object: val=%" PRId64, val); + integer_obj = g_new0(struct bt_value_integer, 1); + if (!integer_obj) { + BT_LOGE_STR("Failed to allocate one integer value object."); + goto end; + } + + integer_obj->base = bt_value_create_base(BT_VALUE_TYPE_INTEGER); + integer_obj->value = val; + BT_LOGD("Created integer value object: addr=%p", + integer_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(integer_obj); +} + +struct bt_value *bt_value_integer_create(void) +{ + return bt_value_integer_create_init(0); +} + +struct bt_value *bt_value_real_create_init(double val) +{ + struct bt_value_real *real_obj; + + BT_LOGD("Creating real number value object: val=%f", val); + real_obj = g_new0(struct bt_value_real, 1); + if (!real_obj) { + BT_LOGE_STR("Failed to allocate one real number value object."); + goto end; + } + + real_obj->base = bt_value_create_base(BT_VALUE_TYPE_REAL); + real_obj->value = val; + BT_LOGD("Created real number value object: addr=%p", + real_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(real_obj); +} + +struct bt_value *bt_value_real_create(void) +{ + return bt_value_real_create_init(0.); +} + +struct bt_value *bt_value_string_create_init(const char *val) +{ + struct bt_value_string *string_obj = NULL; + + if (!val) { + BT_LOGW_STR("Invalid parameter: value is NULL."); + goto end; + } + + BT_LOGD("Creating string value object: val-len=%zu", strlen(val)); + string_obj = g_new0(struct bt_value_string, 1); + if (!string_obj) { + BT_LOGE_STR("Failed to allocate one string object."); + goto end; + } + + string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING); + string_obj->gstr = g_string_new(val); + if (!string_obj->gstr) { + BT_LOGE_STR("Failed to allocate a GString."); + g_free(string_obj); + string_obj = NULL; + goto end; + } + + BT_LOGD("Created string value object: addr=%p", + string_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(string_obj); +} + +struct bt_value *bt_value_string_create(void) +{ + return bt_value_string_create_init(""); +} + +struct bt_value *bt_value_array_create(void) +{ + struct bt_value_array *array_obj; + + BT_LOGD_STR("Creating empty array value object."); + array_obj = g_new0(struct bt_value_array, 1); + if (!array_obj) { + BT_LOGE_STR("Failed to allocate one array object."); + goto end; + } + + array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY); + array_obj->garray = bt_g_ptr_array_new_full(0, + (GDestroyNotify) bt_object_put_ref); + if (!array_obj->garray) { + BT_LOGE_STR("Failed to allocate a GPtrArray."); + g_free(array_obj); + array_obj = NULL; + goto end; + } + + BT_LOGD("Created array value object: addr=%p", + array_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(array_obj); +} + +struct bt_value *bt_value_map_create(void) +{ + struct bt_value_map *map_obj; + + BT_LOGD_STR("Creating empty map value object."); + map_obj = g_new0(struct bt_value_map, 1); + if (!map_obj) { + BT_LOGE_STR("Failed to allocate one map object."); + goto end; + } + + map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP); + map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal, + NULL, (GDestroyNotify) bt_object_put_ref); + if (!map_obj->ght) { + BT_LOGE_STR("Failed to allocate a GHashTable."); + g_free(map_obj); + map_obj = NULL; + goto end; + } + + BT_LOGD("Created map value object: addr=%p", + map_obj); + +end: + return (void *) BT_VALUE_FROM_CONCRETE(map_obj); +} + +bt_bool bt_value_bool_get(const struct bt_value *bool_obj) +{ + BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL); + return BT_VALUE_TO_BOOL(bool_obj)->value; +} + +void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val) +{ + BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL); + BT_ASSERT_PRE_VALUE_HOT(bool_obj, "Value object"); + BT_VALUE_TO_BOOL(bool_obj)->value = val; + BT_LOGV("Set boolean value's raw value: value-addr=%p, value=%d", + bool_obj, val); +} + +int64_t bt_value_integer_get(const struct bt_value *integer_obj) +{ + BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER); + return BT_VALUE_TO_INTEGER(integer_obj)->value; +} + +void bt_value_integer_set(struct bt_value *integer_obj, + int64_t val) +{ + BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER); + BT_ASSERT_PRE_VALUE_HOT(integer_obj, "Value object"); + BT_VALUE_TO_INTEGER(integer_obj)->value = val; + BT_LOGV("Set integer value's raw value: value-addr=%p, value=%" PRId64, + integer_obj, val); +} + +double bt_value_real_get(const struct bt_value *real_obj) +{ + BT_ASSERT_PRE_NON_NULL(real_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL); + return BT_VALUE_TO_REAL(real_obj)->value; +} + +void bt_value_real_set(struct bt_value *real_obj, double val) +{ + BT_ASSERT_PRE_NON_NULL(real_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL); + BT_ASSERT_PRE_VALUE_HOT(real_obj, "Value object"); + BT_VALUE_TO_REAL(real_obj)->value = val; + BT_LOGV("Set real number value's raw value: value-addr=%p, value=%f", + real_obj, val); +} + +const char *bt_value_string_get(const struct bt_value *string_obj) +{ + BT_ASSERT_PRE_NON_NULL(string_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING); + return BT_VALUE_TO_STRING(string_obj)->gstr->str; +} + +enum bt_value_status bt_value_string_set( + struct bt_value *string_obj, const char *val) +{ + BT_ASSERT_PRE_NON_NULL(string_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING); + BT_ASSERT_PRE_VALUE_HOT(string_obj, "Value object"); + g_string_assign(BT_VALUE_TO_STRING(string_obj)->gstr, val); + BT_LOGV("Set string value's raw value: value-addr=%p, raw-value-addr=%p", + string_obj, val); + return BT_VALUE_STATUS_OK; +} + +uint64_t bt_value_array_get_size(const struct bt_value *array_obj) +{ + BT_ASSERT_PRE_NON_NULL(array_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); + return (uint64_t) BT_VALUE_TO_ARRAY(array_obj)->garray->len; +} + +struct bt_value *bt_value_array_borrow_element_by_index( + struct bt_value *array_obj, uint64_t index) +{ + struct bt_value_array *typed_array_obj = + BT_VALUE_TO_ARRAY(array_obj); + + BT_ASSERT_PRE_NON_NULL(array_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); + BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index, + typed_array_obj->garray->len); + return g_ptr_array_index(typed_array_obj->garray, index); +} + +const struct bt_value *bt_value_array_borrow_element_by_index_const( + const struct bt_value *array_obj, + uint64_t index) +{ + return bt_value_array_borrow_element_by_index( + (void *) array_obj, index); +} + +enum bt_value_status bt_value_array_append_element( + struct bt_value *array_obj, + struct bt_value *element_obj) +{ + struct bt_value_array *typed_array_obj = + BT_VALUE_TO_ARRAY(array_obj); + + BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object"); + BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); + BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object"); + g_ptr_array_add(typed_array_obj->garray, element_obj); + bt_object_get_ref(element_obj); + BT_LOGV("Appended element to array value: array-value-addr=%p, " + "element-value-addr=%p, new-size=%u", + array_obj, element_obj, typed_array_obj->garray->len); + return BT_VALUE_STATUS_OK; +} + +enum bt_value_status bt_value_array_append_bool_element( + struct bt_value *array_obj, bt_bool val) +{ + enum bt_value_status ret; + struct bt_value *bool_obj = NULL; + + bool_obj = bt_value_bool_create_init(val); + ret = bt_value_array_append_element(array_obj, + (void *) bool_obj); + bt_object_put_ref(bool_obj); + return ret; +} + +enum bt_value_status bt_value_array_append_integer_element( + struct bt_value *array_obj, int64_t val) +{ + enum bt_value_status ret; + struct bt_value *integer_obj = NULL; + + integer_obj = bt_value_integer_create_init(val); + ret = bt_value_array_append_element(array_obj, + (void *) integer_obj); + bt_object_put_ref(integer_obj); + return ret; +} + +enum bt_value_status bt_value_array_append_real_element( + struct bt_value *array_obj, double val) +{ + enum bt_value_status ret; + struct bt_value *real_obj = NULL; + + real_obj = bt_value_real_create_init(val); + ret = bt_value_array_append_element(array_obj, + (void *) real_obj); + bt_object_put_ref(real_obj); + return ret; +} + +enum bt_value_status bt_value_array_append_string_element( + struct bt_value *array_obj, const char *val) +{ + enum bt_value_status ret; + struct bt_value *string_obj = NULL; + + string_obj = bt_value_string_create_init(val); + ret = bt_value_array_append_element(array_obj, + (void *) string_obj); + bt_object_put_ref(string_obj); + return ret; +} + +enum bt_value_status bt_value_array_append_empty_array_element( + struct bt_value *array_obj) +{ + enum bt_value_status ret; + struct bt_value *empty_array_obj = NULL; + + empty_array_obj = bt_value_array_create(); + ret = bt_value_array_append_element(array_obj, + (void *) empty_array_obj); + bt_object_put_ref(empty_array_obj); + return ret; +} + +enum bt_value_status bt_value_array_append_empty_map_element( + struct bt_value *array_obj) +{ + enum bt_value_status ret; + struct bt_value *map_obj = NULL; + + map_obj = bt_value_map_create(); + ret = bt_value_array_append_element(array_obj, + (void *) map_obj); + bt_object_put_ref(map_obj); + return ret; +} + +enum bt_value_status bt_value_array_set_element_by_index( + struct bt_value *array_obj, uint64_t index, + struct bt_value *element_obj) +{ + struct bt_value_array *typed_array_obj = + BT_VALUE_TO_ARRAY(array_obj); + + BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object"); + BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); + BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object"); + BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index, + typed_array_obj->garray->len); + bt_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index)); + g_ptr_array_index(typed_array_obj->garray, index) = element_obj; + bt_object_get_ref(element_obj); + BT_LOGV("Set array value's element: array-value-addr=%p, " + "index=%" PRIu64 ", element-value-addr=%p", + array_obj, index, element_obj); + return BT_VALUE_STATUS_OK; +} + +uint64_t bt_value_map_get_size(const struct bt_value *map_obj) +{ + BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); + return (uint64_t) g_hash_table_size(BT_VALUE_TO_MAP(map_obj)->ght); +} + +struct bt_value *bt_value_map_borrow_entry_value(struct bt_value *map_obj, + const char *key) +{ + BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); + BT_ASSERT_PRE_NON_NULL(key, "Key"); + BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); + return g_hash_table_lookup(BT_VALUE_TO_MAP(map_obj)->ght, + GUINT_TO_POINTER(g_quark_from_string(key))); +} + +const struct bt_value *bt_value_map_borrow_entry_value_const( + const struct bt_value *map_obj, const char *key) +{ + return bt_value_map_borrow_entry_value((void *) map_obj, key); +} + +bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, const char *key) +{ + BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); + BT_ASSERT_PRE_NON_NULL(key, "Key"); + BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); + return bt_g_hash_table_contains(BT_VALUE_TO_MAP(map_obj)->ght, + GUINT_TO_POINTER(g_quark_from_string(key))); +} + +enum bt_value_status bt_value_map_insert_entry( + struct bt_value *map_obj, + const char *key, struct bt_value *element_obj) +{ + BT_ASSERT_PRE_NON_NULL(map_obj, "Map value object"); + BT_ASSERT_PRE_NON_NULL(key, "Key"); + BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); + BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); + BT_ASSERT_PRE_VALUE_HOT(map_obj, "Map value object"); + g_hash_table_insert(BT_VALUE_TO_MAP(map_obj)->ght, + GUINT_TO_POINTER(g_quark_from_string(key)), element_obj); + bt_object_get_ref(element_obj); + BT_LOGV("Inserted value into map value: map-value-addr=%p, " + "key=\"%s\", element-value-addr=%p", + map_obj, key, element_obj); + return BT_VALUE_STATUS_OK; +} + +enum bt_value_status bt_value_map_insert_bool_entry( + struct bt_value *map_obj, const char *key, bt_bool val) +{ + enum bt_value_status ret; + struct bt_value *bool_obj = NULL; + + bool_obj = bt_value_bool_create_init(val); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) bool_obj); + bt_object_put_ref(bool_obj); + return ret; +} + +enum bt_value_status bt_value_map_insert_integer_entry( + struct bt_value *map_obj, const char *key, int64_t val) +{ + enum bt_value_status ret; + struct bt_value *integer_obj = NULL; + + integer_obj = bt_value_integer_create_init(val); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) integer_obj); + bt_object_put_ref(integer_obj); + return ret; +} + +enum bt_value_status bt_value_map_insert_real_entry( + struct bt_value *map_obj, const char *key, double val) +{ + enum bt_value_status ret; + struct bt_value *real_obj = NULL; + + real_obj = bt_value_real_create_init(val); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) real_obj); + bt_object_put_ref(real_obj); + return ret; +} + +enum bt_value_status bt_value_map_insert_string_entry( + struct bt_value *map_obj, const char *key, + const char *val) +{ + enum bt_value_status ret; + struct bt_value *string_obj = NULL; + + string_obj = bt_value_string_create_init(val); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) string_obj); + bt_object_put_ref(string_obj); + return ret; +} + +enum bt_value_status bt_value_map_insert_empty_array_entry( + struct bt_value *map_obj, const char *key) +{ + enum bt_value_status ret; + struct bt_value *array_obj = NULL; + + array_obj = bt_value_array_create(); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) array_obj); + bt_object_put_ref(array_obj); + return ret; +} + +enum bt_value_status bt_value_map_insert_empty_map_entry( + struct bt_value *map_obj, const char *key) +{ + enum bt_value_status ret; + struct bt_value *empty_map_obj = NULL; + + empty_map_obj = bt_value_map_create(); + ret = bt_value_map_insert_entry(map_obj, key, + (void *) empty_map_obj); + bt_object_put_ref(empty_map_obj); + return ret; +} + +enum bt_value_status bt_value_map_foreach_entry(struct bt_value *map_obj, + bt_value_map_foreach_entry_func func, void *data) +{ + enum bt_value_status ret = BT_VALUE_STATUS_OK; + gpointer key, element_obj; + GHashTableIter iter; + struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj); + + BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); + BT_ASSERT_PRE_NON_NULL(func, "Callback"); + BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); + g_hash_table_iter_init(&iter, typed_map_obj->ght); + + while (g_hash_table_iter_next(&iter, &key, &element_obj)) { + const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); + + if (!func(key_str, element_obj, data)) { + BT_LOGV("User canceled the loop: key=\"%s\", " + "value-addr=%p, data=%p", + key_str, element_obj, data); + ret = BT_VALUE_STATUS_CANCELED; + break; + } + } + + return ret; +} + +enum bt_value_status bt_value_map_foreach_entry_const( + const struct bt_value *map_obj, + bt_value_map_foreach_entry_const_func func, void *data) +{ + return bt_value_map_foreach_entry((void *) map_obj, + (bt_value_map_foreach_entry_func) func, data); +} + +struct extend_map_element_data { + struct bt_value *extended_obj; + enum bt_value_status status; +}; + +static +bt_bool extend_map_element(const char *key, + const struct bt_value *extension_obj_elem, void *data) +{ + bt_bool ret = BT_TRUE; + struct extend_map_element_data *extend_data = data; + struct bt_value *extension_obj_elem_copy = NULL; + + /* Copy object which is to replace the current one */ + extend_data->status = bt_value_copy(extension_obj_elem, + &extension_obj_elem_copy); + if (extend_data->status) { + BT_LOGE("Cannot copy map element: addr=%p", + extension_obj_elem); + goto error; + } + + BT_ASSERT(extension_obj_elem_copy); + + /* Replace in extended object */ + extend_data->status = bt_value_map_insert_entry( + extend_data->extended_obj, key, + (void *) extension_obj_elem_copy); + if (extend_data->status) { + BT_LOGE("Cannot replace value in extended value: key=\"%s\", " + "extended-value-addr=%p, element-value-addr=%p", + key, extend_data->extended_obj, + extension_obj_elem_copy); + goto error; + } + + goto end; + +error: + BT_ASSERT(extend_data->status != BT_VALUE_STATUS_OK); + ret = BT_FALSE; + +end: + BT_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy); + return ret; +} + +enum bt_value_status bt_value_map_extend( + const struct bt_value *base_map_obj, + const struct bt_value *extension_obj, + struct bt_value **extended_map_obj) +{ + struct extend_map_element_data extend_data = { + .extended_obj = NULL, + .status = BT_VALUE_STATUS_OK, + }; + + BT_ASSERT_PRE_NON_NULL(base_map_obj, "Base value object"); + BT_ASSERT_PRE_NON_NULL(extension_obj, "Extension value object"); + BT_ASSERT_PRE_NON_NULL(extended_map_obj, + "Extended value object (output)"); + BT_ASSERT_PRE_VALUE_IS_TYPE(base_map_obj, BT_VALUE_TYPE_MAP); + BT_ASSERT_PRE_VALUE_IS_TYPE(extension_obj, BT_VALUE_TYPE_MAP); + BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p", + base_map_obj, extension_obj); + *extended_map_obj = NULL; + + /* Create copy of base map object to start with */ + extend_data.status = bt_value_copy(base_map_obj, extended_map_obj); + if (extend_data.status) { + BT_LOGE("Cannot copy base value: base-value-addr=%p", + base_map_obj); + goto error; + } + + BT_ASSERT(extended_map_obj); + + /* + * For each key in the extension map object, replace this key + * in the copied map object. + */ + extend_data.extended_obj = *extended_map_obj; + + if (bt_value_map_foreach_entry_const(extension_obj, extend_map_element, + &extend_data)) { + BT_LOGE("Cannot iterate on the extension object's elements: " + "extension-value-addr=%p", extension_obj); + goto error; + } + + if (extend_data.status) { + BT_LOGE("Failed to successfully iterate on the extension object's elements: " + "extension-value-addr=%p", extension_obj); + goto error; + } + + BT_LOGD("Extended map value: extended-value-addr=%p", + *extended_map_obj); + goto end; + +error: + BT_OBJECT_PUT_REF_AND_RESET(*extended_map_obj); + *extended_map_obj = NULL; + +end: + return extend_data.status; +} + +enum bt_value_status bt_value_copy(const struct bt_value *object, + struct bt_value **copy_obj) +{ + enum bt_value_status status = BT_VALUE_STATUS_OK; + + BT_ASSERT_PRE_NON_NULL(object, "Value object"); + BT_ASSERT_PRE_NON_NULL(copy_obj, "Value object copy (output)"); + BT_LOGD("Copying value object: addr=%p", object); + *copy_obj = copy_funcs[object->type](object); + if (*copy_obj) { + BT_LOGD("Copied value object: copy-value-addr=%p", + copy_obj); + } else { + status = BT_VALUE_STATUS_NOMEM; + *copy_obj = NULL; + BT_LOGE_STR("Failed to copy value object."); + } + + return status; +} + +bt_bool bt_value_compare(const struct bt_value *object_a, + const struct bt_value *object_b) +{ + bt_bool ret = BT_FALSE; + + BT_ASSERT_PRE_NON_NULL(object_a, "Value object A"); + BT_ASSERT_PRE_NON_NULL(object_b, "Value object B"); + + if (object_a->type != object_b->type) { + BT_LOGV("Values are different: type mismatch: " + "value-a-addr=%p, value-b-addr=%p, " + "value-a-type=%s, value-b-type=%s", + object_a, object_b, + bt_common_value_type_string(object_a->type), + bt_common_value_type_string(object_b->type)); + goto end; + } + + ret = compare_funcs[object_a->type](object_a, object_b); + +end: + return ret; +} diff --git a/lib/values.c b/lib/values.c deleted file mode 100644 index c9be2254..00000000 --- a/lib/values.c +++ /dev/null @@ -1,1302 +0,0 @@ -/* - * Copyright (c) 2015 EfficiOS Inc. and Linux Foundation - * Copyright (c) 2015 Philippe Proulx - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#define BT_LOG_TAG "VALUES" -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define BT_VALUE_FROM_CONCRETE(_concrete) ((struct bt_value *) (_concrete)) -#define BT_VALUE_TO_BOOL(_base) ((struct bt_value_bool *) (_base)) -#define BT_VALUE_TO_INTEGER(_base) ((struct bt_value_integer *) (_base)) -#define BT_VALUE_TO_REAL(_base) ((struct bt_value_real *) (_base)) -#define BT_VALUE_TO_STRING(_base) ((struct bt_value_string *) (_base)) -#define BT_VALUE_TO_ARRAY(_base) ((struct bt_value_array *) (_base)) -#define BT_VALUE_TO_MAP(_base) ((struct bt_value_map *) (_base)) - -#define BT_ASSERT_PRE_VALUE_IS_TYPE(_value, _type) \ - BT_ASSERT_PRE(((struct bt_value *) (_value))->type == (_type), \ - "Value has the wrong type ID: expected-type=%s, " \ - "%![value-]+v", bt_common_value_type_string(_type), \ - (_value)) - -#define BT_ASSERT_PRE_VALUE_HOT(_value, _name) \ - BT_ASSERT_PRE_HOT(((struct bt_value *) (_value)), (_name), \ - ": %!+v", (_value)) - -#define BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(_index, _count) \ - BT_ASSERT_PRE((_index) < (_count), \ - "Index is out of bound: " \ - "index=%" PRIu64 ", count=%u", (_index), (_count)); - -struct bt_value { - struct bt_object base; - enum bt_value_type type; - bt_bool frozen; -}; - -static -void bt_value_null_instance_release_func(struct bt_object *obj) -{ - BT_LOGW("Releasing the null value singleton: addr=%p", obj); -} - -static -struct bt_value bt_value_null_instance = { - .base = { - .is_shared = true, - .ref_count = 1, - .release_func = bt_value_null_instance_release_func, - .spec_release_func = NULL, - .parent_is_owner_listener_func = NULL, - .parent = NULL, - }, - .type = BT_VALUE_TYPE_NULL, - .frozen = BT_TRUE, -}; - -struct bt_value *bt_value_null = &bt_value_null_instance; - -struct bt_value_bool { - struct bt_value base; - bt_bool value; -}; - -struct bt_value_integer { - struct bt_value base; - int64_t value; -}; - -struct bt_value_real { - struct bt_value base; - double value; -}; - -struct bt_value_string { - struct bt_value base; - GString *gstr; -}; - -struct bt_value_array { - struct bt_value base; - GPtrArray *garray; -}; - -struct bt_value_map { - struct bt_value base; - GHashTable *ght; -}; - -static -void bt_value_destroy(struct bt_object *obj); - -static -void bt_value_string_destroy(struct bt_value *object) -{ - g_string_free(BT_VALUE_TO_STRING(object)->gstr, TRUE); - BT_VALUE_TO_STRING(object)->gstr = NULL; -} - -static -void bt_value_array_destroy(struct bt_value *object) -{ - /* - * Pointer array's registered value destructor will take care - * of putting each contained object. - */ - g_ptr_array_free(BT_VALUE_TO_ARRAY(object)->garray, TRUE); - BT_VALUE_TO_ARRAY(object)->garray = NULL; -} - -static -void bt_value_map_destroy(struct bt_value *object) -{ - /* - * Hash table's registered value destructor will take care of - * putting each contained object. Keys are GQuarks and cannot - * be destroyed anyway. - */ - g_hash_table_destroy(BT_VALUE_TO_MAP(object)->ght); - BT_VALUE_TO_MAP(object)->ght = NULL; -} - -static -void (* const destroy_funcs[])(struct bt_value *) = { - [BT_VALUE_TYPE_NULL] = NULL, - [BT_VALUE_TYPE_BOOL] = NULL, - [BT_VALUE_TYPE_INTEGER] = NULL, - [BT_VALUE_TYPE_REAL] = NULL, - [BT_VALUE_TYPE_STRING] = bt_value_string_destroy, - [BT_VALUE_TYPE_ARRAY] = bt_value_array_destroy, - [BT_VALUE_TYPE_MAP] = bt_value_map_destroy, -}; - -static -struct bt_value *bt_value_null_copy(const struct bt_value *null_obj) -{ - return (void *) bt_value_null; -} - -static -struct bt_value *bt_value_bool_copy(const struct bt_value *bool_obj) -{ - return bt_value_bool_create_init( - BT_VALUE_TO_BOOL(bool_obj)->value); -} - -static -struct bt_value *bt_value_integer_copy( - const struct bt_value *integer_obj) -{ - return bt_value_integer_create_init( - BT_VALUE_TO_INTEGER(integer_obj)->value); -} - -static -struct bt_value *bt_value_real_copy(const struct bt_value *real_obj) -{ - return bt_value_real_create_init( - BT_VALUE_TO_REAL(real_obj)->value); -} - -static -struct bt_value *bt_value_string_copy(const struct bt_value *string_obj) -{ - return bt_value_string_create_init( - BT_VALUE_TO_STRING(string_obj)->gstr->str); -} - -static -struct bt_value *bt_value_array_copy(const struct bt_value *array_obj) -{ - int i; - int ret; - struct bt_value *copy_obj; - struct bt_value_array *typed_array_obj; - - BT_LOGD("Copying array value: addr=%p", array_obj); - typed_array_obj = BT_VALUE_TO_ARRAY(array_obj); - copy_obj = bt_value_array_create(); - if (!copy_obj) { - BT_LOGE_STR("Cannot create empty array value."); - goto end; - } - - for (i = 0; i < typed_array_obj->garray->len; ++i) { - struct bt_value *element_obj_copy = NULL; - const struct bt_value *element_obj = - bt_value_array_borrow_element_by_index_const( - array_obj, i); - - BT_ASSERT(element_obj); - BT_LOGD("Copying array value's element: element-addr=%p, " - "index=%d", element_obj, i); - ret = bt_value_copy(element_obj, &element_obj_copy); - if (ret) { - BT_LOGE("Cannot copy array value's element: " - "array-addr=%p, index=%d", - array_obj, i); - BT_OBJECT_PUT_REF_AND_RESET(copy_obj); - goto end; - } - - BT_ASSERT(element_obj_copy); - ret = bt_value_array_append_element(copy_obj, - (void *) element_obj_copy); - BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy); - if (ret) { - BT_LOGE("Cannot append to array value: addr=%p", - array_obj); - BT_OBJECT_PUT_REF_AND_RESET(copy_obj); - goto end; - } - } - - BT_LOGD("Copied array value: original-addr=%p, copy-addr=%p", - array_obj, copy_obj); - -end: - return copy_obj; -} - -static -struct bt_value *bt_value_map_copy(const struct bt_value *map_obj) -{ - int ret; - GHashTableIter iter; - gpointer key, element_obj; - struct bt_value *copy_obj; - struct bt_value *element_obj_copy = NULL; - struct bt_value_map *typed_map_obj; - - BT_LOGD("Copying map value: addr=%p", map_obj); - typed_map_obj = BT_VALUE_TO_MAP(map_obj); - copy_obj = bt_value_map_create(); - if (!copy_obj) { - goto end; - } - - g_hash_table_iter_init(&iter, typed_map_obj->ght); - - while (g_hash_table_iter_next(&iter, &key, &element_obj)) { - const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); - - BT_ASSERT(key_str); - BT_LOGD("Copying map value's element: element-addr=%p, " - "key=\"%s\"", element_obj, key_str); - ret = bt_value_copy(element_obj, &element_obj_copy); - if (ret) { - BT_LOGE("Cannot copy map value's element: " - "map-addr=%p, key=\"%s\"", - map_obj, key_str); - BT_OBJECT_PUT_REF_AND_RESET(copy_obj); - goto end; - } - - BT_ASSERT(element_obj_copy); - ret = bt_value_map_insert_entry(copy_obj, key_str, - (void *) element_obj_copy); - BT_OBJECT_PUT_REF_AND_RESET(element_obj_copy); - if (ret) { - BT_LOGE("Cannot insert into map value: addr=%p, key=\"%s\"", - map_obj, key_str); - BT_OBJECT_PUT_REF_AND_RESET(copy_obj); - goto end; - } - } - - BT_LOGD("Copied map value: addr=%p", map_obj); - -end: - return copy_obj; -} - -static -struct bt_value *(* const copy_funcs[])(const struct bt_value *) = { - [BT_VALUE_TYPE_NULL] = bt_value_null_copy, - [BT_VALUE_TYPE_BOOL] = bt_value_bool_copy, - [BT_VALUE_TYPE_INTEGER] = bt_value_integer_copy, - [BT_VALUE_TYPE_REAL] = bt_value_real_copy, - [BT_VALUE_TYPE_STRING] = bt_value_string_copy, - [BT_VALUE_TYPE_ARRAY] = bt_value_array_copy, - [BT_VALUE_TYPE_MAP] = bt_value_map_copy, -}; - -static -bt_bool bt_value_null_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - /* - * Always BT_TRUE since bt_value_compare() already checks if both - * object_a and object_b have the same type, and in the case of - * null value objects, they're always the same if it is so. - */ - return BT_TRUE; -} - -static -bt_bool bt_value_bool_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - if (BT_VALUE_TO_BOOL(object_a)->value != - BT_VALUE_TO_BOOL(object_b)->value) { - BT_LOGV("Boolean value objects are different: " - "bool-a-val=%d, bool-b-val=%d", - BT_VALUE_TO_BOOL(object_a)->value, - BT_VALUE_TO_BOOL(object_b)->value); - return BT_FALSE; - } - - return BT_TRUE; -} - -static -bt_bool bt_value_integer_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - if (BT_VALUE_TO_INTEGER(object_a)->value != - BT_VALUE_TO_INTEGER(object_b)->value) { - BT_LOGV("Integer value objects are different: " - "int-a-val=%" PRId64 ", int-b-val=%" PRId64, - BT_VALUE_TO_INTEGER(object_a)->value, - BT_VALUE_TO_INTEGER(object_b)->value); - return BT_FALSE; - } - - return BT_TRUE; -} - -static -bt_bool bt_value_real_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - if (BT_VALUE_TO_REAL(object_a)->value != - BT_VALUE_TO_REAL(object_b)->value) { - BT_LOGV("Real number value objects are different: " - "real-a-val=%f, real-b-val=%f", - BT_VALUE_TO_REAL(object_a)->value, - BT_VALUE_TO_REAL(object_b)->value); - return BT_FALSE; - } - - return BT_TRUE; -} - -static -bt_bool bt_value_string_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - if (strcmp(BT_VALUE_TO_STRING(object_a)->gstr->str, - BT_VALUE_TO_STRING(object_b)->gstr->str) != 0) { - BT_LOGV("String value objects are different: " - "string-a-val=\"%s\", string-b-val=\"%s\"", - BT_VALUE_TO_STRING(object_a)->gstr->str, - BT_VALUE_TO_STRING(object_b)->gstr->str); - return BT_FALSE; - } - - return BT_TRUE; -} - -static -bt_bool bt_value_array_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - int i; - bt_bool ret = BT_TRUE; - const struct bt_value_array *array_obj_a = - BT_VALUE_TO_ARRAY(object_a); - - if (bt_value_array_get_size(object_a) != - bt_value_array_get_size(object_b)) { - BT_LOGV("Array values are different: size mismatch " - "value-a-addr=%p, value-b-addr=%p, " - "value-a-size=%" PRId64 ", value-b-size=%" PRId64, - object_a, object_b, - bt_value_array_get_size(object_a), - bt_value_array_get_size(object_b)); - ret = BT_FALSE; - goto end; - } - - for (i = 0; i < array_obj_a->garray->len; ++i) { - const struct bt_value *element_obj_a; - const struct bt_value *element_obj_b; - - element_obj_a = bt_value_array_borrow_element_by_index_const( - object_a, i); - element_obj_b = bt_value_array_borrow_element_by_index_const( - object_b, i); - - if (!bt_value_compare(element_obj_a, element_obj_b)) { - BT_LOGV("Array values's elements are different: " - "value-a-addr=%p, value-b-addr=%p, index=%d", - element_obj_a, element_obj_b, i); - ret = BT_FALSE; - goto end; - } - } - -end: - return ret; -} - -static -bt_bool bt_value_map_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - bt_bool ret = BT_TRUE; - GHashTableIter iter; - gpointer key, element_obj_a; - const struct bt_value_map *map_obj_a = BT_VALUE_TO_MAP(object_a); - - if (bt_value_map_get_size(object_a) != - bt_value_map_get_size(object_b)) { - BT_LOGV("Map values are different: size mismatch " - "value-a-addr=%p, value-b-addr=%p, " - "value-a-size=%" PRId64 ", value-b-size=%" PRId64, - object_a, object_b, - bt_value_map_get_size(object_a), - bt_value_map_get_size(object_b)); - ret = BT_FALSE; - goto end; - } - - g_hash_table_iter_init(&iter, map_obj_a->ght); - - while (g_hash_table_iter_next(&iter, &key, &element_obj_a)) { - const struct bt_value *element_obj_b; - const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); - - element_obj_b = bt_value_map_borrow_entry_value_const(object_b, - key_str); - - if (!bt_value_compare(element_obj_a, element_obj_b)) { - BT_LOGV("Map values's elements are different: " - "value-a-addr=%p, value-b-addr=%p, key=\"%s\"", - element_obj_a, element_obj_b, key_str); - ret = BT_FALSE; - goto end; - } - } - -end: - return ret; -} - -static -bt_bool (* const compare_funcs[])(const struct bt_value *, - const struct bt_value *) = { - [BT_VALUE_TYPE_NULL] = bt_value_null_compare, - [BT_VALUE_TYPE_BOOL] = bt_value_bool_compare, - [BT_VALUE_TYPE_INTEGER] = bt_value_integer_compare, - [BT_VALUE_TYPE_REAL] = bt_value_real_compare, - [BT_VALUE_TYPE_STRING] = bt_value_string_compare, - [BT_VALUE_TYPE_ARRAY] = bt_value_array_compare, - [BT_VALUE_TYPE_MAP] = bt_value_map_compare, -}; - -static -void bt_value_null_freeze(struct bt_value *object) -{ -} - -static -void bt_value_generic_freeze(struct bt_value *object) -{ - object->frozen = BT_TRUE; -} - -static -void bt_value_array_freeze(struct bt_value *object) -{ - int i; - struct bt_value_array *typed_array_obj = - BT_VALUE_TO_ARRAY(object); - - for (i = 0; i < typed_array_obj->garray->len; ++i) { - bt_value_freeze(g_ptr_array_index(typed_array_obj->garray, i)); - } - - bt_value_generic_freeze(object); -} - -static -void bt_value_map_freeze(struct bt_value *object) -{ - GHashTableIter iter; - gpointer key, element_obj; - const struct bt_value_map *map_obj = BT_VALUE_TO_MAP(object); - - g_hash_table_iter_init(&iter, map_obj->ght); - - while (g_hash_table_iter_next(&iter, &key, &element_obj)) { - bt_value_freeze(element_obj); - } - - bt_value_generic_freeze(object); -} - -static -void (* const freeze_funcs[])(struct bt_value *) = { - [BT_VALUE_TYPE_NULL] = bt_value_null_freeze, - [BT_VALUE_TYPE_BOOL] = bt_value_generic_freeze, - [BT_VALUE_TYPE_INTEGER] = bt_value_generic_freeze, - [BT_VALUE_TYPE_REAL] = bt_value_generic_freeze, - [BT_VALUE_TYPE_STRING] = bt_value_generic_freeze, - [BT_VALUE_TYPE_ARRAY] = bt_value_array_freeze, - [BT_VALUE_TYPE_MAP] = bt_value_map_freeze, -}; - -static -void bt_value_destroy(struct bt_object *obj) -{ - struct bt_value *value; - - value = container_of(obj, struct bt_value, base); - BT_LOGD("Destroying value: addr=%p", value); - - if (bt_value_is_null(value)) { - BT_LOGD_STR("Not destroying the null value singleton."); - return; - } - - if (destroy_funcs[value->type]) { - destroy_funcs[value->type](value); - } - - g_free(value); -} - -BT_HIDDEN -enum bt_value_status _bt_value_freeze(const struct bt_value *c_object) -{ - const struct bt_value *object = (void *) c_object; - enum bt_value_status ret = BT_VALUE_STATUS_OK; - - BT_ASSERT(object); - - if (object->frozen) { - goto end; - } - - BT_LOGD("Freezing value: addr=%p", object); - freeze_funcs[object->type]((void *) object); - -end: - return ret; -} - -enum bt_value_type bt_value_get_type(const struct bt_value *object) -{ - BT_ASSERT_PRE_NON_NULL(object, "Value object"); - return object->type; -} - -static -struct bt_value bt_value_create_base(enum bt_value_type type) -{ - struct bt_value value; - - value.type = type; - value.frozen = BT_FALSE; - bt_object_init_shared(&value.base, bt_value_destroy); - return value; -} - -struct bt_value *bt_value_bool_create_init(bt_bool val) -{ - struct bt_value_bool *bool_obj; - - BT_LOGD("Creating boolean value object: val=%d", val); - bool_obj = g_new0(struct bt_value_bool, 1); - if (!bool_obj) { - BT_LOGE_STR("Failed to allocate one boolean value object."); - goto end; - } - - bool_obj->base = bt_value_create_base(BT_VALUE_TYPE_BOOL); - bool_obj->value = val; - BT_LOGD("Created boolean value object: addr=%p", bool_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(bool_obj); -} - -struct bt_value *bt_value_bool_create(void) -{ - return bt_value_bool_create_init(BT_FALSE); -} - -struct bt_value *bt_value_integer_create_init(int64_t val) -{ - struct bt_value_integer *integer_obj; - - BT_LOGD("Creating integer value object: val=%" PRId64, val); - integer_obj = g_new0(struct bt_value_integer, 1); - if (!integer_obj) { - BT_LOGE_STR("Failed to allocate one integer value object."); - goto end; - } - - integer_obj->base = bt_value_create_base(BT_VALUE_TYPE_INTEGER); - integer_obj->value = val; - BT_LOGD("Created integer value object: addr=%p", - integer_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(integer_obj); -} - -struct bt_value *bt_value_integer_create(void) -{ - return bt_value_integer_create_init(0); -} - -struct bt_value *bt_value_real_create_init(double val) -{ - struct bt_value_real *real_obj; - - BT_LOGD("Creating real number value object: val=%f", val); - real_obj = g_new0(struct bt_value_real, 1); - if (!real_obj) { - BT_LOGE_STR("Failed to allocate one real number value object."); - goto end; - } - - real_obj->base = bt_value_create_base(BT_VALUE_TYPE_REAL); - real_obj->value = val; - BT_LOGD("Created real number value object: addr=%p", - real_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(real_obj); -} - -struct bt_value *bt_value_real_create(void) -{ - return bt_value_real_create_init(0.); -} - -struct bt_value *bt_value_string_create_init(const char *val) -{ - struct bt_value_string *string_obj = NULL; - - if (!val) { - BT_LOGW_STR("Invalid parameter: value is NULL."); - goto end; - } - - BT_LOGD("Creating string value object: val-len=%zu", strlen(val)); - string_obj = g_new0(struct bt_value_string, 1); - if (!string_obj) { - BT_LOGE_STR("Failed to allocate one string object."); - goto end; - } - - string_obj->base = bt_value_create_base(BT_VALUE_TYPE_STRING); - string_obj->gstr = g_string_new(val); - if (!string_obj->gstr) { - BT_LOGE_STR("Failed to allocate a GString."); - g_free(string_obj); - string_obj = NULL; - goto end; - } - - BT_LOGD("Created string value object: addr=%p", - string_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(string_obj); -} - -struct bt_value *bt_value_string_create(void) -{ - return bt_value_string_create_init(""); -} - -struct bt_value *bt_value_array_create(void) -{ - struct bt_value_array *array_obj; - - BT_LOGD_STR("Creating empty array value object."); - array_obj = g_new0(struct bt_value_array, 1); - if (!array_obj) { - BT_LOGE_STR("Failed to allocate one array object."); - goto end; - } - - array_obj->base = bt_value_create_base(BT_VALUE_TYPE_ARRAY); - array_obj->garray = bt_g_ptr_array_new_full(0, - (GDestroyNotify) bt_object_put_ref); - if (!array_obj->garray) { - BT_LOGE_STR("Failed to allocate a GPtrArray."); - g_free(array_obj); - array_obj = NULL; - goto end; - } - - BT_LOGD("Created array value object: addr=%p", - array_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(array_obj); -} - -struct bt_value *bt_value_map_create(void) -{ - struct bt_value_map *map_obj; - - BT_LOGD_STR("Creating empty map value object."); - map_obj = g_new0(struct bt_value_map, 1); - if (!map_obj) { - BT_LOGE_STR("Failed to allocate one map object."); - goto end; - } - - map_obj->base = bt_value_create_base(BT_VALUE_TYPE_MAP); - map_obj->ght = g_hash_table_new_full(g_direct_hash, g_direct_equal, - NULL, (GDestroyNotify) bt_object_put_ref); - if (!map_obj->ght) { - BT_LOGE_STR("Failed to allocate a GHashTable."); - g_free(map_obj); - map_obj = NULL; - goto end; - } - - BT_LOGD("Created map value object: addr=%p", - map_obj); - -end: - return (void *) BT_VALUE_FROM_CONCRETE(map_obj); -} - -bt_bool bt_value_bool_get(const struct bt_value *bool_obj) -{ - BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL); - return BT_VALUE_TO_BOOL(bool_obj)->value; -} - -void bt_value_bool_set(struct bt_value *bool_obj, bt_bool val) -{ - BT_ASSERT_PRE_NON_NULL(bool_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(bool_obj, BT_VALUE_TYPE_BOOL); - BT_ASSERT_PRE_VALUE_HOT(bool_obj, "Value object"); - BT_VALUE_TO_BOOL(bool_obj)->value = val; - BT_LOGV("Set boolean value's raw value: value-addr=%p, value=%d", - bool_obj, val); -} - -int64_t bt_value_integer_get(const struct bt_value *integer_obj) -{ - BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER); - return BT_VALUE_TO_INTEGER(integer_obj)->value; -} - -void bt_value_integer_set(struct bt_value *integer_obj, - int64_t val) -{ - BT_ASSERT_PRE_NON_NULL(integer_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(integer_obj, BT_VALUE_TYPE_INTEGER); - BT_ASSERT_PRE_VALUE_HOT(integer_obj, "Value object"); - BT_VALUE_TO_INTEGER(integer_obj)->value = val; - BT_LOGV("Set integer value's raw value: value-addr=%p, value=%" PRId64, - integer_obj, val); -} - -double bt_value_real_get(const struct bt_value *real_obj) -{ - BT_ASSERT_PRE_NON_NULL(real_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL); - return BT_VALUE_TO_REAL(real_obj)->value; -} - -void bt_value_real_set(struct bt_value *real_obj, double val) -{ - BT_ASSERT_PRE_NON_NULL(real_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(real_obj, BT_VALUE_TYPE_REAL); - BT_ASSERT_PRE_VALUE_HOT(real_obj, "Value object"); - BT_VALUE_TO_REAL(real_obj)->value = val; - BT_LOGV("Set real number value's raw value: value-addr=%p, value=%f", - real_obj, val); -} - -const char *bt_value_string_get(const struct bt_value *string_obj) -{ - BT_ASSERT_PRE_NON_NULL(string_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING); - return BT_VALUE_TO_STRING(string_obj)->gstr->str; -} - -enum bt_value_status bt_value_string_set( - struct bt_value *string_obj, const char *val) -{ - BT_ASSERT_PRE_NON_NULL(string_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(string_obj, BT_VALUE_TYPE_STRING); - BT_ASSERT_PRE_VALUE_HOT(string_obj, "Value object"); - g_string_assign(BT_VALUE_TO_STRING(string_obj)->gstr, val); - BT_LOGV("Set string value's raw value: value-addr=%p, raw-value-addr=%p", - string_obj, val); - return BT_VALUE_STATUS_OK; -} - -uint64_t bt_value_array_get_size(const struct bt_value *array_obj) -{ - BT_ASSERT_PRE_NON_NULL(array_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); - return (uint64_t) BT_VALUE_TO_ARRAY(array_obj)->garray->len; -} - -struct bt_value *bt_value_array_borrow_element_by_index( - struct bt_value *array_obj, uint64_t index) -{ - struct bt_value_array *typed_array_obj = - BT_VALUE_TO_ARRAY(array_obj); - - BT_ASSERT_PRE_NON_NULL(array_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); - BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index, - typed_array_obj->garray->len); - return g_ptr_array_index(typed_array_obj->garray, index); -} - -const struct bt_value *bt_value_array_borrow_element_by_index_const( - const struct bt_value *array_obj, - uint64_t index) -{ - return bt_value_array_borrow_element_by_index( - (void *) array_obj, index); -} - -enum bt_value_status bt_value_array_append_element( - struct bt_value *array_obj, - struct bt_value *element_obj) -{ - struct bt_value_array *typed_array_obj = - BT_VALUE_TO_ARRAY(array_obj); - - BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object"); - BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); - BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object"); - g_ptr_array_add(typed_array_obj->garray, element_obj); - bt_object_get_ref(element_obj); - BT_LOGV("Appended element to array value: array-value-addr=%p, " - "element-value-addr=%p, new-size=%u", - array_obj, element_obj, typed_array_obj->garray->len); - return BT_VALUE_STATUS_OK; -} - -enum bt_value_status bt_value_array_append_bool_element( - struct bt_value *array_obj, bt_bool val) -{ - enum bt_value_status ret; - struct bt_value *bool_obj = NULL; - - bool_obj = bt_value_bool_create_init(val); - ret = bt_value_array_append_element(array_obj, - (void *) bool_obj); - bt_object_put_ref(bool_obj); - return ret; -} - -enum bt_value_status bt_value_array_append_integer_element( - struct bt_value *array_obj, int64_t val) -{ - enum bt_value_status ret; - struct bt_value *integer_obj = NULL; - - integer_obj = bt_value_integer_create_init(val); - ret = bt_value_array_append_element(array_obj, - (void *) integer_obj); - bt_object_put_ref(integer_obj); - return ret; -} - -enum bt_value_status bt_value_array_append_real_element( - struct bt_value *array_obj, double val) -{ - enum bt_value_status ret; - struct bt_value *real_obj = NULL; - - real_obj = bt_value_real_create_init(val); - ret = bt_value_array_append_element(array_obj, - (void *) real_obj); - bt_object_put_ref(real_obj); - return ret; -} - -enum bt_value_status bt_value_array_append_string_element( - struct bt_value *array_obj, const char *val) -{ - enum bt_value_status ret; - struct bt_value *string_obj = NULL; - - string_obj = bt_value_string_create_init(val); - ret = bt_value_array_append_element(array_obj, - (void *) string_obj); - bt_object_put_ref(string_obj); - return ret; -} - -enum bt_value_status bt_value_array_append_empty_array_element( - struct bt_value *array_obj) -{ - enum bt_value_status ret; - struct bt_value *empty_array_obj = NULL; - - empty_array_obj = bt_value_array_create(); - ret = bt_value_array_append_element(array_obj, - (void *) empty_array_obj); - bt_object_put_ref(empty_array_obj); - return ret; -} - -enum bt_value_status bt_value_array_append_empty_map_element( - struct bt_value *array_obj) -{ - enum bt_value_status ret; - struct bt_value *map_obj = NULL; - - map_obj = bt_value_map_create(); - ret = bt_value_array_append_element(array_obj, - (void *) map_obj); - bt_object_put_ref(map_obj); - return ret; -} - -enum bt_value_status bt_value_array_set_element_by_index( - struct bt_value *array_obj, uint64_t index, - struct bt_value *element_obj) -{ - struct bt_value_array *typed_array_obj = - BT_VALUE_TO_ARRAY(array_obj); - - BT_ASSERT_PRE_NON_NULL(array_obj, "Array value object"); - BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(array_obj, BT_VALUE_TYPE_ARRAY); - BT_ASSERT_PRE_VALUE_HOT(array_obj, "Array value object"); - BT_ASSERT_PRE_VALUE_INDEX_IN_BOUNDS(index, - typed_array_obj->garray->len); - bt_object_put_ref(g_ptr_array_index(typed_array_obj->garray, index)); - g_ptr_array_index(typed_array_obj->garray, index) = element_obj; - bt_object_get_ref(element_obj); - BT_LOGV("Set array value's element: array-value-addr=%p, " - "index=%" PRIu64 ", element-value-addr=%p", - array_obj, index, element_obj); - return BT_VALUE_STATUS_OK; -} - -uint64_t bt_value_map_get_size(const struct bt_value *map_obj) -{ - BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); - return (uint64_t) g_hash_table_size(BT_VALUE_TO_MAP(map_obj)->ght); -} - -struct bt_value *bt_value_map_borrow_entry_value(struct bt_value *map_obj, - const char *key) -{ - BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); - BT_ASSERT_PRE_NON_NULL(key, "Key"); - BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); - return g_hash_table_lookup(BT_VALUE_TO_MAP(map_obj)->ght, - GUINT_TO_POINTER(g_quark_from_string(key))); -} - -const struct bt_value *bt_value_map_borrow_entry_value_const( - const struct bt_value *map_obj, const char *key) -{ - return bt_value_map_borrow_entry_value((void *) map_obj, key); -} - -bt_bool bt_value_map_has_entry(const struct bt_value *map_obj, const char *key) -{ - BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); - BT_ASSERT_PRE_NON_NULL(key, "Key"); - BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); - return bt_g_hash_table_contains(BT_VALUE_TO_MAP(map_obj)->ght, - GUINT_TO_POINTER(g_quark_from_string(key))); -} - -enum bt_value_status bt_value_map_insert_entry( - struct bt_value *map_obj, - const char *key, struct bt_value *element_obj) -{ - BT_ASSERT_PRE_NON_NULL(map_obj, "Map value object"); - BT_ASSERT_PRE_NON_NULL(key, "Key"); - BT_ASSERT_PRE_NON_NULL(element_obj, "Element value object"); - BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); - BT_ASSERT_PRE_VALUE_HOT(map_obj, "Map value object"); - g_hash_table_insert(BT_VALUE_TO_MAP(map_obj)->ght, - GUINT_TO_POINTER(g_quark_from_string(key)), element_obj); - bt_object_get_ref(element_obj); - BT_LOGV("Inserted value into map value: map-value-addr=%p, " - "key=\"%s\", element-value-addr=%p", - map_obj, key, element_obj); - return BT_VALUE_STATUS_OK; -} - -enum bt_value_status bt_value_map_insert_bool_entry( - struct bt_value *map_obj, const char *key, bt_bool val) -{ - enum bt_value_status ret; - struct bt_value *bool_obj = NULL; - - bool_obj = bt_value_bool_create_init(val); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) bool_obj); - bt_object_put_ref(bool_obj); - return ret; -} - -enum bt_value_status bt_value_map_insert_integer_entry( - struct bt_value *map_obj, const char *key, int64_t val) -{ - enum bt_value_status ret; - struct bt_value *integer_obj = NULL; - - integer_obj = bt_value_integer_create_init(val); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) integer_obj); - bt_object_put_ref(integer_obj); - return ret; -} - -enum bt_value_status bt_value_map_insert_real_entry( - struct bt_value *map_obj, const char *key, double val) -{ - enum bt_value_status ret; - struct bt_value *real_obj = NULL; - - real_obj = bt_value_real_create_init(val); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) real_obj); - bt_object_put_ref(real_obj); - return ret; -} - -enum bt_value_status bt_value_map_insert_string_entry( - struct bt_value *map_obj, const char *key, - const char *val) -{ - enum bt_value_status ret; - struct bt_value *string_obj = NULL; - - string_obj = bt_value_string_create_init(val); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) string_obj); - bt_object_put_ref(string_obj); - return ret; -} - -enum bt_value_status bt_value_map_insert_empty_array_entry( - struct bt_value *map_obj, const char *key) -{ - enum bt_value_status ret; - struct bt_value *array_obj = NULL; - - array_obj = bt_value_array_create(); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) array_obj); - bt_object_put_ref(array_obj); - return ret; -} - -enum bt_value_status bt_value_map_insert_empty_map_entry( - struct bt_value *map_obj, const char *key) -{ - enum bt_value_status ret; - struct bt_value *empty_map_obj = NULL; - - empty_map_obj = bt_value_map_create(); - ret = bt_value_map_insert_entry(map_obj, key, - (void *) empty_map_obj); - bt_object_put_ref(empty_map_obj); - return ret; -} - -enum bt_value_status bt_value_map_foreach_entry(struct bt_value *map_obj, - bt_value_map_foreach_entry_func func, void *data) -{ - enum bt_value_status ret = BT_VALUE_STATUS_OK; - gpointer key, element_obj; - GHashTableIter iter; - struct bt_value_map *typed_map_obj = BT_VALUE_TO_MAP(map_obj); - - BT_ASSERT_PRE_NON_NULL(map_obj, "Value object"); - BT_ASSERT_PRE_NON_NULL(func, "Callback"); - BT_ASSERT_PRE_VALUE_IS_TYPE(map_obj, BT_VALUE_TYPE_MAP); - g_hash_table_iter_init(&iter, typed_map_obj->ght); - - while (g_hash_table_iter_next(&iter, &key, &element_obj)) { - const char *key_str = g_quark_to_string(GPOINTER_TO_UINT(key)); - - if (!func(key_str, element_obj, data)) { - BT_LOGV("User canceled the loop: key=\"%s\", " - "value-addr=%p, data=%p", - key_str, element_obj, data); - ret = BT_VALUE_STATUS_CANCELED; - break; - } - } - - return ret; -} - -enum bt_value_status bt_value_map_foreach_entry_const( - const struct bt_value *map_obj, - bt_value_map_foreach_entry_const_func func, void *data) -{ - return bt_value_map_foreach_entry((void *) map_obj, - (bt_value_map_foreach_entry_func) func, data); -} - -struct extend_map_element_data { - struct bt_value *extended_obj; - enum bt_value_status status; -}; - -static -bt_bool extend_map_element(const char *key, - const struct bt_value *extension_obj_elem, void *data) -{ - bt_bool ret = BT_TRUE; - struct extend_map_element_data *extend_data = data; - struct bt_value *extension_obj_elem_copy = NULL; - - /* Copy object which is to replace the current one */ - extend_data->status = bt_value_copy(extension_obj_elem, - &extension_obj_elem_copy); - if (extend_data->status) { - BT_LOGE("Cannot copy map element: addr=%p", - extension_obj_elem); - goto error; - } - - BT_ASSERT(extension_obj_elem_copy); - - /* Replace in extended object */ - extend_data->status = bt_value_map_insert_entry( - extend_data->extended_obj, key, - (void *) extension_obj_elem_copy); - if (extend_data->status) { - BT_LOGE("Cannot replace value in extended value: key=\"%s\", " - "extended-value-addr=%p, element-value-addr=%p", - key, extend_data->extended_obj, - extension_obj_elem_copy); - goto error; - } - - goto end; - -error: - BT_ASSERT(extend_data->status != BT_VALUE_STATUS_OK); - ret = BT_FALSE; - -end: - BT_OBJECT_PUT_REF_AND_RESET(extension_obj_elem_copy); - return ret; -} - -enum bt_value_status bt_value_map_extend( - const struct bt_value *base_map_obj, - const struct bt_value *extension_obj, - struct bt_value **extended_map_obj) -{ - struct extend_map_element_data extend_data = { - .extended_obj = NULL, - .status = BT_VALUE_STATUS_OK, - }; - - BT_ASSERT_PRE_NON_NULL(base_map_obj, "Base value object"); - BT_ASSERT_PRE_NON_NULL(extension_obj, "Extension value object"); - BT_ASSERT_PRE_NON_NULL(extended_map_obj, - "Extended value object (output)"); - BT_ASSERT_PRE_VALUE_IS_TYPE(base_map_obj, BT_VALUE_TYPE_MAP); - BT_ASSERT_PRE_VALUE_IS_TYPE(extension_obj, BT_VALUE_TYPE_MAP); - BT_LOGD("Extending map value: base-value-addr=%p, extension-value-addr=%p", - base_map_obj, extension_obj); - *extended_map_obj = NULL; - - /* Create copy of base map object to start with */ - extend_data.status = bt_value_copy(base_map_obj, extended_map_obj); - if (extend_data.status) { - BT_LOGE("Cannot copy base value: base-value-addr=%p", - base_map_obj); - goto error; - } - - BT_ASSERT(extended_map_obj); - - /* - * For each key in the extension map object, replace this key - * in the copied map object. - */ - extend_data.extended_obj = *extended_map_obj; - - if (bt_value_map_foreach_entry_const(extension_obj, extend_map_element, - &extend_data)) { - BT_LOGE("Cannot iterate on the extension object's elements: " - "extension-value-addr=%p", extension_obj); - goto error; - } - - if (extend_data.status) { - BT_LOGE("Failed to successfully iterate on the extension object's elements: " - "extension-value-addr=%p", extension_obj); - goto error; - } - - BT_LOGD("Extended map value: extended-value-addr=%p", - *extended_map_obj); - goto end; - -error: - BT_OBJECT_PUT_REF_AND_RESET(*extended_map_obj); - *extended_map_obj = NULL; - -end: - return extend_data.status; -} - -enum bt_value_status bt_value_copy(const struct bt_value *object, - struct bt_value **copy_obj) -{ - enum bt_value_status status = BT_VALUE_STATUS_OK; - - BT_ASSERT_PRE_NON_NULL(object, "Value object"); - BT_ASSERT_PRE_NON_NULL(copy_obj, "Value object copy (output)"); - BT_LOGD("Copying value object: addr=%p", object); - *copy_obj = copy_funcs[object->type](object); - if (*copy_obj) { - BT_LOGD("Copied value object: copy-value-addr=%p", - copy_obj); - } else { - status = BT_VALUE_STATUS_NOMEM; - *copy_obj = NULL; - BT_LOGE_STR("Failed to copy value object."); - } - - return status; -} - -bt_bool bt_value_compare(const struct bt_value *object_a, - const struct bt_value *object_b) -{ - bt_bool ret = BT_FALSE; - - BT_ASSERT_PRE_NON_NULL(object_a, "Value object A"); - BT_ASSERT_PRE_NON_NULL(object_b, "Value object B"); - - if (object_a->type != object_b->type) { - BT_LOGV("Values are different: type mismatch: " - "value-a-addr=%p, value-b-addr=%p, " - "value-a-type=%s, value-b-type=%s", - object_a, object_b, - bt_common_value_type_string(object_a->type), - bt_common_value_type_string(object_b->type)); - goto end; - } - - ret = compare_funcs[object_a->type](object_a, object_b); - -end: - return ret; -} diff --git a/plugins/libctfcopytrace/clock-fields.c b/plugins/libctfcopytrace/clock-fields.c index 1e28c899..5f7c7246 100644 --- a/plugins/libctfcopytrace/clock-fields.c +++ b/plugins/libctfcopytrace/clock-fields.c @@ -33,7 +33,7 @@ #include #include -#include "clock-fields.h" +#include "clock-field.h" static int find_update_struct_clock_fields(FILE *err, struct bt_field_type *type, diff --git a/plugins/libctfcopytrace/ctfcopytrace.c b/plugins/libctfcopytrace/ctfcopytrace.c index fc3f8592..62ce7425 100644 --- a/plugins/libctfcopytrace/ctfcopytrace.c +++ b/plugins/libctfcopytrace/ctfcopytrace.c @@ -33,7 +33,7 @@ #include #include "ctfcopytrace.h" -#include "clock-fields.h" +#include "clock-field.h" BT_HIDDEN const struct bt_clock_class *ctf_copy_clock_class(FILE *err, diff --git a/plugins/text/dmesg/dmesg.c b/plugins/text/dmesg/dmesg.c index 4da898bd..c317a7b0 100644 --- a/plugins/text/dmesg/dmesg.c +++ b/plugins/text/dmesg/dmesg.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/utils/muxer/muxer.c b/plugins/utils/muxer/muxer.c index c75ed207..1d273beb 100644 --- a/plugins/utils/muxer/muxer.c +++ b/plugins/utils/muxer/muxer.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/plugins/utils/trimmer/iterator.c b/plugins/utils/trimmer/iterator.c index c0503d25..29e9951b 100644 --- a/plugins/utils/trimmer/iterator.c +++ b/plugins/utils/trimmer/iterator.c @@ -137,7 +137,7 @@ int update_lazy_bound(struct trimmer_bound *bound, const char *name, } tm.tm_sec = bound->lazy_values.ss; tm.tm_min = bound->lazy_values.mm; - tm.tm_hour = bound->lazy_values.hh; + tm.tm_hour = bound->lazy_value.hh; timeval = bt_timegm(&tm); if (timeval < 0) { BT_LOGE("Failure in bt_timegm(), incorrectly formatted %s timestamp", @@ -152,7 +152,7 @@ int update_lazy_bound(struct trimmer_bound *bound, const char *name, } tm.tm_sec = bound->lazy_values.ss; tm.tm_min = bound->lazy_values.mm; - tm.tm_hour = bound->lazy_values.hh; + tm.tm_hour = bound->lazy_value.hh; timeval = mktime(&tm); if (timeval < 0) { BT_LOGE("Failure in mktime(), incorrectly formatted %s timestamp", diff --git a/plugins/utils/trimmer/trimmer.c b/plugins/utils/trimmer/trimmer.c index ba4053f9..21dc871a 100644 --- a/plugins/utils/trimmer/trimmer.c +++ b/plugins/utils/trimmer/trimmer.c @@ -135,7 +135,7 @@ int timestamp_from_param(const char *param_name, struct bt_value *param, if (ret == 4) { if (!trimmer->date) { /* We don't know which day until we get an event. */ - result_bound->lazy_values.hh = hh; + result_bound->lazy_value.hh = hh; result_bound->lazy_values.mm = mm; result_bound->lazy_values.ss = ss; result_bound->lazy_values.ns = ns; @@ -227,7 +227,7 @@ int timestamp_from_param(const char *param_name, struct bt_value *param, if (ret == 3) { if (!trimmer->date) { /* We don't know which day until we get an event. */ - result_bound->lazy_values.hh = hh; + result_bound->lazy_value.hh = hh; result_bound->lazy_values.mm = mm; result_bound->lazy_values.ss = ss; result_bound->lazy_values.ns = 0; diff --git a/tests/lib/test_ctf_writer.c b/tests/lib/test_ctf_writer.c index a893188d..c3608701 100644 --- a/tests/lib/test_ctf_writer.c +++ b/tests/lib/test_ctf_writer.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include #include #include