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