+static
+int serialize_basic_type(enum ustctl_abstract_types *uatype,
+ enum lttng_abstract_types atype,
+ union _ustctl_basic_type *ubt,
+ const union _lttng_basic_type *lbt)
+{
+ switch (atype) {
+ case atype_integer:
+ {
+ struct ustctl_integer_type *uit;
+ const struct lttng_integer_type *lit;
+
+ uit = &ubt->integer;
+ lit = &lbt->integer;
+ uit->size = lit->size;
+ uit->signedness = lit->signedness;
+ uit->reverse_byte_order = lit->reverse_byte_order;
+ uit->base = lit->base;
+ if (serialize_string_encoding(&uit->encoding, lit->encoding))
+ return -EINVAL;
+ uit->alignment = lit->alignment;
+ *uatype = ustctl_atype_integer;
+ break;
+ }
+ case atype_string:
+ {
+ if (serialize_string_encoding(&ubt->string.encoding,
+ lbt->string.encoding))
+ return -EINVAL;
+ *uatype = ustctl_atype_string;
+ break;
+ }
+ case atype_float:
+ {
+ struct ustctl_float_type *uft;
+ const struct lttng_float_type *lft;
+
+ uft = &ubt->_float;
+ lft = &lbt->_float;
+ uft->exp_dig = lft->exp_dig;
+ uft->mant_dig = lft->mant_dig;
+ uft->alignment = lft->alignment;
+ uft->reverse_byte_order = lft->reverse_byte_order;
+ *uatype = ustctl_atype_float;
+ break;
+ }
+ case atype_enum:
+ case atype_array:
+ case atype_sequence:
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static
+int serialize_one_type(struct ustctl_type *ut, const struct lttng_type *lt)
+{
+ int ret;
+
+ switch (lt->atype) {
+ case atype_integer:
+ case atype_float:
+ case atype_string:
+ ret = serialize_basic_type(&ut->atype, lt->atype,
+ &ut->u.basic, <->u.basic);
+ if (ret)
+ return ret;
+ break;
+ case atype_array:
+ {
+ struct ustctl_basic_type *ubt;
+ const struct lttng_basic_type *lbt;
+ int ret;
+
+ ubt = &ut->u.array.elem_type;
+ lbt = <->u.array.elem_type;
+ ut->u.array.length = lt->u.array.length;
+ ret = serialize_basic_type(&ubt->atype, lbt->atype,
+ &ubt->u.basic, &lbt->u.basic);
+ if (ret)
+ return -EINVAL;
+ ut->atype = ustctl_atype_array;
+ break;
+ }
+ case atype_sequence:
+ {
+ struct ustctl_basic_type *ubt;
+ const struct lttng_basic_type *lbt;
+ int ret;
+
+ ubt = &ut->u.sequence.length_type;
+ lbt = <->u.sequence.length_type;
+ ret = serialize_basic_type(&ubt->atype, lbt->atype,
+ &ubt->u.basic, &lbt->u.basic);
+ if (ret)
+ return -EINVAL;
+ ubt = &ut->u.sequence.elem_type;
+ lbt = <->u.sequence.elem_type;
+ ret = serialize_basic_type(&ubt->atype, lbt->atype,
+ &ubt->u.basic, &lbt->u.basic);
+ if (ret)
+ return -EINVAL;
+ ut->atype = ustctl_atype_sequence;
+ break;
+ }
+ case atype_enum:
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static
+int serialize_fields(size_t *_nr_write_fields,
+ struct ustctl_field **ustctl_fields,
+ size_t nr_fields,
+ const struct lttng_event_field *lttng_fields)
+{
+ struct ustctl_field *fields;
+ int i, ret;
+ size_t nr_write_fields = 0;
+
+ fields = zmalloc(nr_fields * sizeof(*fields));
+ if (!fields)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_fields; i++) {
+ struct ustctl_field *f;
+ const struct lttng_event_field *lf;
+
+ f = &fields[nr_write_fields];
+ lf = <tng_fields[i];
+
+ /* skip 'nowrite' fields */
+ if (lf->nowrite)
+ continue;
+ strncpy(f->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+ f->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ ret = serialize_one_type(&f->type, &lf->type);
+ if (ret)
+ goto error_type;
+ nr_write_fields++;
+ }
+
+ *_nr_write_fields = nr_write_fields;
+ *ustctl_fields = fields;
+ return 0;
+
+error_type:
+ free(fields);
+ return ret;
+}
+
+static
+int serialize_ctx_fields(size_t *_nr_write_fields,
+ struct ustctl_field **ustctl_fields,
+ size_t nr_fields,
+ const struct lttng_ctx_field *lttng_fields)
+{
+ struct ustctl_field *fields;
+ int i, ret;
+ size_t nr_write_fields = 0;
+
+ fields = zmalloc(nr_fields * sizeof(*fields));
+ if (!fields)
+ return -ENOMEM;
+
+ for (i = 0; i < nr_fields; i++) {
+ struct ustctl_field *f;
+ const struct lttng_event_field *lf;
+
+ f = &fields[nr_write_fields];
+ lf = <tng_fields[i].event_field;
+
+ /* skip 'nowrite' fields */
+ if (lf->nowrite)
+ continue;
+ strncpy(f->name, lf->name, LTTNG_UST_SYM_NAME_LEN);
+ f->name[LTTNG_UST_SYM_NAME_LEN - 1] = '\0';
+ ret = serialize_one_type(&f->type, &lf->type);
+ if (ret)
+ goto error_type;
+ nr_write_fields++;
+ }
+
+ *_nr_write_fields = nr_write_fields;
+ *ustctl_fields = fields;
+ return 0;
+
+error_type:
+ free(fields);
+ return ret;
+}