summaryrefslogtreecommitdiff
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/aplwc_internal.h50
-rw-r--r--src/lib/main.c54
-rw-r--r--src/lib/memory.c55
3 files changed, 159 insertions, 0 deletions
diff --git a/src/lib/aplwc_internal.h b/src/lib/aplwc_internal.h
new file mode 100644
index 0000000..97a89ba
--- /dev/null
+++ b/src/lib/aplwc_internal.h
@@ -0,0 +1,50 @@
+#ifndef APLWC_INTERNAL_H
+#define APLWC_INTERNAL_H
+
+#include <aplwc.h>
+
+#define UNUSED_PARAMETER(arg) ((void)arg)
+
+#define RETURN_ERROR(aplwcp, rc, msg) do{ \
+ return ((aplwc)->last_error = (rc)); \
+ }while(0)
+
+#define NELEM(x) (sizeof(x)/sizeof(x[0]))
+
+#if APLWC_BUILD_TYPE_DEBUG
+ #define ALWAYS(x) ((x) ? 1 : (assert(0), 0))
+ #define NEVER(x) ((x) ? (assert(0), 1) : 0)
+#elif APLWC_BUILD_TYPE_RELEASE
+ #define ALWAYS(x) (X)
+ #define NEVER(X) (X)
+#elif APLWC_BUILD_TYPE_COVERAGE
+ #define ALWAYS(x) (1)
+ #define NEVER(x) (0)
+#endif
+
+#include <assert.h>
+#include <stdalign.h>
+#include <stdbool.h>
+#include <string.h>
+
+struct memory {
+ uint8_t *data;
+ size_t size;
+ size_t offset;
+};
+
+struct aplwc {
+ enum aplwc_rc last_error;
+ char last_error_msg[64];
+ struct memory memory;
+};
+
+/* errors.c */
+const char *rc_to_string(enum aplwc_rc);
+
+/* memory.c */
+struct memory memory_init(uint8_t *, size_t);
+struct aplwc *memory_alloc_aplwc(struct memory *);
+void memory_free_aplwc(struct memory *, struct aplwc *);
+
+#endif /* APLWC_INTERNAL_H */
diff --git a/src/lib/main.c b/src/lib/main.c
new file mode 100644
index 0000000..d44d6de
--- /dev/null
+++ b/src/lib/main.c
@@ -0,0 +1,54 @@
+#include "aplwc_internal.h"
+
+enum aplwc_rc
+aplwc_new(struct aplwc **p, uint8_t *data, size_t size)
+{
+ struct memory m;
+
+ m = memory_init(data, size);
+
+ *p = memory_alloc_aplwc(&m);
+ if(*p == NULL)
+ return APLWC_OUT_OF_MEMORY;
+ (*p)->memory = m;
+
+ return APLWC_OK;
+}
+
+enum aplwc_rc
+aplwc_destroy(struct aplwc *p)
+{
+ if(p)
+ memory_free_aplwc(&p->memory, p);
+
+ return APLWC_OK;
+}
+
+const char *
+aplwc_errstr_rc(enum aplwc_rc rc)
+{
+ switch(rc){
+ case APLWC_OK:
+ return "";
+ case APLWC_OUT_OF_MEMORY:
+ return "Out of memory";
+ default:
+ return "(unable to produce error string)";
+ }
+}
+
+const char *
+aplwc_errstr(struct aplwc *aplwc)
+{
+ enum { BUF_SIZE = 256 };
+
+ const char *err;
+ enum aplwc_rc rc;
+
+ err = NULL;
+
+ rc = aplwc ? aplwc->last_error : APLWC_RC_LAST+1;
+ err = aplwc_errstr_rc(rc);
+
+ return err;
+}
diff --git a/src/lib/memory.c b/src/lib/memory.c
new file mode 100644
index 0000000..187137e
--- /dev/null
+++ b/src/lib/memory.c
@@ -0,0 +1,55 @@
+#include "aplwc_internal.h"
+
+struct memory
+memory_init(uint8_t *data , size_t size)
+{
+ struct memory mem;
+
+ mem.data = data;
+ mem.size = size;
+ mem.offset = 0;
+ return mem;
+}
+
+static void *
+alloc(struct memory *m, size_t size, size_t align)
+{
+ uintptr_t ptr;
+ size_t alloc_size, adjust;
+ void *p;
+
+ ptr = (uintptr_t)m->data;
+ alloc_size = size;
+
+ if(NEVER(align == 0))
+ return NULL;
+ adjust = ptr % align;
+
+ if(adjust)
+ alloc_size += align - adjust;
+
+ if((m->size - m->offset) >= alloc_size){
+ p = m->data+m->offset+alloc_size-size;
+ m->offset += alloc_size;
+ memset(p, 0, size);
+ }else
+ p = NULL;
+
+ return p;
+}
+
+struct aplwc *
+memory_alloc_aplwc(struct memory *m)
+{
+ struct aplwc *p;
+
+ p = alloc(m, sizeof(struct aplwc), alignof(struct aplwc));
+ return p;
+}
+
+void
+memory_free_aplwc(struct memory *m, struct aplwc *p)
+{
+ UNUSED_PARAMETER(m);
+ UNUSED_PARAMETER(p);
+}