/*
- * Copyright (C) 2019 - Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
+ * Copyright (C) 2019 Jonathan Rajotte-Julien <jonathan.rajotte-julien@efficios.com>
*
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License, version 2.1 only,
- * as published by the Free Software Foundation.
+ * SPDX-License-Identifier: LGPL-2.1-only
*
- * This library is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
- * for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this library; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <assert.h>
return LTTNG_TRACKER_ID_STATUS_OK;
}
-void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
+static void lttng_tracker_id_reset(struct lttng_tracker_id *id)
{
if (id == NULL) {
return;
if (id->string != NULL) {
free(id->string);
+ id->string = NULL;
}
- free(id);
+ id->type = LTTNG_ID_UNKNOWN;
+ id->value = -1;
}
-void lttng_tracker_ids_destroy(struct lttng_tracker_id **ids, size_t nr_ids)
+void lttng_tracker_id_destroy(struct lttng_tracker_id *id)
{
- if (ids == NULL) {
+ if (id == NULL) {
return;
}
- for (int i = 0; i < nr_ids; i++) {
- lttng_tracker_id_destroy(ids[i]);
- }
+ lttng_tracker_id_reset(id);
+
+ free(id);
}
enum lttng_tracker_id_type lttng_tracker_id_get_type(
return 1;
}
-struct lttng_tracker_id *lttng_tracker_id_copy(
+int lttng_tracker_id_copy(struct lttng_tracker_id *dest,
const struct lttng_tracker_id *orig)
{
- struct lttng_tracker_id *copy = NULL;
+ int ret = 0;
enum lttng_tracker_id_status status;
- copy = lttng_tracker_id_create();
- if (copy == NULL) {
- goto error;
- }
+ assert(dest);
+ assert(orig);
switch (orig->type) {
case LTTNG_ID_ALL:
- status = lttng_tracker_id_set_all(copy);
+ status = lttng_tracker_id_set_all(dest);
break;
case LTTNG_ID_VALUE:
- status = lttng_tracker_id_set_value(copy, orig->value);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- goto error;
- }
+ status = lttng_tracker_id_set_value(dest, orig->value);
break;
case LTTNG_ID_STRING:
- status = lttng_tracker_id_set_string(copy, orig->string);
- if (status != LTTNG_TRACKER_ID_STATUS_OK) {
- goto error;
- }
+ status = lttng_tracker_id_set_string(dest, orig->string);
break;
default:
status = LTTNG_TRACKER_ID_STATUS_OK;
}
if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -1;
+ goto error;
+ }
+error:
+ return ret;
+}
+
+struct lttng_tracker_id *lttng_tracker_id_duplicate(
+ const struct lttng_tracker_id *orig)
+{
+ int ret;
+ struct lttng_tracker_id *copy = NULL;
+
+ copy = lttng_tracker_id_create();
+ if (copy == NULL) {
+ goto error;
+ }
+
+ ret = lttng_tracker_id_copy(copy, orig);
+ if (ret) {
goto error;
}
*value = id->string;
return LTTNG_TRACKER_ID_STATUS_OK;
}
+
+struct lttng_tracker_ids *lttng_tracker_ids_create(unsigned int count)
+{
+ struct lttng_tracker_ids *ids = NULL;
+
+ ids = zmalloc(sizeof(*ids));
+ if (!ids) {
+ goto error;
+ }
+
+ ids->id_array = zmalloc(sizeof(struct lttng_tracker_id) * count);
+ if (!ids->id_array) {
+ goto error;
+ }
+
+ ids->count = count;
+
+ return ids;
+error:
+ free(ids);
+ return NULL;
+}
+
+LTTNG_HIDDEN
+struct lttng_tracker_id *lttng_tracker_ids_get_pointer_of_index(
+ const struct lttng_tracker_ids *ids, unsigned int index)
+{
+ assert(ids);
+ if (index >= ids->count) {
+ return NULL;
+ }
+
+ return &ids->id_array[index];
+}
+
+const struct lttng_tracker_id *lttng_tracker_ids_get_at_index(
+ const struct lttng_tracker_ids *ids, unsigned int index)
+{
+ assert(ids);
+ return lttng_tracker_ids_get_pointer_of_index(ids, index);
+}
+
+enum lttng_tracker_id_status lttng_tracker_ids_get_count(const struct lttng_tracker_ids *ids, unsigned int *count)
+{
+
+ enum lttng_tracker_id_status status = LTTNG_TRACKER_ID_STATUS_OK;
+
+ if (!ids || !count) {
+ status = LTTNG_TRACKER_ID_STATUS_INVALID;
+ goto end;
+ }
+
+ *count = ids->count;
+end:
+ return status;
+}
+
+void lttng_tracker_ids_destroy(struct lttng_tracker_ids *ids)
+{
+ int i;
+
+ if (!ids) {
+ return;
+ }
+
+ for (i = 0; i < ids->count; i++) {
+ lttng_tracker_id_reset(&ids->id_array[i]);
+ }
+ free(ids->id_array);
+ free(ids);
+}
+
+int lttng_tracker_ids_serialize(const struct lttng_tracker_ids *ids,
+ struct lttng_dynamic_buffer *buffer)
+{
+ int ret;
+ int value;
+ const char *string;
+ unsigned int count;
+ enum lttng_tracker_id_status status;
+ const struct lttng_tracker_id *id;
+ unsigned int i;
+
+ status = lttng_tracker_ids_get_count(ids, &count);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ for (i = 0; i < count; i++) {
+ struct lttcomm_tracker_id_header id_hdr;
+ size_t var_data_len = 0;
+
+ id = lttng_tracker_ids_get_at_index(ids, i);
+ if (!id) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ memset(&id_hdr, 0, sizeof(id_hdr));
+ id_hdr.type = lttng_tracker_id_get_type(id);
+ switch (id_hdr.type) {
+ case LTTNG_ID_ALL:
+ break;
+ case LTTNG_ID_VALUE:
+ status = lttng_tracker_id_get_value(id, &value);
+ id_hdr.u.value = value;
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+ break;
+ case LTTNG_ID_STRING:
+ status = lttng_tracker_id_get_string(
+ id, &string);
+ if (status != LTTNG_TRACKER_ID_STATUS_OK) {
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+
+ id_hdr.u.var_data_len = var_data_len =
+ strlen(string) + 1;
+ break;
+ default:
+ ret = -LTTNG_ERR_INVALID;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(
+ buffer, &id_hdr, sizeof(id_hdr));
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ ret = lttng_dynamic_buffer_append(
+ buffer, string, var_data_len);
+ if (ret) {
+ ret = -LTTNG_ERR_NOMEM;
+ goto error;
+ }
+ }
+error:
+ return ret;
+}