summaryrefslogtreecommitdiff
path: root/infra/exdata
diff options
context:
space:
mode:
authoryangwei <[email protected]>2024-09-06 18:36:24 +0800
committeryangwei <[email protected]>2024-09-06 19:48:29 +0800
commita24214cbee8207653833095c5817c7e26094c948 (patch)
tree29f363659b2832592f20ac81237ad1d4f112f32e /infra/exdata
parent3de8bbdabcdf49ecc805b7c4b3a74646f60411f7 (diff)
✨ feat(infra/exdata): exdata as independent component
Diffstat (limited to 'infra/exdata')
-rw-r--r--infra/exdata/CMakeLists.txt3
-rw-r--r--infra/exdata/exdata.c154
-rw-r--r--infra/exdata/exdata.h22
-rw-r--r--infra/exdata/exdata_internal.h35
4 files changed, 214 insertions, 0 deletions
diff --git a/infra/exdata/CMakeLists.txt b/infra/exdata/CMakeLists.txt
new file mode 100644
index 0000000..2630f57
--- /dev/null
+++ b/infra/exdata/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_library(exdata exdata.c)
+
+#add_subdirectory(test) \ No newline at end of file
diff --git a/infra/exdata/exdata.c b/infra/exdata/exdata.c
new file mode 100644
index 0000000..289898d
--- /dev/null
+++ b/infra/exdata/exdata.c
@@ -0,0 +1,154 @@
+#include "stellar/utils.h"
+
+#include "exdata_internal.h"
+
+
+/*******************************
+ * STELLAR EXDATA SCHEMA API*
+ *******************************/
+
+struct exdata_schema *exdata_schema_new()
+{
+ struct exdata_schema *s = CALLOC(struct exdata_schema, 1);
+ return s;
+}
+
+void exdata_schema_free(struct exdata_schema *s)
+{
+ if(s==NULL)return;
+ if(s->exdata_meta_array)
+ {
+ utarray_free(s->exdata_meta_array);
+ }
+ FREE(s);
+}
+
+int exdata_schema_get_idx_by_name(struct exdata_schema *schema, const char *name)
+{
+ if(schema==NULL || schema->exdata_meta_array == NULL || name == NULL)return -1;
+ unsigned int len = utarray_len(schema->exdata_meta_array);
+ struct exdata_meta *t_schema;
+ for(unsigned int i = 0; i < len; i++)
+ {
+ t_schema = (struct exdata_meta *)utarray_eltptr(schema->exdata_meta_array, i);
+ if(strcmp(t_schema->name, name) == 0)
+ {
+ return t_schema->idx;
+ }
+ }
+ return -1;
+}
+
+static void stellar_exdata_met_copy(void *_dst, const void *_src)
+{
+ struct exdata_meta *dst = (struct exdata_meta *)_dst, *src = (struct exdata_meta *)_src;
+ dst->free_func = src->free_func;
+ dst->free_arg = src->free_arg;
+ dst->idx = src->idx;
+ dst->name = src->name ? strdup(src->name) : NULL;
+}
+
+static void stellar_exdata_met_dtor(void *_elt)
+{
+ struct exdata_meta *elt = (struct exdata_meta *)_elt;
+ if (elt->name)
+ FREE(elt->name);
+}
+
+UT_icd stellar_exdata_meta_icd = {sizeof(struct exdata_meta), NULL, stellar_exdata_met_copy, stellar_exdata_met_dtor};
+
+int exdata_new_index(struct exdata_schema *s, const char *name, exdata_free *free_func,void *free_arg)
+{
+ if(s==NULL || name==NULL)return -1;
+ if(s->exdata_meta_array == NULL)
+ {
+ utarray_new(s->exdata_meta_array, &stellar_exdata_meta_icd);
+ }
+ if(s->exdata_meta_array == NULL)return -1;
+ unsigned int len = utarray_len(s->exdata_meta_array);
+ struct exdata_meta *t_schema;
+ for(unsigned int i = 0; i < len; i++)
+ {
+ t_schema = (struct exdata_meta *)utarray_eltptr(s->exdata_meta_array, i);
+ if(strcmp(t_schema->name, name) == 0)
+ {
+ t_schema->free_func=free_func;
+ t_schema->free_arg=free_arg;
+ return t_schema->idx;
+ }
+ }
+ struct exdata_meta new_schema;
+ memset(&new_schema, 0, sizeof(struct exdata_schema));
+ new_schema.free_func=free_func;
+ new_schema.name=(char *)name;
+ new_schema.idx=len;
+ new_schema.free_arg=free_arg;
+ utarray_push_back(s->exdata_meta_array, &new_schema);
+ return new_schema.idx;
+}
+
+/*******************************
+ * STELLAR EXDATA HANDLE API *
+ *******************************/
+struct exdata_handle *exdata_handle_new(struct exdata_schema *s)
+{
+ if(s==NULL || s->exdata_meta_array==NULL)return NULL;
+ struct exdata_handle *h = CALLOC(struct exdata_handle, 1);
+ h->schema=s;
+ unsigned int len = utarray_len(s->exdata_meta_array);
+ if(len > 0)
+ {
+ h->exdata_array=CALLOC(struct exdata, len);
+ }
+ return h;
+}
+
+void exdata_handle_reset(struct exdata_handle *h)
+{
+ if(h==NULL||h->schema==NULL||h->exdata_array==NULL)return;
+ unsigned int len=utarray_len(h->schema->exdata_meta_array);
+ for (unsigned int i = 0; i < len; i++)
+ {
+ void *exdata = (h->exdata_array + i)->exdata;
+ (h->exdata_array + i)->state=EXIT;
+ struct exdata_meta *schema = (struct exdata_meta *)utarray_eltptr(h->schema->exdata_meta_array, i);
+ if (exdata)
+ {
+ if (schema->free_func)
+ {
+ schema->free_func(i, exdata, schema->free_arg);
+ (h->exdata_array + i)->exdata=NULL;
+ }
+ }
+ (h->exdata_array + i)->state=INIT;
+ }
+ return;
+}
+
+void exdata_handle_free(struct exdata_handle *h)
+{
+ if(h==NULL)return;
+ exdata_handle_reset(h);
+ if(h->exdata_array)FREE(h->exdata_array);
+ FREE(h);
+}
+
+
+int exdata_set(struct exdata_handle *h, int idx, void *ex_ptr)
+{
+ if(h==NULL || h->schema == NULL|| h->exdata_array == NULL)return -1;
+ unsigned int len=utarray_len(h->schema->exdata_meta_array);
+ if(len < (unsigned int)idx)return -1;
+ if((h->exdata_array+idx)->state == EXIT)return -1;
+ (h->exdata_array+idx)->exdata=ex_ptr;
+ return 0;
+}
+
+void *exdata_get(struct exdata_handle *h, int idx)
+{
+ if(h==NULL || h->schema == NULL|| h->exdata_array == NULL)return NULL;
+ unsigned int len = utarray_len(h->schema->exdata_meta_array);
+ if(len < (unsigned int)idx)return NULL;
+ if((h->exdata_array+idx)->state == EXIT)return NULL;
+ return (h->exdata_array+idx)->exdata;
+} \ No newline at end of file
diff --git a/infra/exdata/exdata.h b/infra/exdata/exdata.h
new file mode 100644
index 0000000..862dbfc
--- /dev/null
+++ b/infra/exdata/exdata.h
@@ -0,0 +1,22 @@
+#pragma once
+
+typedef void exdata_free(int idx, void *ex_ptr, void *arg);
+
+struct exdata_schema;
+
+struct exdata_schema *exdata_schema_new();
+void exdata_schema_free(struct exdata_schema *s);
+
+int exdata_new_index(struct exdata_schema *schema, const char *name, exdata_free *free_func,void *free_arg);
+
+int exdata_schema_get_idx_by_name(struct exdata_schema *schema, const char *name);
+
+struct exdata_handle;
+
+struct exdata_handle *exdata_handle_new(struct exdata_schema *h);
+void exdata_handle_free(struct exdata_handle *h);
+void exdata_handle_reset(struct exdata_handle *h);
+
+int exdata_set(struct exdata_handle *h, int idx, void *ex_ptr);
+void *exdata_get(struct exdata_handle *h, int idx);
+
diff --git a/infra/exdata/exdata_internal.h b/infra/exdata/exdata_internal.h
new file mode 100644
index 0000000..9eb481d
--- /dev/null
+++ b/infra/exdata/exdata_internal.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include "uthash/utarray.h"
+
+#include "exdata.h"
+
+struct exdata_schema
+{
+ UT_array *exdata_meta_array;
+};
+
+struct exdata_meta
+{
+ char *name;
+ exdata_free *free_func;
+
+ void *free_arg;
+ int idx;
+}__attribute__((aligned(sizeof(void*))));
+
+
+enum exdata_state
+{ INIT, ACTIVE, EXIT };
+
+struct exdata
+{
+ void *exdata;
+ enum exdata_state state;
+};
+
+struct exdata_handle
+{
+ struct exdata_schema *schema;
+ struct exdata *exdata_array;
+}; \ No newline at end of file