OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* ftmemory.h */ | |
4 /* */ | |
5 /* The FreeType memory management macros (specification). */ | |
6 /* */ | |
7 /* Copyright 1996-2002, 2004-2007, 2010, 2013 by */ | |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg */ | |
9 /* */ | |
10 /* This file is part of the FreeType project, and may only be used, */ | |
11 /* modified, and distributed under the terms of the FreeType project */ | |
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ | |
13 /* this file you indicate that you have read the license and */ | |
14 /* understand and accept it fully. */ | |
15 /* */ | |
16 /***************************************************************************/ | |
17 | |
18 | |
19 #ifndef __FTMEMORY_H__ | |
20 #define __FTMEMORY_H__ | |
21 | |
22 | |
23 #include "../../ft2build.h" | |
24 #include "../config/ftconfig.h" | |
25 #include "../fttypes.h" | |
26 | |
27 | |
28 FT_BEGIN_HEADER | |
29 | |
30 | |
31 /*************************************************************************/ | |
32 /* */ | |
33 /* <Macro> */ | |
34 /* FT_SET_ERROR */ | |
35 /* */ | |
36 /* <Description> */ | |
37 /* This macro is used to set an implicit `error' variable to a given */ | |
38 /* expression's value (usually a function call), and convert it to a */ | |
39 /* boolean which is set whenever the value is != 0. */ | |
40 /* */ | |
41 #undef FT_SET_ERROR | |
42 #define FT_SET_ERROR( expression ) \ | |
43 ( ( error = (expression) ) != 0 ) | |
44 | |
45 | |
46 | |
47 /*************************************************************************/ | |
48 /*************************************************************************/ | |
49 /*************************************************************************/ | |
50 /**** ****/ | |
51 /**** ****/ | |
52 /**** M E M O R Y ****/ | |
53 /**** ****/ | |
54 /**** ****/ | |
55 /*************************************************************************/ | |
56 /*************************************************************************/ | |
57 /*************************************************************************/ | |
58 | |
59 | |
60 /* | |
61 * C++ refuses to handle statements like p = (void*)anything, with `p' a | |
62 * typed pointer. Since we don't have a `typeof' operator in standard | |
63 * C++, we have to use a template to emulate it. | |
64 */ | |
65 | |
66 #ifdef __cplusplus | |
67 | |
68 extern "C++" | |
69 template <typename T> inline T* | |
70 cplusplus_typeof( T*, | |
71 void *v ) | |
72 { | |
73 return static_cast <T*> ( v ); | |
74 } | |
75 | |
76 #define FT_ASSIGNP( p, val ) (p) = cplusplus_typeof( (p), (val) ) | |
77 | |
78 #else | |
79 | |
80 #define FT_ASSIGNP( p, val ) (p) = (val) | |
81 | |
82 #endif | |
83 | |
84 | |
85 | |
86 #ifdef FT_DEBUG_MEMORY | |
87 | |
88 FT_BASE( const char* ) _ft_debug_file; | |
89 FT_BASE( long ) _ft_debug_lineno; | |
90 | |
91 #define FT_DEBUG_INNER( exp ) ( _ft_debug_file = __FILE__, \ | |
92 _ft_debug_lineno = __LINE__, \ | |
93 (exp) ) | |
94 | |
95 #define FT_ASSIGNP_INNER( p, exp ) ( _ft_debug_file = __FILE__, \ | |
96 _ft_debug_lineno = __LINE__, \ | |
97 FT_ASSIGNP( p, exp ) ) | |
98 | |
99 #else /* !FT_DEBUG_MEMORY */ | |
100 | |
101 #define FT_DEBUG_INNER( exp ) (exp) | |
102 #define FT_ASSIGNP_INNER( p, exp ) FT_ASSIGNP( p, exp ) | |
103 | |
104 #endif /* !FT_DEBUG_MEMORY */ | |
105 | |
106 | |
107 /* | |
108 * The allocation functions return a pointer, and the error code | |
109 * is written to through the `p_error' parameter. See below for | |
110 * for documentation. | |
111 */ | |
112 | |
113 FT_BASE( FT_Pointer ) | |
114 ft_mem_alloc( FT_Memory memory, | |
115 FT_Long size, | |
116 FT_Error *p_error ); | |
117 | |
118 FT_BASE( FT_Pointer ) | |
119 ft_mem_qalloc( FT_Memory memory, | |
120 FT_Long size, | |
121 FT_Error *p_error ); | |
122 | |
123 FT_BASE( FT_Pointer ) | |
124 ft_mem_realloc( FT_Memory memory, | |
125 FT_Long item_size, | |
126 FT_Long cur_count, | |
127 FT_Long new_count, | |
128 void* block, | |
129 FT_Error *p_error ); | |
130 | |
131 FT_BASE( FT_Pointer ) | |
132 ft_mem_qrealloc( FT_Memory memory, | |
133 FT_Long item_size, | |
134 FT_Long cur_count, | |
135 FT_Long new_count, | |
136 void* block, | |
137 FT_Error *p_error ); | |
138 #ifdef _DEBUG | |
139 //#define _XYQ_MEM_DEBUG | |
140 #endif | |
141 | |
142 #ifdef _XYQ_MEM_DEBUG /* XYQ */ | |
143 FT_BASE( FT_Pointer ) | |
144 ft_mem_allocdebug( FT_Memory memory, | |
145 FT_Long size, const char* filename, int line, | |
146 FT_Error *p_error ); | |
147 | |
148 FT_BASE( FT_Pointer ) | |
149 ft_mem_qallocdebug( FT_Memory memory, | |
150 FT_Long size, const char* filename, int line, | |
151 FT_Error *p_error ); | |
152 | |
153 FT_BASE( FT_Pointer ) | |
154 ft_mem_reallocdebug( FT_Memory memory, | |
155 FT_Long item_size, | |
156 FT_Long cur_count, | |
157 FT_Long new_count, | |
158 void* block, const char* filename, int line, | |
159 FT_Error *p_error ); | |
160 | |
161 FT_BASE( FT_Pointer ) | |
162 ft_mem_qreallocdebug( FT_Memory memory, | |
163 FT_Long item_size, | |
164 FT_Long cur_count, | |
165 FT_Long new_count, | |
166 void* block, const char* filename, int line, | |
167 FT_Error *p_error ); | |
168 #endif | |
169 | |
170 | |
171 FT_BASE( void ) | |
172 ft_mem_free( FT_Memory memory, | |
173 const void* P ); | |
174 | |
175 | |
176 #define FT_MEM_FREE( ptr ) \ | |
177 FT_BEGIN_STMNT \ | |
178 ft_mem_free( memory, (ptr) ); \ | |
179 (ptr) = NULL; \ | |
180 FT_END_STMNT | |
181 #ifndef _XYQ_MEM_DEBUG | |
182 #define FT_MEM_ALLOC( ptr, size ) \ | |
183 FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, (size), &error )
) | |
184 | |
185 | |
186 #define FT_MEM_REALLOC( ptr, cursz, newsz ) \ | |
187 FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ | |
188 1, \ | |
189 (FT_Long)(cursz), \ | |
190 (FT_Long)(newsz), \ | |
191 (ptr), \ | |
192 &error ) ) | |
193 | |
194 #define FT_MEM_QALLOC( ptr, size ) \ | |
195 FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \ | |
196 (FT_Long)(size), \ | |
197 &error ) ) | |
198 | |
199 #define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ | |
200 FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ | |
201 1, \ | |
202 (FT_Long)(cursz), \ | |
203 (FT_Long)(newsz), \ | |
204 (ptr), \ | |
205 &error ) ) | |
206 | |
207 #define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ | |
208 FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ | |
209 (FT_Long)(item_size), \ | |
210 0, \ | |
211 (FT_Long)(count), \ | |
212 NULL, \ | |
213 &error ) ) | |
214 | |
215 #define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ | |
216 FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ | |
217 (FT_Long)(itmsz), \ | |
218 (FT_Long)(oldcnt), \ | |
219 (FT_Long)(newcnt), \ | |
220 (ptr), \ | |
221 &error ) ) | |
222 | |
223 #define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ | |
224 FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ | |
225 (FT_Long)(item_size), \ | |
226 0, \ | |
227 (FT_Long)(count), \ | |
228 NULL, \ | |
229 &error ) ) | |
230 | |
231 #define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ | |
232 FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ | |
233 (FT_Long)(itmsz), \ | |
234 (FT_Long)(oldcnt), \ | |
235 (FT_Long)(newcnt), \ | |
236 (ptr), \ | |
237 &error ) ) | |
238 #define FT_MEM_NEW_ARRAY( ptr, count ) \ | |
239 FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ | |
240 0, (count), \ | |
241 NULL, &error ) ) | |
242 | |
243 #define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ | |
244 FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, sizeof ( *(ptr) ), \ | |
245 (cursz), (newsz), \ | |
246 (ptr), &error ) ) | |
247 | |
248 #define FT_MEM_QNEW_ARRAY( ptr, count ) \ | |
249 FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ | |
250 0, (count), \ | |
251 NULL, &error ) ) | |
252 | |
253 #define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ | |
254 FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, sizeof ( *(ptr) ), \ | |
255 (cursz), (newsz), \ | |
256 (ptr), &error ) ) | |
257 | |
258 #else | |
259 #define FT_MEM_ALLOC( ptr, size ) \ | |
260 FT_ASSIGNP_INNER( ptr, ft_mem_allocdebug( memory, (size), __FILE__, __LINE__,
&error ) ) | |
261 | |
262 #define FT_MEM_REALLOC( ptr, cursz, newsz ) \ | |
263 FT_ASSIGNP_INNER( ptr, ft_mem_reallocdebug( memory, 1, \ | |
264 (cursz), (newsz), \ | |
265 (ptr), __FILE__, __LINE__, &err
or ) ) | |
266 | |
267 #define FT_MEM_QALLOC( ptr, size ) \ | |
268 FT_ASSIGNP_INNER( ptr, ft_mem_qallocdebug( memory, (size), __FILE__, _
_LINE__, &error ) ) | |
269 | |
270 #define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ | |
271 FT_ASSIGNP_INNER( ptr, ft_mem_qreallocdebug( memory, 1, \ | |
272 (cursz), (newsz), \ | |
273 (ptr), __FILE__, __LINE__, &er
ror ) ) | |
274 | |
275 #define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ | |
276 FT_ASSIGNP_INNER( ptr, ft_mem_reallocdebug( memory, (item_size), \ | |
277 0, (count), \ | |
278 NULL, __FILE__, __LINE__, &erro
r ) ) | |
279 | |
280 #define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ | |
281 FT_ASSIGNP_INNER( ptr, ft_mem_reallocdebug( memory, (itmsz), \ | |
282 (oldcnt), (newcnt), \ | |
283 (ptr), __FILE__, __LINE__, &err
or ) ) | |
284 | |
285 #define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ | |
286 FT_ASSIGNP_INNER( ptr, ft_mem_qreallocdebug( memory, (item_size), \ | |
287 0, (count), \ | |
288 NULL, __FILE__, __LINE__, &err
or ) ) | |
289 | |
290 #define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ | |
291 FT_ASSIGNP_INNER( ptr, ft_mem_qreallocdebug( memory, (itmsz), \ | |
292 (oldcnt), (newcnt), \ | |
293 (ptr), __FILE__, __LINE__, &er
ror ) ) | |
294 /*************************************************************************/ | |
295 /* */ | |
296 /* The following functions macros expect that their pointer argument is */ | |
297 /* _typed_ in order to automatically compute array element sizes. */ | |
298 /* */ | |
299 | |
300 #define FT_MEM_NEW_ARRAY( ptr, count ) \ | |
301 FT_ASSIGNP_INNER( ptr, ft_mem_reallocdebug( memory, sizeof ( *(ptr) ),
\ | |
302 0, (count), \ | |
303 NULL, __FILE__, __LINE__, &erro
r ) ) | |
304 | |
305 #define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ | |
306 FT_ASSIGNP_INNER( ptr, ft_mem_reallocdebug( memory, sizeof ( *(ptr) ),
\ | |
307 (cursz), (newsz), \ | |
308 (ptr), __FILE__, __LINE__, &err
or ) ) | |
309 | |
310 #define FT_MEM_QNEW_ARRAY( ptr, count ) \ | |
311 FT_ASSIGNP_INNER( ptr, ft_mem_qreallocdebug( memory, sizeof ( *(ptr) )
, \ | |
312 0, (count), \ | |
313 NULL, __FILE__, __LINE__, &err
or ) ) | |
314 | |
315 #define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ | |
316 FT_ASSIGNP_INNER( ptr, ft_mem_qreallocdebug( memory, sizeof ( *(ptr) )
, \ | |
317 (cursz), (newsz), \ | |
318 (ptr), __FILE__, __LINE__, &er
ror ) ) | |
319 | |
320 #endif | |
321 | |
322 #define FT_MEM_NEW( ptr ) \ | |
323 FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) | |
324 | |
325 #define FT_MEM_QNEW( ptr ) \ | |
326 FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) | |
327 | |
328 #define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) | |
329 | |
330 | |
331 #define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) | |
332 | |
333 #define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) | |
334 | |
335 #define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) | |
336 | |
337 | |
338 #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) | |
339 | |
340 #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) | |
341 | |
342 | |
343 #define FT_ARRAY_ZERO( dest, count ) \ | |
344 FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) | |
345 | |
346 #define FT_ARRAY_COPY( dest, source, count ) \ | |
347 FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) | |
348 | |
349 #define FT_ARRAY_MOVE( dest, source, count ) \ | |
350 FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) | |
351 | |
352 | |
353 /* | |
354 * Return the maximum number of addressable elements in an array. | |
355 * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid | |
356 * any problems. | |
357 */ | |
358 #define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) | |
359 | |
360 #define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) | |
361 | |
362 | |
363 /*************************************************************************/ | |
364 /* */ | |
365 /* The following functions macros expect that their pointer argument is */ | |
366 /* _typed_ in order to automatically compute array element sizes. */ | |
367 /* */ | |
368 | |
369 #define FT_ALLOC( ptr, size ) \ | |
370 FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) | |
371 | |
372 #define FT_REALLOC( ptr, cursz, newsz ) \ | |
373 FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) | |
374 | |
375 #define FT_ALLOC_MULT( ptr, count, item_size ) \ | |
376 FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) | |
377 | |
378 #define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ | |
379 FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ | |
380 newcnt, itmsz ) ) | |
381 | |
382 #define FT_QALLOC( ptr, size ) \ | |
383 FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) | |
384 | |
385 #define FT_QREALLOC( ptr, cursz, newsz ) \ | |
386 FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) | |
387 | |
388 #define FT_QALLOC_MULT( ptr, count, item_size ) \ | |
389 FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) | |
390 | |
391 #define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ | |
392 FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ | |
393 newcnt, itmsz ) ) | |
394 | |
395 #define FT_FREE( ptr ) FT_MEM_FREE( ptr ) | |
396 | |
397 #define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) | |
398 | |
399 #define FT_NEW_ARRAY( ptr, count ) \ | |
400 FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) | |
401 | |
402 #define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ | |
403 FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) | |
404 | |
405 #define FT_QNEW( ptr ) \ | |
406 FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) | |
407 | |
408 #define FT_QNEW_ARRAY( ptr, count ) \ | |
409 FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) | |
410 | |
411 #define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ | |
412 FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) | |
413 | |
414 | |
415 FT_BASE( FT_Pointer ) | |
416 ft_mem_strdup( FT_Memory memory, | |
417 const char* str, | |
418 FT_Error *p_error ); | |
419 | |
420 FT_BASE( FT_Pointer ) | |
421 ft_mem_dup( FT_Memory memory, | |
422 const void* address, | |
423 FT_ULong size, | |
424 FT_Error *p_error ); | |
425 | |
426 | |
427 #define FT_MEM_STRDUP( dst, str ) \ | |
428 (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) | |
429 | |
430 #define FT_STRDUP( dst, str ) \ | |
431 FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) | |
432 | |
433 #define FT_MEM_DUP( dst, address, size ) \ | |
434 (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) | |
435 | |
436 #define FT_DUP( dst, address, size ) \ | |
437 FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) | |
438 | |
439 | |
440 /* Return >= 1 if a truncation occurs. */ | |
441 /* Return 0 if the source string fits the buffer. */ | |
442 /* This is *not* the same as strlcpy(). */ | |
443 FT_BASE( FT_Int ) | |
444 ft_mem_strcpyn( char* dst, | |
445 const char* src, | |
446 FT_ULong size ); | |
447 | |
448 #define FT_STRCPYN( dst, src, size ) \ | |
449 ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) | |
450 | |
451 /* */ | |
452 | |
453 | |
454 FT_END_HEADER | |
455 | |
456 #endif /* __FTMEMORY_H__ */ | |
457 | |
458 | |
459 /* END */ | |
OLD | NEW |