aboutsummaryrefslogtreecommitdiffstats
path: root/src/stack.h
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-05-12 22:44:36 +0200
committerDavid Robillard <d@drobilla.net>2020-10-27 13:13:58 +0100
commit255fc4d36518728e8367feafb4a154e14b2b35d0 (patch)
tree4e5b6907ca9288ae2d3aa649cce7a39f83cf185a /src/stack.h
parent95f7334bbc02f3e75b33b9914eee58c69f1588bd (diff)
downloadserd-255fc4d36518728e8367feafb4a154e14b2b35d0.tar.gz
serd-255fc4d36518728e8367feafb4a154e14b2b35d0.tar.bz2
serd-255fc4d36518728e8367feafb4a154e14b2b35d0.zip
Simplify stack management by popping in bulk at higher levels
Since all memory used by the reader is POD in the stack, there is no benefit to forcing code to explicitly pop everything pushed to the stack, since any function can record an offset and pop back down to it regardless of what its callers pushed if it knows that it does not need those items.
Diffstat (limited to 'src/stack.h')
-rw-r--r--src/stack.h33
1 files changed, 11 insertions, 22 deletions
diff --git a/src/stack.h b/src/stack.h
index 174c6378..cbbe6b18 100644
--- a/src/stack.h
+++ b/src/stack.h
@@ -22,6 +22,7 @@
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
+#include <string.h>
/** An offset to start the stack at. Note 0 is reserved for NULL. */
#define SERD_STACK_BOTTOM sizeof(void*)
@@ -80,40 +81,28 @@ serd_stack_pop(SerdStack* stack, size_t n_bytes)
stack->size -= n_bytes;
}
+static inline void
+serd_stack_pop_to(SerdStack* stack, size_t n_bytes)
+{
+ assert(stack->size >= n_bytes);
+ stack->size = n_bytes;
+}
+
static inline void*
serd_stack_push_aligned(SerdStack* stack, size_t n_bytes, size_t align)
{
- // Push one byte to ensure space for a pad count
- if (!serd_stack_push(stack, 1)) {
- return NULL;
- }
-
// Push padding if necessary
const size_t pad = align - stack->size % align;
if (pad > 0) {
- if (!serd_stack_push(stack, pad)) {
+ void* padding = serd_stack_push(stack, pad);
+ if (!padding) {
return NULL;
}
+ memset(padding, 0, pad);
}
- // Set top of stack to pad count so we can properly pop later
- stack->buf[stack->size - 1] = (char)pad;
-
// Push requested space at aligned location
return serd_stack_push(stack, n_bytes);
}
-static inline void
-serd_stack_pop_aligned(SerdStack* stack, size_t n_bytes)
-{
- // Pop requested space down to aligned location
- serd_stack_pop(stack, n_bytes);
-
- // Get amount of padding from top of stack
- const uint8_t pad = (uint8_t)stack->buf[stack->size - 1];
-
- // Pop padding and pad count
- serd_stack_pop(stack, pad + 1u);
-}
-
#endif // SERD_STACK_H