Commit ac8cff75dacf87d923dc5d5e78c6f53ae79f985a

Thomas de Grivel 2020-01-09T15:24:35

import from libdata 0.1

diff --git a/data.c b/data.c
new file mode 100644
index 0000000..f2e3e52
--- /dev/null
+++ b/data.c
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2018 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <strings.h>
+#include "data.h"
+
+s_data_type g_data_alloc_type = {
+  sizeof(s_data_alloc) * 8,
+  DATA_TYPE_BITS
+};
+s_data_alloc g_data_alloc;
+
+s_data_type g_data_type_type = {
+  sizeof(u_data_type) * 8,
+  DATA_TYPE_BITS
+};
+s_data_alloc *g_data_type_alloc = 0;
+
+int libdata_init ()
+{
+  data_alloc_init(&g_data_alloc, &g_data_alloc_type,
+                  DATA_ALLOC_MAX, 0, (f_data_clean*) data_alloc_clean);
+  return 0;
+}
+
+void data_alloc_init (s_data_alloc *da, s_data_type *t,
+                      unsigned int max, f_data_init *init,
+                      f_data_clean *clean)
+{
+  assert(da);
+  assert(t);
+  da->t = t;
+  da->max = max;
+  da->mem = calloc(max, (t->bits + 7) / 8);
+  da->n = 0;
+  da->free = calloc(max, sizeof(unsigned int));
+  da->free_n = 0;
+  da->init = init;
+  da->clean = clean;
+}
+
+void data_alloc_clean (s_data_alloc *da)
+{
+  assert(da);
+  bzero(da->mem, da->max * ((da->t->bits + 7) / 8));
+  bzero(da->free, da->max * sizeof(unsigned int));
+  free(da->mem);
+  free(da->free);
+}
+
+static inline
+void * data_new_at (s_data_alloc *da, unsigned int i)
+{
+  unsigned int octets = (da->t->bits + 7) / 8;
+  unsigned int offset = i * octets;
+  void *m = da->mem + offset;
+  bzero(m, octets);
+  if (da->init)
+    da->init(m);
+  return m;
+}
+
+void * data_new (s_data_alloc *da)
+{
+  assert(da);
+  if (da->free_n) {
+    unsigned int i = da->free[--da->free_n];
+    da->free[da->free_n] = 0;
+    return data_new_at(da, i);
+  }
+  if (da->n < da->max) {
+    unsigned int i = da->n++;
+    return data_new_at(da, i);
+  }
+  return 0;
+}
+
+int data_new_i (s_data_alloc *da)
+{
+  assert(da);
+  if (da->free_n) {
+    unsigned int i = da->free[--da->free_n];
+    da->free[da->free_n] = 0;
+    data_new_at(da, i);
+    return i;
+  }
+  if (da->n < da->max) {
+    unsigned int i = da->n++;
+    data_new_at(da, i);
+    return i;
+  }
+  return -1;
+}
+
+void data_delete (s_data_alloc *da, void *data)
+{
+  unsigned int octets;
+  unsigned int i;
+  assert(da);
+  assert(da->t);
+  octets = ((da->t->bits + 7) / 8);
+  assert(da->mem <= data);
+  assert(data < da->mem + da->max * octets);
+  if (da->clean)
+    da->clean(data);
+  bzero(data, octets);
+  i = (data - da->mem) / octets;
+  da->free[da->free_n++] = i;
+}
+
+s_data_alloc * data_alloc_new (s_data_type *t, unsigned int max,
+                               f_data_init *init, f_data_clean *clean)
+{
+  s_data_alloc *da = data_new(&g_data_alloc);
+  assert(da);
+  data_alloc_init(da, t, max, init, clean);
+  return da;
+}
+
+void data_alloc_delete (s_data_alloc *da)
+{
+  assert(da);
+  data_delete(&g_data_alloc, da);
+}
+
+u_data_type * data_type_new (unsigned int bits, unsigned int type)
+{
+  u_data_type *t;
+  if (!g_data_type_alloc)
+    g_data_type_alloc = data_alloc_new(&g_data_type_type, DATA_TYPE_MAX,
+                                       0, 0);
+  assert(g_data_type_alloc);
+  t = data_new(g_data_type_alloc);
+  assert(t);
+  t->t.bits = bits;
+  t->t.type = type;
+  return t;
+}
+
+void data_type_delete (s_data_type *t)
+{
+  assert(g_data_type_alloc);
+  data_delete(g_data_type_alloc, t);
+}
diff --git a/data.h b/data.h
new file mode 100644
index 0000000..8e61f96
--- /dev/null
+++ b/data.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2018 Thomas de Grivel <thoxdg@gmail.com> +33614550127
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#ifndef DATA_H
+#define DATA_H
+
+typedef enum {
+  DATA_TYPE_BITS,
+  DATA_TYPE_VECTOR,
+  DATA_TYPE_INTEGER,
+  DATA_TYPE_FLOAT,
+  DATA_TYPE_STRUCT
+} e_data_type;
+
+#define DATA_TYPE_SIGNED     1
+#define DATA_TYPE_BIG_ENDIAN 2
+
+typedef struct data_type {
+  unsigned int bits;
+  unsigned int type;
+} s_data_type;
+
+typedef struct data_type_vector {
+  s_data_type  t;
+  s_data_type *element_type;
+  unsigned int nmemb;
+} s_data_type_vector;
+
+typedef struct data_type_integer {
+  s_data_type  t;
+  unsigned int flags;
+} s_data_type_integer;
+
+typedef struct data_type_float {
+  s_data_type t;
+} s_data_type_float;
+
+typedef struct data_type_struct {
+  s_data_type  t;
+  s_data_type *first;
+  struct data_type_struct *rest;
+} s_data_type_struct;
+
+typedef union data_type_ {
+  s_data_type         t;
+  s_data_type_vector  t_vector;
+  s_data_type_integer t_integer;
+  s_data_type_float   t_float;
+  s_data_type_struct  t_struct;
+} u_data_type;
+
+#define DATA_TYPE_MAX 1024
+
+u_data_type * data_type_new (unsigned int bits, unsigned int type);
+void          data_type_delete (s_data_type *t);
+
+typedef void f_data_init (void *data);
+typedef void f_data_clean (void *data);
+
+typedef struct data_alloc {
+  s_data_type  *t;
+  unsigned int  max;
+  void         *mem;
+  unsigned int  n;
+  unsigned int *free;
+  unsigned int  free_n;
+  f_data_init  *init;
+  f_data_clean *clean;
+} s_data_alloc;
+
+#define DATA_ALLOC_MAX 1024
+
+void * data_new (s_data_alloc *da);
+int    data_new_i (s_data_alloc *da);
+void   data_delete (s_data_alloc *da, void *data);
+
+void           data_alloc_init (s_data_alloc *da, s_data_type *t,
+                                unsigned int max, f_data_init *init,
+                                f_data_clean *clean);
+void           data_alloc_clean (s_data_alloc *da);
+s_data_alloc * data_alloc_new (s_data_type *t,
+                               unsigned int max, f_data_init *init,
+                               f_data_clean *clean);
+void           data_alloc_delete (s_data_alloc *da);
+
+int libdata_init ();
+
+#endif