blob: da56e3981bcd66ccb6b82af29dfcf85bf600f261 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001#define IN_BALLOC
2
3#include "uemf.h"
4#include <stdarg.h>
5#include <stdlib.h>
6
7static bType *bQhead[B_MAX_CLASS];
8static char *bFreeBuf;
9static char *bFreeNext;
10static int bFreeSize;
11static int bFreeLeft;
12static int bFlags = B_USE_MALLOC;
13static int bopenCount = 0;
14
15static int ballocGetSize(int size, int *q);
16
17int bopen(void *buf, int bufsize, int flags)
18{
19 bFlags = flags;
20
21 if (++bopenCount > 1) {
22 return 0;
23 }
24
25 if (buf == NULL) {
26 if (bufsize == 0) {
27 bufsize = B_DEFAULT_MEM;
28 }
29 if ((buf = malloc(bufsize)) == NULL) {
30 --bopenCount;
31 return -1;
32 }
33 } else {
34 bFlags |= B_USER_BUF;
35 }
36
37 bFreeSize = bFreeLeft = bufsize;
38 bFreeBuf = bFreeNext = buf;
39 memset(bQhead, 0, sizeof(bQhead));
40 return 0;
41}
42
43void bclose()
44{
45 if (--bopenCount <= 0 && !(bFlags & B_USER_BUF)) {
46 free(bFreeBuf);
47 bopenCount = 0;
48 }
49}
50
51bType *balloc_tmp;
52void *balloc(B_ARGS_DEC, int size)
53{
54 bType *bp;
55 int q, memSize;
56
57 if (bFreeBuf == NULL) {
58 if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) {
59 return NULL;
60 }
61 }
62 if (size < 0) {
63 return NULL;
64 }
65
66 memSize = ballocGetSize(size+1, &q);
67
68 if (q >= B_MAX_CLASS) {
69 if (bFlags & B_USE_MALLOC) {
70 bp = (bType*) malloc(memSize);
71 if (bp == NULL) {
72 traceRaw(T("B: malloc failed\n"));
73 return NULL;
74 }
75
76 } else {
77 traceRaw(T("B: malloc failed\n"));
78 return NULL;
79 }
80 bp->u.size = memSize - sizeof(bType);
81 bp->flags = B_MALLOCED;
82
83 } else if ((bp = bQhead[q]) != NULL) {
84#ifdef WEBS_SECURITY
85 bType *tmp = bp->u.next;
86 if(tmp != NULL)
87 balloc_tmp = tmp->u.next;
88#endif
89 bQhead[q] = bp->u.next;
90
91 bp->u.size = memSize - sizeof(bType);
92 bp->flags = 0;
93
94 } else {
95 if (bFreeLeft > memSize) {
96
97 bp = (bType*) bFreeNext;
98
99 bFreeNext += memSize;
100 bFreeLeft -= memSize;
101
102 bp->u.size = memSize - sizeof(bType);
103 bp->flags = 0;
104
105 } else if (bFlags & B_USE_MALLOC) {
106
107 if ((bp = (bType*) malloc(memSize)) == NULL) {
108 traceRaw(T("B: malloc failed\n"));
109 return NULL;
110 }
111 bp->u.size = memSize - sizeof(bType);
112 bp->flags = B_MALLOCED;
113
114 } else {
115 traceRaw(T("B: malloc failed\n"));
116 return NULL;
117 }
118 }
119
120 bp->flags |= B_INTEGRITY;
121
122 return (void*) ((char*) bp + sizeof(bType));
123}
124
125void bfree(B_ARGS_DEC, void *mp)
126{
127 bType *bp;
128 int q, memSize;
129
130 bp = (bType*) ((char*) mp - sizeof(bType));
131
132 a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
133
134 if ((bp->flags & B_INTEGRITY_MASK) != B_INTEGRITY) {
135 return;
136 }
137
138 memSize = ballocGetSize(bp->u.size, &q);
139
140 if (bp->flags & B_MALLOCED) {
141 free(bp);
142 return;
143 }
144
145 bp->u.next = bQhead[q];
146 bQhead[q] = bp;
147
148 bp->flags = B_FILL_WORD;
149}
150
151
152void bfreeSafe(B_ARGS_DEC, void *mp)
153{
154 if (mp) {
155 bfree(B_ARGS, mp);
156 }
157}
158
159char_t *bstrdup(B_ARGS_DEC, char_t *s)
160{
161 char_t *cp;
162 int len;
163
164 if (s == NULL) {
165 s = T("");
166 }
167 len = gstrlen(s) + 1;
168 if ((cp = balloc(B_ARGS, len * sizeof(char_t))) != NULL) {
169 gstrcpy(cp, s);
170 }
171 return cp;
172}
173
174void *brealloc(B_ARGS_DEC, void *mp, int newsize)
175{
176 bType *bp;
177 void *newbuf;
178
179 if (mp == NULL) {
180 return balloc(B_ARGS, newsize);
181 }
182 bp = (bType*) ((char*) mp - sizeof(bType));
183 a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
184
185 if (bp->u.size >= newsize) {
186 return mp;
187 }
188 if ((newbuf = balloc(B_ARGS, newsize)) != NULL) {
189 memcpy(newbuf, mp, bp->u.size);
190 bfree(B_ARGS, mp);
191 }
192 return newbuf;
193}
194
195static int ballocGetSize(int size, int *q)
196{
197 int mask;
198
199 mask = (size == 0) ? 0 : (size-1) >> B_SHIFT;
200 for (*q = 0; mask; mask >>= 1) {
201 *q = *q + 1;
202 }
203 return ((1 << (B_SHIFT + *q)) + sizeof(bType));
204}
205
206