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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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__, &error ) ) 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 */ 460