aboutsummaryrefslogtreecommitdiff
path: root/src/memory.c
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-04-17 18:14:35 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-04-17 18:14:35 -0700
commitdca72268ae6bcbd411aa8660604451226f76b4eb (patch)
tree741be97c97ef4fe1a023882267b06ec7eac78527 /src/memory.c
parent998ee2ce7110987bb5cbeb11a55781a271a1ca47 (diff)
chore: basic maintenance
Diffstat (limited to 'src/memory.c')
-rw-r--r--src/memory.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/memory.c b/src/memory.c
new file mode 100644
index 0000000..3d35299
--- /dev/null
+++ b/src/memory.c
@@ -0,0 +1,49 @@
+#include <u.h>
+
+// -------------------------------------------------------------------------
+// Dynamic buffer.
+
+/* Grow to particular size */
+void*
+bufgrow(void* buf, vlong newLen, vlong eltsize)
+{
+ Assert(bufcap(buf) <= (SIZE_MAX - 1) / 2);
+
+ vlong newCap = MAX(16, MAX(1 + 2 * bufcap(buf), newLen));
+
+ Assert(newLen <= newCap);
+ Assert(newCap <= (SIZE_MAX - offsetof(bufHdr, buf)) / eltsize);
+
+ vlong newSize = offsetof(bufHdr, buf) + newCap * eltsize;
+
+ bufHdr* newHdr;
+ if (buf) {
+ newHdr = _bufHdr(buf);
+ newHdr = (bufHdr*)realloc((void*)newHdr, newSize);
+ } else {
+ newHdr = (bufHdr*)malloc(newSize);
+ newHdr->len = 0;
+ }
+
+ newHdr->cap = newCap;
+ return (void*)newHdr->buf;
+}
+
+/* Pop out a value */
+void
+_bufpop(void *buf, int i, vlong eltsize)
+{
+ int n;
+ byte *b;
+ byte stk[1024];
+ Assert(eltsize < sizeof(stk));
+
+ b = (byte*) buf;
+ if (n = buflen(buf), i < n) {
+ memcpy(stk, b+eltsize*i, eltsize);
+ memcpy(b+eltsize*i, b+eltsize*(i+1), eltsize*(n-i-1));
+ memcpy(b+eltsize*(n-1), stk, eltsize);
+ }
+ _bufHdr(buf)->len--;
+}
+