aboutsummaryrefslogtreecommitdiffstats
path: root/ctrl/libhicnctrl/src/data.c
diff options
context:
space:
mode:
Diffstat (limited to 'ctrl/libhicnctrl/src/data.c')
-rw-r--r--ctrl/libhicnctrl/src/data.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/ctrl/libhicnctrl/src/data.c b/ctrl/libhicnctrl/src/data.c
new file mode 100644
index 000000000..605e23601
--- /dev/null
+++ b/ctrl/libhicnctrl/src/data.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * \file data.c
+ * \brief Implementation of request result data.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <hicn/ctrl/data.h>
+#include <hicn/ctrl/object.h>
+#include <hicn/util/log.h>
+
+#define MIN_ALLOC_SIZE 8
+#define MAX(x, y) (((x) > (y)) ? (x) : (y))
+
+struct hc_data_s {
+ hc_object_type_t object_type;
+ bool complete;
+
+ /**
+ * >=0 success, indicates the number of records in array
+ * <0 error
+ */
+ ssize_t size;
+ size_t alloc_size; /** Allocated size (a power of 2 when managed
+ automatically) */
+ size_t max_size; /** Maximum size defined at creation (0 = unlimited) */
+
+ uint8_t *buffer;
+};
+
+void _hc_data_clear(hc_data_t *data) {
+ data->complete = false;
+ data->buffer = NULL;
+ data->max_size = 0;
+ data->alloc_size = 0;
+ data->size = 0;
+}
+
+hc_data_t *hc_data_create(hc_object_type_t object_type) {
+ hc_data_t *data = malloc(sizeof(hc_data_t));
+ if (!data) return NULL;
+
+ data->object_type = object_type;
+
+ _hc_data_clear(data);
+
+ return data;
+ // data->buffer = malloc((1 << data->max_size_log) * data->out_element_size);
+ // if (!data->buffer) goto ERR_BUFFER;
+}
+
+void hc_data_free(hc_data_t *data) {
+ assert(data);
+
+ if (data->buffer) free(data->buffer);
+ free(data);
+}
+
+int hc_data_set_max_size(hc_data_t *data, size_t max_size) {
+ if (data->size > max_size) return -1;
+ data->max_size = max_size;
+ return 0;
+}
+
+const uint8_t *hc_data_get_buffer(hc_data_t *data) { return data->buffer; }
+
+const uint8_t *hc_data_get_free(hc_data_t *data) {
+ if (!data) return NULL;
+ if (data->max_size > 0 && data->size >= data->max_size) return NULL;
+ hc_object_type_t object_type = hc_data_get_object_type(data);
+ size_t object_size = hc_object_size(object_type);
+ return data->buffer + data->size * object_size;
+}
+
+void hc_data_inc_size(hc_data_t *data) { data->size++; }
+
+hc_object_type_t hc_data_get_object_type(const hc_data_t *data) {
+ return data->object_type;
+}
+
+void hc_data_set_object_type(hc_data_t *data, hc_object_type_t object_type) {
+ data->object_type = object_type;
+}
+
+ssize_t hc_data_get_size(const hc_data_t *data) { return data->size; }
+
+int hc_data_clear(hc_data_t *data) {
+ free(data->buffer);
+ _hc_data_clear(data);
+ return 0;
+}
+
+int _hc_data_allocate(hc_data_t *data, size_t size) {
+ data->buffer =
+ realloc(data->buffer, size * hc_object_size(data->object_type));
+ if (!data->buffer) goto ERR;
+ data->alloc_size = size;
+ return 0;
+ERR:
+ data->alloc_size = 0;
+ return -1;
+}
+
+int hc_data_allocate(hc_data_t *data, size_t size) {
+ /* Do not allocate twice */
+ if (data->buffer) return -1;
+ if (data->max_size > 0 && size > data->max_size) return -1;
+ return _hc_data_allocate(data, size);
+}
+
+int hc_data_ensure_available(hc_data_t *data, size_t count) {
+ size_t new_size = data->size + count;
+ if (new_size < data->alloc_size) return 0;
+ if (data->max_size > 0 && new_size > data->max_size) return -1;
+
+ size_t new_alloc_size = MAX(MIN_ALLOC_SIZE, next_pow2(new_size));
+ if (data->max_size > 0 && new_alloc_size > data->max_size)
+ new_alloc_size = data->max_size;
+
+ return _hc_data_allocate(data, new_alloc_size);
+}
+
+int hc_data_push_many(hc_data_t *data, const void *elements, size_t count) {
+ if (!data) return -1;
+ if (!elements) return -1;
+ if (count < 1) return -1;
+
+ if (hc_data_ensure_available(data, count) < 0) return -1;
+
+ hc_object_type_t object_type = hc_data_get_object_type(data);
+ size_t object_size = hc_object_size(object_type);
+
+ uint8_t *dst = data->buffer + data->size * object_size;
+ memcpy(dst, elements, count * object_size);
+ data->size += count;
+
+ return 0;
+}
+
+int hc_data_push(hc_data_t *data, const void *element) {
+ return hc_data_push_many(data, element, 1);
+}
+#if 0
+/**
+ *
+ * NOTE: This function make sure there is enough room available in the data
+ * structure.
+ */
+u8 *hc_data_get_next(hc_data_t *data) {
+ if (hc_data_ensure_available(data, 1) < 0) return NULL;
+
+ return data->buffer + data->size * data->out_element_size;
+}
+
+int hc_data_set_callback(hc_data_t *data, data_callback_t cb, void *cb_data) {
+ data->complete_cb = cb;
+ data->complete_cb_data = cb_data;
+ return 0;
+}
+#endif
+
+void hc_data_set_complete(hc_data_t *data) { data->complete = true; }
+
+bool hc_data_is_complete(const hc_data_t *data) { return data->complete; }
+
+void hc_data_set_error(hc_data_t *data) {
+ data->size = -1;
+ data->complete = true;
+}
+
+bool hc_data_get_result(hc_data_t *data) { return (data->size >= 0); }
+
+hc_object_t *hc_data_find(hc_data_t *data, hc_object_t *object) {
+ hc_object_type_t object_type = hc_data_get_object_type(data);
+ hc_data_foreach(data, found, {
+ if (hc_object_cmp(object_type, object, found) == 0) return found;
+ });
+ return NULL;
+}
+
+const hc_object_t *hc_data_get_object(const hc_data_t *data, off_t pos) {
+ size_t size = hc_data_get_size(data);
+ if (pos >= size) return NULL;
+
+ hc_object_type_t object_type = hc_data_get_object_type(data);
+ size_t object_size = hc_object_size(object_type);
+
+ return (const hc_object_t *)(data->buffer + pos * object_size);
+}
+
+#if 0
+int hc_data_reset(hc_data_t *data) {
+ data->size = 0;
+ return 0;
+}
+#endif