util: add fixed-size stack
This commit is contained in:
parent
55d3da43a2
commit
6bd5e2dbab
71
util/stack.c
Normal file
71
util/stack.c
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
#include "stack.h"
|
||||||
|
#include "../runtime/stdio.h"
|
||||||
|
#include <memory.h>
|
||||||
|
|
||||||
|
|
||||||
|
void stack_InitBuffered(stack *s, void *buffer, uintptr_t size) {
|
||||||
|
s->data = buffer;
|
||||||
|
s->size = size;
|
||||||
|
s->top = buffer + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack_PushByte(stack *s, const uint8_t b) {
|
||||||
|
if (s->top <= s->data) {
|
||||||
|
io_Printf("stack_PushByte: full[%llu bytes], discarding byte 0x%x\n", s->size, b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint8_t *)--s->top = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t stack_PopByte(stack *s) {
|
||||||
|
if (s->top == s->data + s->size) {
|
||||||
|
io_WriteConsoleASCII("stack_PopByte: popping an empty stack\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return *(uint8_t *)s->top++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack_Push(stack *s, const void *buffer, uintptr_t size) {
|
||||||
|
if (stack_Space(s) < size) {
|
||||||
|
io_Printf("stack_Push: insufficient space (%d/%d bytes, want %d bytes)\n", stack_Size(s), s->size, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s->top -= size;
|
||||||
|
memcpy(s->top, buffer, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t stack_Pop(stack *s, void *buffer, uintptr_t size) {
|
||||||
|
if (stack_Size(s) < size)
|
||||||
|
return 0;
|
||||||
|
memcpy(buffer, s->top, size);
|
||||||
|
s->top += size;
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t stack_TopByte(stack *s) {
|
||||||
|
if (stack_Empty(s)) {
|
||||||
|
io_WriteConsoleASCII("stack_TopByte: called on an empty stack\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return *(uint8_t *)s->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t stack_Top(stack *s, void *buffer, uintptr_t size) {
|
||||||
|
if (stack_Size(s) < size)
|
||||||
|
return 0;
|
||||||
|
memcpy(buffer, s->top, size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool stack_Empty(stack *s) {
|
||||||
|
return s->top == s->data + s->size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t stack_Size(stack *s) {
|
||||||
|
return s->data + s->size - s->top;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t stack_Space(stack *s) {
|
||||||
|
return s->top - s->data;
|
||||||
|
}
|
52
util/stack.h
Normal file
52
util/stack.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../main.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
void * data; // the data buffer
|
||||||
|
uintptr_t size; // size of data buffer
|
||||||
|
void * top; // top of the stack, the stack grows downward (from data+size to data)
|
||||||
|
} stack;
|
||||||
|
|
||||||
|
// initialize a stack with a existing buffer
|
||||||
|
void stack_InitBuffered(stack *s, void *buffer, uintptr_t size);
|
||||||
|
|
||||||
|
// pushes one byte to the stack, discarding if full
|
||||||
|
void stack_PushByte(stack *s, const uint8_t b);
|
||||||
|
|
||||||
|
// pops one byte from the top of the stack, returning it
|
||||||
|
uint8_t stack_PopByte(stack *s);
|
||||||
|
|
||||||
|
// pushes Size bytes to the stack, none written if there is not space for all the bytes
|
||||||
|
void stack_Push(stack *s, const void *buffer, uintptr_t size);
|
||||||
|
|
||||||
|
// pops Size bytes from the stack, none popped if there are no enough data
|
||||||
|
// returns the number of bytes popped (either Size or 0)
|
||||||
|
uintptr_t stack_Pop(stack *s, void *buffer, uintptr_t size);
|
||||||
|
|
||||||
|
// return the byte at the top of the stack
|
||||||
|
uint8_t stack_TopByte(stack *s);
|
||||||
|
|
||||||
|
// copy the bytes at the top of the stack
|
||||||
|
// returns the number of bytes copied
|
||||||
|
uintptr_t stack_Top(stack *s, void *buffer, uintptr_t size);
|
||||||
|
|
||||||
|
// tells if the stack is empty
|
||||||
|
bool stack_Empty(stack *s);
|
||||||
|
|
||||||
|
// returns the number of bytes in the stack
|
||||||
|
uintptr_t stack_Size(stack *s);
|
||||||
|
|
||||||
|
// returns the empty space left in the stack
|
||||||
|
uintptr_t stack_Space(stack *s);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user