BT_FIELD_CLASS_TYPE_STRUCTURE,
BT_FIELD_CLASS_TYPE_STATIC_ARRAY,
BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY,
+ BT_FIELD_CLASS_TYPE_OPTION,
BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR,
BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR,
BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR,
bt_field_class_array_dynamic_borrow_length_field_path_const(
const bt_field_class *field_class);
+extern const bt_field_class *
+bt_field_class_option_borrow_field_class_const(
+ const bt_field_class *field_class);
+
+extern const bt_field_path *
+bt_field_class_option_borrow_selector_field_path_const(
+ const bt_field_class *field_class);
+
extern uint64_t bt_field_class_variant_get_option_count(
const bt_field_class *field_class);
extern bt_field_class *bt_field_class_array_borrow_element_field_class(
bt_field_class *field_class);
+extern bt_field_class *bt_field_class_option_create(
+ bt_trace_class *trace_class,
+ bt_field_class *content_field_class,
+ bt_field_class *selector_field_class);
+
extern bt_field_class *bt_field_class_variant_create(
bt_trace_class *trace_class,
bt_field_class *selector_field_class);
bt_field_array_borrow_element_field_by_index_const(
const bt_field *field, uint64_t index);
+extern const bt_field *
+bt_field_option_borrow_field_const(const bt_field *field);
+
extern uint64_t bt_field_variant_get_selected_option_field_index(
const bt_field *field);
typedef enum bt_field_path_item_type {
BT_FIELD_PATH_ITEM_TYPE_INDEX,
BT_FIELD_PATH_ITEM_TYPE_CURRENT_ARRAY_ELEMENT,
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT,
} bt_field_path_item_type;
typedef enum bt_field_path_scope {
bt_field_array_dynamic_set_length(
bt_field *field, uint64_t length);
+extern void bt_field_option_set_has_field(bt_field *field, bt_bool has_field);
+
+extern bt_field *bt_field_option_borrow_field(bt_field *field);
+
typedef enum bt_field_variant_select_option_field_by_index_status {
BT_FIELD_VARIANT_SELECT_OPTION_FIELD_STATUS_OK = __BT_FUNC_STATUS_OK,
} bt_field_variant_select_option_field_by_index_status;
break;
}
+ case BT_FIELD_CLASS_TYPE_OPTION:
+ {
+ const struct bt_field_class_option *opt_fc =
+ (const void *) field_class;
+
+ BUF_APPEND(", %scontent-fc-addr=%p, %scontent-fc-type=%s",
+ PRFIELD(opt_fc->content_fc),
+ PRFIELD(bt_common_field_class_type_string(opt_fc->content_fc->type)));
+
+ if (opt_fc->selector_fc) {
+ SET_TMP_PREFIX("selector-fc-");
+ format_field_class(buf_ch, extended, tmp_prefix,
+ opt_fc->selector_fc);
+ }
+
+ if (opt_fc->selector_field_path) {
+ SET_TMP_PREFIX("selector-field-path-");
+ format_field_path(buf_ch, extended, tmp_prefix,
+ opt_fc->selector_field_path);
+ }
+
+ break;
+ }
case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR:
return named_fc->fc;
}
+static
+void destroy_option_field_class(struct bt_object *obj)
+{
+ struct bt_field_class_option *fc = (void *) obj;
+
+ BT_ASSERT(fc);
+ BT_LIB_LOGD("Destroying option field class object: %!+F", fc);
+ BT_LOGD_STR("Putting content field class.");
+ BT_OBJECT_PUT_REF_AND_RESET(fc->content_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_option_create(bt_trace_class *trace_class,
+ bt_field_class *content_fc, bt_field_class *selector_fc)
+{
+ struct bt_field_class_option *opt_fc = NULL;
+
+ BT_ASSERT_PRE_NON_NULL(trace_class, "Trace class");
+ BT_ASSERT_PRE_NON_NULL(content_fc, "Content field class");
+ BT_LIB_LOGD("Creating option field class: "
+ "%![content-fc-]+F, %![sel-fc-]+F", content_fc, selector_fc);
+ opt_fc = g_new0(struct bt_field_class_option, 1);
+ if (!opt_fc) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one option field class.");
+ goto error;
+ }
+
+ init_field_class((void *) opt_fc, BT_FIELD_CLASS_TYPE_OPTION,
+ destroy_option_field_class);
+ opt_fc->content_fc = content_fc;
+ bt_object_get_no_null_check(opt_fc->content_fc);
+ bt_field_class_freeze(opt_fc->content_fc);
+
+ if (selector_fc) {
+ BT_ASSERT_PRE_FC_HAS_ID(selector_fc, BT_FIELD_CLASS_TYPE_BOOL,
+ "Selector field class");
+ opt_fc->selector_fc = selector_fc;
+ bt_object_get_no_null_check(opt_fc->selector_fc);
+ bt_field_class_freeze(selector_fc);
+ }
+
+ BT_LIB_LOGD("Created option field class object: "
+ "%![opt-fc-]+F, %![sel-fc-]+F", opt_fc, selector_fc);
+ goto end;
+
+error:
+ BT_OBJECT_PUT_REF_AND_RESET(opt_fc);
+
+end:
+ return (void *) opt_fc;
+}
+
+const struct bt_field_class *bt_field_class_option_borrow_field_class_const(
+ const struct bt_field_class *fc)
+{
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
+ "Field class");
+ return opt_fc->content_fc;
+}
+
+const struct bt_field_path *
+bt_field_class_option_borrow_selector_field_path_const(
+ const struct bt_field_class *fc)
+{
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ BT_ASSERT_PRE_NON_NULL(fc, "Field class");
+ BT_ASSERT_PRE_DEV_FC_HAS_ID(fc, BT_FIELD_CLASS_TYPE_OPTION,
+ "Field class");
+ return opt_fc->selector_field_path;
+}
+
static
void finalize_variant_field_class(struct bt_field_class_variant *var_fc)
{
struct bt_field_class_array_dynamic {
struct bt_field_class_array common;
- /* Weak: never dereferenced, only use to find it elsewhere */
+ /* Owned by this */
struct bt_field_class *length_fc;
/* Owned by this */
struct bt_field_path *length_field_path;
};
+struct bt_field_class_option {
+ struct bt_field_class common;
+
+ /* Owned by this */
+ struct bt_field_class *content_fc;
+
+ /* Owned by this */
+ struct bt_field_class *selector_fc;
+
+ /* Owned by this */
+ struct bt_field_path *selector_field_path;
+};
+
/* Variant FC (with selector) option: named field class + range set */
struct bt_field_class_variant_with_selector_option {
struct bt_named_field_class common;
static
void reset_structure_field(struct bt_field *field);
+static
+void reset_option_field(struct bt_field *field);
+
static
void reset_variant_field(struct bt_field *field);
static
void set_structure_field_is_frozen(struct bt_field *field, bool is_frozen);
+static
+void set_option_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 structure_field_is_set(const struct bt_field *field);
+static
+bool option_field_is_set(const struct bt_field *field);
+
static
bool variant_field_is_set(const struct bt_field *field);
.reset = reset_array_field,
};
+static
+struct bt_field_methods option_field_methods = {
+ .set_is_frozen = set_option_field_is_frozen,
+ .is_set = option_field_is_set,
+ .reset = reset_option_field,
+};
+
static
struct bt_field_methods variant_field_methods = {
.set_is_frozen = set_variant_field_is_frozen,
static
struct bt_field *create_dynamic_array_field(struct bt_field_class *);
+static
+struct bt_field *create_option_field(struct bt_field_class *);
+
static
struct bt_field *create_variant_field(struct bt_field_class *);
[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_OPTION] = create_option_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = create_variant_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = create_variant_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = create_variant_field,
static
void destroy_array_field(struct bt_field *field);
+static
+void destroy_option_field(struct bt_field *field);
+
static
void destroy_variant_field(struct bt_field *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_OPTION] = destroy_option_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR] = destroy_variant_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR] = destroy_variant_field,
[BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR] = destroy_variant_field,
return (void *) struct_field;
}
+static
+struct bt_field *create_option_field(struct bt_field_class *fc)
+{
+ struct bt_field_option *opt_field;
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ BT_LIB_LOGD("Creating option field object: %![fc-]+F", fc);
+ opt_field = g_new0(struct bt_field_option, 1);
+ if (!opt_field) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to allocate one option field.");
+ goto end;
+ }
+
+ init_field((void *) opt_field, fc, &option_field_methods);
+ opt_field->content_field = bt_field_create(opt_fc->content_fc);
+ if (!opt_field->content_field) {
+ BT_LIB_LOGE_APPEND_CAUSE(
+ "Failed to create option field's content field: "
+ "%![opt-fc-]+F, %![content-fc-]+F",
+ opt_fc, opt_fc->content_fc);
+ BT_OBJECT_PUT_REF_AND_RESET(opt_field);
+ goto end;
+ }
+
+ BT_LIB_LOGD("Created option field object: %!+f", opt_field);
+
+end:
+ return (void *) opt_field;
+}
+
static
struct bt_field *create_variant_field(struct bt_field_class *fc)
{
(void *) field, name);
}
+void bt_field_option_set_has_field(struct bt_field *field, bt_bool has_field)
+{
+ struct bt_field_option *opt_field = (void *) field;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+ BT_FIELD_CLASS_TYPE_OPTION, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HOT(field, "Field");
+
+ if (has_field) {
+ opt_field->selected_field = opt_field->content_field;
+ } else {
+ opt_field->selected_field = NULL;
+ }
+}
+
+struct bt_field *bt_field_option_borrow_field(struct bt_field *field)
+{
+ struct bt_field_option *opt_field = (void *) field;
+
+ BT_ASSERT_PRE_DEV_NON_NULL(field, "Field");
+ BT_ASSERT_PRE_DEV_FIELD_HAS_CLASS_TYPE(field,
+ BT_FIELD_CLASS_TYPE_OPTION, "Field");
+ return opt_field->selected_field;
+}
+
+const struct bt_field *bt_field_option_borrow_field_const(
+ const struct bt_field *field)
+{
+ return (const void *) bt_field_option_borrow_field((void *) field);
+}
+
static inline
struct bt_field *borrow_variant_field_selected_option_field(
struct bt_field *field)
g_free(field);
}
+static
+void destroy_option_field(struct bt_field *field)
+{
+ struct bt_field_option *opt_field = (void *) field;
+
+ BT_ASSERT(field);
+ BT_LIB_LOGD("Destroying option field object: %!+f", field);
+ bt_field_finalize(field);
+
+ if (opt_field->content_field) {
+ bt_field_destroy(opt_field->content_field);
+ }
+
+ g_free(field);
+}
+
static
void destroy_variant_field(struct bt_field *field)
{
}
}
+static
+void reset_option_field(struct bt_field *field)
+{
+ struct bt_field_option *opt_field = (void *) field;
+
+ BT_ASSERT(opt_field);
+ bt_field_reset(opt_field->content_field);
+ opt_field->selected_field = NULL;
+}
+
static
void reset_variant_field(struct bt_field *field)
{
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);
+ _bt_field_set_is_frozen(member_field, is_frozen);
}
set_single_field_is_frozen(field, is_frozen);
}
+static
+void set_option_field_is_frozen(struct bt_field *field, bool is_frozen)
+{
+ struct bt_field_option *opt_field = (void *) field;
+
+ BT_LIB_LOGD("Setting option field's frozen state: "
+ "%![field-]+f, is-frozen=%d", field, is_frozen);
+ _bt_field_set_is_frozen(opt_field->content_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)
{
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);
+ _bt_field_set_is_frozen(option_field, is_frozen);
}
set_single_field_is_frozen(field, is_frozen);
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);
+ _bt_field_set_is_frozen(elem_field, is_frozen);
}
set_single_field_is_frozen(field, is_frozen);
return is_set;
}
+static
+bool option_field_is_set(const struct bt_field *field)
+{
+ const struct bt_field_option *opt_field = (const void *) field;
+ bool is_set = false;
+
+ BT_ASSERT(field);
+
+ if (opt_field->selected_field) {
+ is_set = bt_field_is_set(opt_field->selected_field);
+ }
+
+ return is_set;
+}
+
static
bool variant_field_is_set(const struct bt_field *field)
{
GPtrArray *fields;
};
+struct bt_field_option {
+ struct bt_field common;
+
+ /* Owned by this */
+ struct bt_field *content_field;
+
+ /* Weak: equal to `content_field` above or `NULL` */
+ struct bt_field *selected_field;
+};
+
struct bt_field_variant {
struct bt_field common;
}
switch (fc->type) {
+ case BT_FIELD_CLASS_TYPE_OPTION:
+ {
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ struct bt_field_path_item item = {
+ .type = BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT,
+ .index = UINT64_C(-1),
+ };
+
+ bt_field_path_append_item(field_path, &item);
+ found = find_field_class_recursive(opt_fc->content_fc,
+ tgt_fc, field_path);
+ if (found) {
+ goto end;
+ }
+
+ bt_field_path_remove_last_item(field_path);
+ break;
+ }
case BT_FIELD_CLASS_TYPE_STRUCTURE:
case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
struct bt_field_class *child_fc = NULL;
switch (parent_fc->type) {
+ case BT_FIELD_CLASS_TYPE_OPTION:
+ {
+ struct bt_field_class_option *opt_fc = (void *) parent_fc;
+
+ BT_ASSERT(fp_item->type ==
+ BT_FIELD_PATH_ITEM_TYPE_CURRENT_OPTION_CONTENT);
+ child_fc = opt_fc->content_fc;
+ break;
+ }
case BT_FIELD_CLASS_TYPE_STRUCTURE:
case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR:
if (fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
+ fc->type == BT_FIELD_CLASS_TYPE_OPTION ||
fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR ||
fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
if (tgt_fc->type == BT_FIELD_CLASS_TYPE_STATIC_ARRAY ||
tgt_fc->type == BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY ||
+ tgt_fc->type == BT_FIELD_CLASS_TYPE_OPTION ||
tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR ||
tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR ||
tgt_fc->type == BT_FIELD_CLASS_TYPE_VARIANT_WITH_SIGNED_SELECTOR) {
/* Resolving part for dynamic array and variant field classes */
switch (fc->type) {
+ case BT_FIELD_CLASS_TYPE_OPTION:
+ {
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ if (opt_fc->selector_fc) {
+ BT_ASSERT(!opt_fc->selector_field_path);
+ opt_fc->selector_field_path = resolve_field_path(
+ fc, opt_fc->selector_fc, ctx);
+ if (!opt_fc->selector_field_path) {
+ ret = -1;
+ goto end;
+ }
+ }
+
+ break;
+ }
case BT_FIELD_CLASS_TYPE_DYNAMIC_ARRAY:
{
struct bt_field_class_array_dynamic *dyn_array_fc = (void *) fc;
/* Recursive part */
switch (fc->type) {
+ case BT_FIELD_CLASS_TYPE_OPTION:
+ {
+ struct bt_field_class_option *opt_fc = (void *) fc;
+
+ ret = bt_resolve_field_paths(opt_fc->content_fc, ctx);
+ break;
+ }
case BT_FIELD_CLASS_TYPE_STRUCTURE:
case BT_FIELD_CLASS_TYPE_VARIANT_WITHOUT_SELECTOR:
case BT_FIELD_CLASS_TYPE_VARIANT_WITH_UNSIGNED_SELECTOR: