1 | /* |
2 | * << Haru Free PDF Library >> -- hpdf_mmgr.c |
3 | * |
4 | * URL: http://libharu.org |
5 | * |
6 | * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp> |
7 | * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org> |
8 | * |
9 | * Permission to use, copy, modify, distribute and sell this software |
10 | * and its documentation for any purpose is hereby granted without fee, |
11 | * provided that the above copyright notice appear in all copies and |
12 | * that both that copyright notice and this permission notice appear |
13 | * in supporting documentation. |
14 | * It is provided "as is" without express or implied warranty. |
15 | * |
16 | */ |
17 | |
18 | #include "hpdf_conf.h" |
19 | #include "hpdf_consts.h" |
20 | #include "hpdf_mmgr.h" |
21 | #include "hpdf_utils.h" |
22 | |
23 | #ifndef HPDF_STDCALL |
24 | #ifdef HPDF_DLL_MAKE |
25 | #define HPDF_STDCALL __stdcall |
26 | #else |
27 | #ifdef HPDF_DLL |
28 | #define HPDF_STDCALL __stdcall |
29 | #else |
30 | #define HPDF_STDCALL |
31 | #endif |
32 | #endif |
33 | #endif |
34 | |
35 | static void * HPDF_STDCALL |
36 | InternalGetMem (HPDF_UINT size); |
37 | |
38 | static void HPDF_STDCALL |
39 | InternalFreeMem (void* aptr); |
40 | |
41 | |
42 | HPDF_MMgr |
43 | HPDF_MMgr_New (HPDF_Error error, |
44 | HPDF_UINT buf_size, |
45 | HPDF_Alloc_Func alloc_fn, |
46 | HPDF_Free_Func free_fn) |
47 | { |
48 | HPDF_MMgr mmgr; |
49 | |
50 | HPDF_PTRACE((" HPDF_MMgr_New\n" )); |
51 | |
52 | if (alloc_fn) |
53 | mmgr = (HPDF_MMgr)alloc_fn (sizeof(HPDF_MMgr_Rec)); |
54 | else |
55 | mmgr = (HPDF_MMgr)InternalGetMem (sizeof(HPDF_MMgr_Rec)); |
56 | |
57 | HPDF_PTRACE(("+%p mmgr-new\n" , mmgr)); |
58 | |
59 | if (mmgr != NULL) { |
60 | /* initialize mmgr object */ |
61 | mmgr->error = error; |
62 | |
63 | |
64 | #ifdef HPDF_MEM_DEBUG |
65 | mmgr->alloc_cnt = 0; |
66 | mmgr->free_cnt = 0; |
67 | #endif |
68 | /* |
69 | * if alloc_fn and free_fn are specified, these function is |
70 | * used. if not, default function (maybe these will be "malloc" and |
71 | * "free") is used. |
72 | */ |
73 | if (alloc_fn && free_fn) { |
74 | mmgr->alloc_fn = alloc_fn; |
75 | mmgr->free_fn = free_fn; |
76 | } else { |
77 | mmgr->alloc_fn = InternalGetMem; |
78 | mmgr->free_fn = InternalFreeMem; |
79 | } |
80 | |
81 | /* |
82 | * if buf_size parameter is specified, this object is configured |
83 | * to be using memory-pool. |
84 | * |
85 | */ |
86 | if (!buf_size) |
87 | mmgr->mpool = NULL; |
88 | else { |
89 | HPDF_MPool_Node node; |
90 | |
91 | node = (HPDF_MPool_Node)mmgr->alloc_fn (sizeof(HPDF_MPool_Node_Rec) + |
92 | buf_size); |
93 | |
94 | HPDF_PTRACE(("+%p mmgr-node-new\n" , node)); |
95 | |
96 | if (node == NULL) { |
97 | HPDF_SetError (error, HPDF_FAILD_TO_ALLOC_MEM, HPDF_NOERROR); |
98 | |
99 | mmgr->free_fn(mmgr); |
100 | mmgr = NULL; |
101 | } else { |
102 | mmgr->mpool = node; |
103 | node->buf = (HPDF_BYTE *)node + sizeof(HPDF_MPool_Node_Rec); |
104 | node->size = buf_size; |
105 | node->used_size = 0; |
106 | node->next_node = NULL; |
107 | } |
108 | |
109 | #ifdef HPDF_MEM_DEBUG |
110 | if (mmgr) { |
111 | mmgr->alloc_cnt += 1; |
112 | } |
113 | #endif |
114 | } |
115 | |
116 | if (mmgr) { |
117 | mmgr->buf_size = buf_size; |
118 | } |
119 | } else |
120 | HPDF_SetError(error, HPDF_FAILD_TO_ALLOC_MEM, HPDF_NOERROR); |
121 | |
122 | return mmgr; |
123 | } |
124 | |
125 | void |
126 | HPDF_MMgr_Free (HPDF_MMgr mmgr) |
127 | { |
128 | HPDF_MPool_Node node; |
129 | |
130 | HPDF_PTRACE((" HPDF_MMgr_Free\n" )); |
131 | |
132 | if (mmgr == NULL) |
133 | return; |
134 | |
135 | node = mmgr->mpool; |
136 | |
137 | /* delete all nodes recursively */ |
138 | while (node != NULL) { |
139 | HPDF_MPool_Node tmp = node; |
140 | node = tmp->next_node; |
141 | |
142 | HPDF_PTRACE(("-%p mmgr-node-free\n" , tmp)); |
143 | mmgr->free_fn (tmp); |
144 | |
145 | #ifdef HPDF_MEM_DEBUG |
146 | mmgr->free_cnt++; |
147 | #endif |
148 | |
149 | } |
150 | |
151 | #ifdef HPDF_MEM_DEBUG |
152 | HPDF_PRINTF ("# HPDF_MMgr alloc-cnt=%u, free-cnt=%u\n" , |
153 | mmgr->alloc_cnt, mmgr->free_cnt); |
154 | |
155 | if (mmgr->alloc_cnt != mmgr->free_cnt) |
156 | HPDF_PRINTF ("# ERROR #\n" ); |
157 | #endif |
158 | |
159 | HPDF_PTRACE(("-%p mmgr-free\n" , mmgr)); |
160 | mmgr->free_fn (mmgr); |
161 | } |
162 | |
163 | void* |
164 | HPDF_GetMem (HPDF_MMgr mmgr, |
165 | HPDF_UINT size) |
166 | { |
167 | void * ptr; |
168 | |
169 | if (mmgr->mpool) { |
170 | HPDF_MPool_Node node = mmgr->mpool; |
171 | |
172 | #ifdef HPDF_ALINMENT_SIZ |
173 | size = (size + (HPDF_ALINMENT_SIZ - 1)) / HPDF_ALINMENT_SIZ; |
174 | size *= HPDF_ALINMENT_SIZ; |
175 | #endif |
176 | |
177 | if (node->size - node->used_size >= size) { |
178 | ptr = (HPDF_BYTE*)node->buf + node->used_size; |
179 | node->used_size += size; |
180 | return ptr; |
181 | } else { |
182 | HPDF_UINT tmp_buf_siz = (mmgr->buf_size < size) ? size : |
183 | mmgr->buf_size; |
184 | |
185 | node = (HPDF_MPool_Node)mmgr->alloc_fn (sizeof(HPDF_MPool_Node_Rec) |
186 | + tmp_buf_siz); |
187 | HPDF_PTRACE(("+%p mmgr-new-node\n" , node)); |
188 | |
189 | if (!node) { |
190 | HPDF_SetError (mmgr->error, HPDF_FAILD_TO_ALLOC_MEM, |
191 | HPDF_NOERROR); |
192 | return NULL; |
193 | } |
194 | |
195 | node->size = tmp_buf_siz; |
196 | } |
197 | |
198 | node->next_node = mmgr->mpool; |
199 | mmgr->mpool = node; |
200 | node->used_size = size; |
201 | node->buf = (HPDF_BYTE*)node + sizeof(HPDF_MPool_Node_Rec); |
202 | ptr = node->buf; |
203 | } else { |
204 | ptr = mmgr->alloc_fn (size); |
205 | HPDF_PTRACE(("+%p mmgr-alloc_fn size=%u\n" , ptr, size)); |
206 | |
207 | if (ptr == NULL) |
208 | HPDF_SetError (mmgr->error, HPDF_FAILD_TO_ALLOC_MEM, HPDF_NOERROR); |
209 | } |
210 | |
211 | #ifdef HPDF_MEM_DEBUG |
212 | if (ptr) |
213 | mmgr->alloc_cnt++; |
214 | #endif |
215 | |
216 | return ptr; |
217 | } |
218 | |
219 | void |
220 | HPDF_FreeMem (HPDF_MMgr mmgr, |
221 | void *aptr) |
222 | { |
223 | if (!aptr) |
224 | return; |
225 | |
226 | if (!mmgr->mpool) { |
227 | HPDF_PTRACE(("-%p mmgr-free-mem\n" , aptr)); |
228 | mmgr->free_fn(aptr); |
229 | |
230 | #ifdef HPDF_MEM_DEBUG |
231 | mmgr->free_cnt++; |
232 | #endif |
233 | } |
234 | |
235 | return; |
236 | } |
237 | |
238 | static void * HPDF_STDCALL |
239 | InternalGetMem (HPDF_UINT size) |
240 | { |
241 | return HPDF_MALLOC (size); |
242 | } |
243 | |
244 | static void HPDF_STDCALL |
245 | InternalFreeMem (void* aptr) |
246 | { |
247 | HPDF_FREE (aptr); |
248 | } |
249 | |
250 | |
251 | |