agssim: always initialize next instruction to NULL
[rofl0r-agsutils.git] / MemGrow.c
blobbd99e9712d2da83e7d2114b33077a5c9c7be483d
1 #include "MemGrow.h"
2 #include <string.h>
3 #include <stdlib.h>
4 #include <limits.h>
5 #include <fcntl.h>
6 #include <unistd.h>
7 #ifndef PAGE_SIZE
8 #define PAGE_SIZE 4096
9 #endif
11 void mem_init(MG* mem) {
12 memset(mem, 0, sizeof *mem);
15 void mem_free(MG* mem) {
16 if(mem->mem) free(mem->mem);
17 mem_init(mem);
20 /* returns 1 if realloc was necessary, -1 if no realloc was necessary, 0 when realloc failed */
21 int mem_grow_if_needed(MG *mem, size_t newsize) {
22 if(newsize > mem->capa) {
23 size_t nucap = mem->capa * 2;
24 if(newsize > nucap) {
25 nucap = newsize;
26 if(nucap & (PAGE_SIZE -1)) {
27 nucap += PAGE_SIZE;
28 nucap &= ~(PAGE_SIZE -1);
31 void *nu = realloc(mem->mem, nucap);
32 if(!nu) return 0;
33 mem->mem = nu;
34 mem->capa = nucap;
35 return 1;
37 return -1;
40 int mem_write(MG *mem, size_t offset, void* data, size_t size) {
41 int ret;
42 size_t needed = offset + size;
43 if(needed < offset) return 0; /* overflow */
44 if((ret = mem_grow_if_needed(mem, needed))) {
45 memcpy((char*) mem->mem + offset, data, size);
46 if(needed > mem->used) mem->used = needed;
48 return ret;
51 int mem_append(MG *mem, void* data, size_t size) {
52 return mem_write(mem, mem->used, data, size);
55 void* mem_getptr(MG* mem, size_t offset, size_t byteswanted) {
56 if(!mem->mem || offset + byteswanted > mem->used) return 0;
57 return (char*)mem->mem + offset;
60 void mem_set(MG* mem, void* data, size_t used, size_t allocated) {
61 mem->mem = data;
62 mem->used = used;
63 mem->capa = allocated;
66 int mem_write_stream(MG* mem, FILE* out) {
67 if(!mem->mem || !mem->used) return 0;
68 int ret = (fwrite(mem->mem, 1, mem->used, out) == mem->used);
69 return ret;
72 int mem_write_file(MG* mem, char* fn) {
73 FILE *out = fopen(fn, "w");
74 if(!out) return 0;
75 int ret = mem_write_stream(mem, out);
76 fclose(out);
77 return ret;