+ssize_t count_one_type(const struct lttng_ust_type_common *lt)
+{
+ switch (lt->type) {
+ case lttng_ust_type_integer:
+ case lttng_ust_type_float:
+ case lttng_ust_type_string:
+ return 1;
+ case lttng_ust_type_enum:
+ return count_one_type(lttng_ust_get_type_enum(lt)->container_type) + 1;
+ case lttng_ust_type_array:
+ return count_one_type(lttng_ust_get_type_array(lt)->elem_type) + 1;
+ case lttng_ust_type_sequence:
+ return count_one_type(lttng_ust_get_type_sequence(lt)->elem_type) + 1;
+ case lttng_ust_type_struct:
+ return count_fields_recursive(lttng_ust_get_type_struct(lt)->nr_fields,
+ lttng_ust_get_type_struct(lt)->fields) + 1;
+
+ case lttng_ust_type_dynamic:
+ {
+ const struct lttng_ust_event_field **choices;
+ size_t nr_choices;
+ int ret;
+
+ ret = lttng_ust_dynamic_type_choices(&nr_choices,
+ &choices);
+ if (ret)
+ return ret;
+ /*
+ * Two fields for enum, one field for variant, and
+ * one field per choice.
+ */
+ return count_fields_recursive(nr_choices, choices) + 3;
+ }
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static
+ssize_t count_fields_recursive(size_t nr_fields,
+ const struct lttng_ust_event_field **lttng_fields)
+{
+ int i;
+ ssize_t ret, count = 0;
+
+ for (i = 0; i < nr_fields; i++) {
+ const struct lttng_ust_event_field *lf;
+
+ lf = lttng_fields[i];
+ /* skip 'nowrite' fields */
+ if (lf->nowrite)
+ continue;
+ ret = count_one_type(lf->type);
+ if (ret < 0)
+ return ret; /* error */
+ count += ret;
+ }
+ return count;
+}
+
+static
+ssize_t count_ctx_fields_recursive(size_t nr_fields,
+ struct lttng_ust_ctx_field *lttng_fields)
+{
+ int i;
+ ssize_t ret, count = 0;
+
+ for (i = 0; i < nr_fields; i++) {
+ const struct lttng_ust_event_field *lf;
+
+ lf = lttng_fields[i].event_field;
+ /* skip 'nowrite' fields */
+ if (lf->nowrite)
+ continue;
+ ret = count_one_type(lf->type);
+ if (ret < 0)
+ return ret; /* error */
+ count += ret;
+ }
+ return count;
+}
+
+static
+int serialize_string_encoding(int32_t *ue,
+ enum lttng_ust_string_encoding le)