From 64c2c2496913d64ddd77343b9651f1f233cda5cf Mon Sep 17 00:00:00 2001 From: Julien Desfossez Date: Tue, 10 Apr 2012 17:43:31 -0400 Subject: [PATCH] API Fix : missing list fields of event decl This patchs allows the user to list the fields (in all scopes) for each event declarations (so as soon as the trace is opened). It uses a lazy allocation, so the memory for storing the fields is only allocated if the users asks for the list and it is allocated per event. Signed-off-by: Julien Desfossez Signed-off-by: Mathieu Desnoyers --- formats/ctf/ctf.c | 12 +++ formats/ctf/events.c | 124 ++++++++++++++++++++++- include/babeltrace/ctf/events-internal.h | 6 ++ include/babeltrace/ctf/events.h | 19 +++- 4 files changed, 158 insertions(+), 3 deletions(-) diff --git a/formats/ctf/ctf.c b/formats/ctf/ctf.c index 32206166..1e4e491d 100644 --- a/formats/ctf/ctf.c +++ b/formats/ctf/ctf.c @@ -1718,6 +1718,18 @@ void ctf_close_trace(struct trace_descriptor *tdp) struct bt_ctf_event_decl *event; event = g_ptr_array_index(td->event_declarations, i); + if (event->context_decl) + g_ptr_array_free(event->context_decl, TRUE); + if (event->fields_decl) + g_ptr_array_free(event->fields_decl, TRUE); + if (event->packet_header_decl) + g_ptr_array_free(event->packet_header_decl, TRUE); + if (event->event_context_decl) + g_ptr_array_free(event->event_context_decl, TRUE); + if (event->event_header_decl) + g_ptr_array_free(event->event_header_decl, TRUE); + if (event->packet_context_decl) + g_ptr_array_free(event->packet_context_decl, TRUE); g_free(event); } g_ptr_array_free(td->event_declarations, TRUE); diff --git a/formats/ctf/events.c b/formats/ctf/events.c index 13c7411a..27a5fe7b 100644 --- a/formats/ctf/events.c +++ b/formats/ctf/events.c @@ -443,7 +443,7 @@ char *bt_ctf_get_string(const struct definition *field) } int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, - struct bt_ctf_event_decl const * const **list, + struct bt_ctf_event_decl * const **list, unsigned int *count) { struct bt_trace_handle *handle; @@ -461,7 +461,7 @@ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, td = handle->td; tin = container_of(td, struct ctf_trace, parent); - *list = (struct bt_ctf_event_decl const* const*) tin->event_declarations->pdata; + *list = (struct bt_ctf_event_decl * const*) tin->event_declarations->pdata; *count = tin->event_declarations->len; return 0; @@ -475,3 +475,123 @@ const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event) return NULL; return g_quark_to_string(event->parent.name); } + +int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl, + enum bt_ctf_scope scope, + struct bt_ctf_field_decl const * const **list, + unsigned int *count) +{ + int i; + GArray *fields = NULL; + gpointer *ret_list = NULL; + GPtrArray *fields_array = NULL; + int ret = 0; + *count = 0; + + switch (scope) { + case BT_EVENT_CONTEXT: + if (event_decl->context_decl) { + ret_list = event_decl->context_decl->pdata; + *count = event_decl->context_decl->len; + goto end; + } + event_decl->context_decl = g_ptr_array_new(); + if (!event_decl->parent.context_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.context_decl->fields; + fields_array = event_decl->context_decl; + break; + case BT_EVENT_FIELDS: + if (event_decl->fields_decl) { + ret_list = event_decl->fields_decl->pdata; + *count = event_decl->fields_decl->len; + goto end; + } + event_decl->fields_decl = g_ptr_array_new(); + if (!event_decl->parent.fields_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.fields_decl->fields; + fields_array = event_decl->fields_decl; + break; + case BT_STREAM_PACKET_CONTEXT: + if (event_decl->packet_context_decl) { + ret_list = event_decl->packet_context_decl->pdata; + *count = event_decl->packet_context_decl->len; + goto end; + } + event_decl->packet_context_decl = g_ptr_array_new(); + if (!event_decl->parent.stream->packet_context_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.stream->packet_context_decl->fields; + fields_array = event_decl->packet_context_decl; + break; + case BT_STREAM_EVENT_CONTEXT: + if (event_decl->event_context_decl) { + ret_list = event_decl->event_context_decl->pdata; + *count = event_decl->event_context_decl->len; + goto end; + } + event_decl->event_context_decl = g_ptr_array_new(); + if (!event_decl->parent.stream->event_context_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.stream->event_context_decl->fields; + fields_array = event_decl->event_context_decl; + break; + case BT_STREAM_EVENT_HEADER: + if (event_decl->event_header_decl) { + ret_list = event_decl->event_header_decl->pdata; + *count = event_decl->event_header_decl->len; + goto end; + } + event_decl->event_header_decl = g_ptr_array_new(); + if (!event_decl->parent.stream->event_header_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.stream->event_header_decl->fields; + fields_array = event_decl->event_header_decl; + break; + case BT_TRACE_PACKET_HEADER: + if (event_decl->packet_header_decl) { + ret_list = event_decl->packet_header_decl->pdata; + *count = event_decl->packet_header_decl->len; + goto end; + } + event_decl->packet_header_decl = g_ptr_array_new(); + if (!event_decl->parent.stream->trace->packet_header_decl) { + ret = -1; + goto end; + } + fields = event_decl->parent.stream->trace->packet_header_decl->fields; + fields_array = event_decl->packet_header_decl; + break; + } + + for (i = 0; i < fields->len; i++) { + g_ptr_array_add(fields_array, + &g_array_index(fields, + struct declaration_field, i)); + } + ret_list = fields_array->pdata; + *count = fields->len; + +end: + *list = (struct bt_ctf_field_decl const* const*) ret_list; + + return ret; +} + +const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field) +{ + if (field) + return rem_(g_quark_to_string(((struct declaration_field *) field)->name)); + return NULL; +} diff --git a/include/babeltrace/ctf/events-internal.h b/include/babeltrace/ctf/events-internal.h index 56b7e6b9..aaa09262 100644 --- a/include/babeltrace/ctf/events-internal.h +++ b/include/babeltrace/ctf/events-internal.h @@ -40,6 +40,12 @@ struct bt_ctf_event { struct bt_ctf_event_decl { struct ctf_event_declaration parent; + GPtrArray *context_decl; + GPtrArray *fields_decl; + GPtrArray *packet_header_decl; + GPtrArray *event_context_decl; + GPtrArray *event_header_decl; + GPtrArray *packet_context_decl; }; struct bt_ctf_iter { diff --git a/include/babeltrace/ctf/events.h b/include/babeltrace/ctf/events.h index 73e6bc1a..30365aaa 100644 --- a/include/babeltrace/ctf/events.h +++ b/include/babeltrace/ctf/events.h @@ -29,6 +29,7 @@ struct definition; struct bt_ctf_event; struct bt_ctf_event_decl; +struct bt_ctf_field_decl; /* * the top-level scopes in CTF @@ -195,7 +196,7 @@ int bt_ctf_field_get_error(void); * Return 0 on success and a negative value on error. */ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, - struct bt_ctf_event_decl const * const **list, + struct bt_ctf_event_decl * const **list, unsigned int *count); /* @@ -203,4 +204,20 @@ int bt_ctf_get_event_decl_list(int handle_id, struct bt_context *ctx, */ const char *bt_ctf_get_decl_event_name(const struct bt_ctf_event_decl *event); +/* + * bt_ctf_get_decl_fields: set list pointer to an array of bt_ctf_field_decl + * pointers and set count to the number of elements in the array. + * + * Returns 0 on success and a negative value on error + */ +int bt_ctf_get_decl_fields(struct bt_ctf_event_decl *event_decl, + enum bt_ctf_scope scope, + struct bt_ctf_field_decl const * const **list, + unsigned int *count); + +/* + * bt_ctf_get_decl_field_name: return the name of a field decl or NULL on error + */ +const char *bt_ctf_get_decl_field_name(const struct bt_ctf_field_decl *field); + #endif /* _BABELTRACE_CTF_EVENTS_H */ -- 2.34.1