1 // implementation of generic tools
2
3 #include "tools.h"
4 #include <new>
5
6 //////////////////////////// pool ///////////////////////////
7
pool()8 pool::pool()
9 {
10 blocks = 0;
11 allocnext(POOLSIZE);
12 for(int i = 0; i<MAXBUCKETS; i++) reuse[i] = NULL;
13 };
14
alloc(size_t size)15 void *pool::alloc(size_t size)
16 {
17 if(size>MAXREUSESIZE)
18 {
19 return malloc(size);
20 }
21 else
22 {
23 size = bucket(size);
24 void **r = (void **)reuse[size];
25 if(r)
26 {
27 reuse[size] = *r;
28 return (void *)r;
29 }
30 else
31 {
32 size <<= PTRBITS;
33 if(left<size) allocnext(POOLSIZE);
34 char *r = p;
35 p += size;
36 left -= size;
37 return r;
38 };
39 };
40 };
41
dealloc(void * p,size_t size)42 void pool::dealloc(void *p, size_t size)
43 {
44 if(size>MAXREUSESIZE)
45 {
46 free(p);
47 }
48 else
49 {
50 size = bucket(size);
51 if(size) // only needed for 0-size free, are there any?
52 {
53 *((void **)p) = reuse[size];
54 reuse[size] = p;
55 };
56 };
57 };
58
realloc(void * p,size_t oldsize,size_t newsize)59 void *pool::realloc(void *p, size_t oldsize, size_t newsize)
60 {
61 void *np = alloc(newsize);
62 if(!oldsize) return np;
63 memcpy(np, p, newsize>oldsize ? oldsize : newsize);
64 dealloc(p, oldsize);
65 return np;
66 };
67
dealloc_block(void * b)68 void pool::dealloc_block(void *b)
69 {
70 if(b)
71 {
72 dealloc_block(*((char **)b));
73 free(b);
74 };
75 }
76
allocnext(size_t allocsize)77 void pool::allocnext(size_t allocsize)
78 {
79 char *b = (char *)malloc(allocsize+PTRSIZE);
80 *((char **)b) = blocks;
81 blocks = b;
82 p = b+PTRSIZE;
83 left = allocsize;
84 };
85
string(char * s,size_t l)86 char *pool::string(char *s, size_t l)
87 {
88 char *b = (char *)alloc(l+1);
89 strncpy(b,s,l);
90 b[l] = 0;
91 return b;
92 };
93
gp()94 pool *gp() // useful for global buffers that need to be initialisation order independant
95 {
96 static pool *p = NULL;
97 return p ? p : (p = new pool());
98 };
99
100
101 ///////////////////////// misc tools ///////////////////////
102
path(char * s)103 char *path(char *s)
104 {
105 for(char *t = s; t = strpbrk(t, "/\\"); *t++ = PATHDIV);
106 return s;
107 };
108
loadfile(char * fn,int * size)109 char *loadfile(char *fn, int *size)
110 {
111 FILE *f = fopen(fn, "rb");
112 if(!f) return NULL;
113 fseek(f, 0, SEEK_END);
114 int len = ftell(f);
115 fseek(f, 0, SEEK_SET);
116 char *buf = (char *)malloc(len+1);
117 if(!buf) return NULL;
118 buf[len] = 0;
119 size_t rlen = fread(buf, 1, len, f);
120 fclose(f);
121 if(len!=rlen || len<=0)
122 {
123 free(buf);
124 return NULL;
125 };
126 if(size!=NULL) *size = len;
127 return buf;
128 };
129
endianswap(void * memory,int stride,int length)130 void endianswap(void *memory, int stride, int length) // little indians as storage format
131 {
132 if(*((char *)&stride)) return;
133 loop(w, length) loop(i, stride/2)
134 {
135 uchar *p = (uchar *)memory+w*stride;
136 uchar t = p[i];
137 p[i] = p[stride-i-1];
138 p[stride-i-1] = t;
139 };
140 }
141