153 lines
3.3 KiB
C
153 lines
3.3 KiB
C
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
typedef struct arena_s Arena;
|
|
struct arena_s {
|
|
unsigned char *tape;
|
|
unsigned int count;
|
|
unsigned int capacity;
|
|
};
|
|
|
|
void *aalloc(Arena *arena, unsigned int size){
|
|
unsigned int pos;
|
|
if(arena == NULL) return NULL;
|
|
if(arena->count + size > arena->capacity) return NULL;
|
|
|
|
pos = arena->count;
|
|
arena->count += size;
|
|
return (void *)&arena->tape[pos];
|
|
}
|
|
|
|
unsigned int
|
|
scpy(char *to, const char *from, unsigned int length)
|
|
{
|
|
unsigned int i;
|
|
if(to == NULL || from == NULL) return -1;
|
|
if(length == 0) return 0;
|
|
for(i = 0; i < length - 1 && from[i] != '\0'; i++) to[i] = from[i];
|
|
to[i] = '\0';
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
ascpy(Arena *arena, const char *start, unsigned int length)
|
|
{
|
|
char *str;
|
|
if(!start) return NULL;
|
|
str = (char *)aalloc(arena, length + 1);
|
|
if(!str) return NULL;
|
|
scpy(str, start, length);
|
|
return str;
|
|
}
|
|
|
|
void *
|
|
areturn(Arena *arena, unsigned int checkpoint, const void *src, unsigned int size)
|
|
{
|
|
void *dest;
|
|
if(arena == NULL || src == NULL) return NULL;
|
|
|
|
dest = (void *)&arena->tape[checkpoint];
|
|
if (src == dest) return dest;
|
|
|
|
memmove(dest, src, size);
|
|
arena->count = checkpoint + size;
|
|
|
|
return dest;
|
|
}
|
|
|
|
#define ARENA_RETURN(arena, ckpt, src_ptr, type) \
|
|
return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type))
|
|
|
|
#define ARENA_RETURN_ARRAY(arena, ckpt, src_ptr, type, count) \
|
|
return (type *)areturn((arena), (ckpt), (src_ptr), sizeof(type) * (count))
|
|
|
|
typedef struct Point Point;
|
|
struct Point {
|
|
unsigned int x;
|
|
unsigned int y;
|
|
};
|
|
|
|
Point *
|
|
Point_new(Arena *a, unsigned int x, unsigned int y)
|
|
{
|
|
Point *this = (Point *)aalloc(a, sizeof(Point));
|
|
this->x = x;
|
|
this->y = y;
|
|
return this;
|
|
}
|
|
|
|
char*
|
|
Point_toS(Arena *a, Point *this)
|
|
{
|
|
unsigned int ckpt = a->count;
|
|
char *s = (char*)&a->tape[a->count];
|
|
int len = sprintf(s, "[x:%d, y:%d]",
|
|
this->x,
|
|
this->y);
|
|
s[len] = '\0';
|
|
a->count += len + 1;
|
|
ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1);
|
|
}
|
|
|
|
typedef struct Rect Rect;
|
|
struct Rect {
|
|
Point top_left;
|
|
Point bottom_right;
|
|
unsigned int width;
|
|
unsigned int height;
|
|
};
|
|
|
|
Rect *
|
|
Rect_new(Arena *a, Point *tl, Point *br, unsigned int width, unsigned int height)
|
|
{
|
|
Rect *this = (Rect *)aalloc(a, sizeof(Rect));
|
|
memcpy(&this->top_left, tl, sizeof(Point));
|
|
memcpy(&this->bottom_right, br, sizeof(Point));
|
|
this->width = width;
|
|
this->height = height;
|
|
return this;
|
|
}
|
|
|
|
char*
|
|
Rect_toS(Arena *a, Rect *this)
|
|
{
|
|
unsigned int ckpt = a->count;
|
|
char *s1 = Point_toS(a, &this->top_left);
|
|
char *s2 = Point_toS(a, &this->bottom_right);
|
|
|
|
char *s = (char*)&a->tape[a->count];
|
|
int len = sprintf(s, "[top_left: %s, bottom_right: %s, width:%d, height:%d]",
|
|
s1,
|
|
s2,
|
|
this->width,
|
|
this->height);
|
|
s[len] = '\0';
|
|
a->count += len + 1;
|
|
ARENA_RETURN_ARRAY(a, ckpt, s, char, len + 1);
|
|
}
|
|
|
|
Rect *
|
|
create_geometry(Arena *a)
|
|
{
|
|
unsigned int ckpt = a->count;
|
|
Rect *final_rect;
|
|
Point *temp_tl;
|
|
Point *temp_br;
|
|
|
|
temp_tl = Point_new(a, 10, 20);
|
|
temp_br = Point_new(a, 100, 200);
|
|
|
|
final_rect = Rect_new(a, temp_tl, temp_br, 90, 180);
|
|
|
|
ARENA_RETURN(a, ckpt, final_rect, Rect);
|
|
}
|
|
|
|
int main() {
|
|
unsigned char tape[64000];
|
|
Arena a = {tape, 0, 64000};
|
|
Rect *r = create_geometry(&a);
|
|
printf("%s\n", Rect_toS(&a, r));
|
|
return 0;
|
|
}
|