The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 1 | /***************************************************************************/ |
| 2 | /* */ |
| 3 | /* ftmemory.h */ |
| 4 | /* */ |
| 5 | /* The FreeType memory management macros (specification). */ |
| 6 | /* */ |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 7 | /* Copyright 1996-2002, 2004-2007, 2010, 2013 by */ |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 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 FT_CONFIG_CONFIG_H |
| 25 | #include FT_TYPES_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 | /* |
Nick Kralevich | aacb8e1 | 2010-09-14 17:02:58 -0700 | [diff] [blame] | 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. |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 64 | */ |
| 65 | |
| 66 | #ifdef __cplusplus |
Nick Kralevich | aacb8e1 | 2010-09-14 17:02:58 -0700 | [diff] [blame] | 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 | |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 78 | #else |
Nick Kralevich | aacb8e1 | 2010-09-14 17:02:58 -0700 | [diff] [blame] | 79 | |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 80 | #define FT_ASSIGNP( p, val ) (p) = (val) |
Nick Kralevich | aacb8e1 | 2010-09-14 17:02:58 -0700 | [diff] [blame] | 81 | |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 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 | |
| 139 | FT_BASE( void ) |
| 140 | ft_mem_free( FT_Memory memory, |
| 141 | const void* P ); |
| 142 | |
| 143 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 144 | #define FT_MEM_ALLOC( ptr, size ) \ |
| 145 | FT_ASSIGNP_INNER( ptr, ft_mem_alloc( memory, \ |
| 146 | (FT_Long)(size), \ |
| 147 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 148 | |
| 149 | #define FT_MEM_FREE( ptr ) \ |
| 150 | FT_BEGIN_STMNT \ |
| 151 | ft_mem_free( memory, (ptr) ); \ |
| 152 | (ptr) = NULL; \ |
| 153 | FT_END_STMNT |
| 154 | |
| 155 | #define FT_MEM_NEW( ptr ) \ |
| 156 | FT_MEM_ALLOC( ptr, sizeof ( *(ptr) ) ) |
| 157 | |
| 158 | #define FT_MEM_REALLOC( ptr, cursz, newsz ) \ |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 159 | FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ |
| 160 | 1, \ |
| 161 | (FT_Long)(cursz), \ |
| 162 | (FT_Long)(newsz), \ |
| 163 | (ptr), \ |
| 164 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 165 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 166 | #define FT_MEM_QALLOC( ptr, size ) \ |
| 167 | FT_ASSIGNP_INNER( ptr, ft_mem_qalloc( memory, \ |
| 168 | (FT_Long)(size), \ |
| 169 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 170 | |
| 171 | #define FT_MEM_QNEW( ptr ) \ |
| 172 | FT_MEM_QALLOC( ptr, sizeof ( *(ptr) ) ) |
| 173 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 174 | #define FT_MEM_QREALLOC( ptr, cursz, newsz ) \ |
| 175 | FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ |
| 176 | 1, \ |
| 177 | (FT_Long)(cursz), \ |
| 178 | (FT_Long)(newsz), \ |
| 179 | (ptr), \ |
| 180 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 181 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 182 | #define FT_MEM_ALLOC_MULT( ptr, count, item_size ) \ |
| 183 | FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ |
| 184 | (FT_Long)(item_size), \ |
| 185 | 0, \ |
| 186 | (FT_Long)(count), \ |
| 187 | NULL, \ |
| 188 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 189 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 190 | #define FT_MEM_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ |
| 191 | FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ |
| 192 | (FT_Long)(itmsz), \ |
| 193 | (FT_Long)(oldcnt), \ |
| 194 | (FT_Long)(newcnt), \ |
| 195 | (ptr), \ |
| 196 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 197 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 198 | #define FT_MEM_QALLOC_MULT( ptr, count, item_size ) \ |
| 199 | FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ |
| 200 | (FT_Long)(item_size), \ |
| 201 | 0, \ |
| 202 | (FT_Long)(count), \ |
| 203 | NULL, \ |
| 204 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 205 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 206 | #define FT_MEM_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz) \ |
| 207 | FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ |
| 208 | (FT_Long)(itmsz), \ |
| 209 | (FT_Long)(oldcnt), \ |
| 210 | (FT_Long)(newcnt), \ |
| 211 | (ptr), \ |
| 212 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 213 | |
| 214 | |
| 215 | #define FT_MEM_SET_ERROR( cond ) ( (cond), error != 0 ) |
| 216 | |
| 217 | |
| 218 | #define FT_MEM_SET( dest, byte, count ) ft_memset( dest, byte, count ) |
| 219 | |
| 220 | #define FT_MEM_COPY( dest, source, count ) ft_memcpy( dest, source, count ) |
| 221 | |
| 222 | #define FT_MEM_MOVE( dest, source, count ) ft_memmove( dest, source, count ) |
| 223 | |
| 224 | |
| 225 | #define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) |
| 226 | |
| 227 | #define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) |
| 228 | |
| 229 | |
| 230 | #define FT_ARRAY_ZERO( dest, count ) \ |
| 231 | FT_MEM_ZERO( dest, (count) * sizeof ( *(dest) ) ) |
| 232 | |
| 233 | #define FT_ARRAY_COPY( dest, source, count ) \ |
| 234 | FT_MEM_COPY( dest, source, (count) * sizeof ( *(dest) ) ) |
| 235 | |
| 236 | #define FT_ARRAY_MOVE( dest, source, count ) \ |
| 237 | FT_MEM_MOVE( dest, source, (count) * sizeof ( *(dest) ) ) |
| 238 | |
| 239 | |
| 240 | /* |
| 241 | * Return the maximum number of addressable elements in an array. |
| 242 | * We limit ourselves to INT_MAX, rather than UINT_MAX, to avoid |
| 243 | * any problems. |
| 244 | */ |
| 245 | #define FT_ARRAY_MAX( ptr ) ( FT_INT_MAX / sizeof ( *(ptr) ) ) |
| 246 | |
| 247 | #define FT_ARRAY_CHECK( ptr, count ) ( (count) <= FT_ARRAY_MAX( ptr ) ) |
| 248 | |
| 249 | |
| 250 | /*************************************************************************/ |
| 251 | /* */ |
| 252 | /* The following functions macros expect that their pointer argument is */ |
| 253 | /* _typed_ in order to automatically compute array element sizes. */ |
| 254 | /* */ |
| 255 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 256 | #define FT_MEM_NEW_ARRAY( ptr, count ) \ |
| 257 | FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ |
| 258 | sizeof ( *(ptr) ), \ |
| 259 | 0, \ |
| 260 | (FT_Long)(count), \ |
| 261 | NULL, \ |
| 262 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 263 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 264 | #define FT_MEM_RENEW_ARRAY( ptr, cursz, newsz ) \ |
| 265 | FT_ASSIGNP_INNER( ptr, ft_mem_realloc( memory, \ |
| 266 | sizeof ( *(ptr) ), \ |
| 267 | (FT_Long)(cursz), \ |
| 268 | (FT_Long)(newsz), \ |
| 269 | (ptr), \ |
| 270 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 271 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 272 | #define FT_MEM_QNEW_ARRAY( ptr, count ) \ |
| 273 | FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ |
| 274 | sizeof ( *(ptr) ), \ |
| 275 | 0, \ |
| 276 | (FT_Long)(count), \ |
| 277 | NULL, \ |
| 278 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 279 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 280 | #define FT_MEM_QRENEW_ARRAY( ptr, cursz, newsz ) \ |
| 281 | FT_ASSIGNP_INNER( ptr, ft_mem_qrealloc( memory, \ |
| 282 | sizeof ( *(ptr) ), \ |
| 283 | (FT_Long)(cursz), \ |
| 284 | (FT_Long)(newsz), \ |
| 285 | (ptr), \ |
| 286 | &error ) ) |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 287 | |
| 288 | #define FT_ALLOC( ptr, size ) \ |
| 289 | FT_MEM_SET_ERROR( FT_MEM_ALLOC( ptr, size ) ) |
| 290 | |
| 291 | #define FT_REALLOC( ptr, cursz, newsz ) \ |
| 292 | FT_MEM_SET_ERROR( FT_MEM_REALLOC( ptr, cursz, newsz ) ) |
| 293 | |
| 294 | #define FT_ALLOC_MULT( ptr, count, item_size ) \ |
| 295 | FT_MEM_SET_ERROR( FT_MEM_ALLOC_MULT( ptr, count, item_size ) ) |
| 296 | |
| 297 | #define FT_REALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ |
| 298 | FT_MEM_SET_ERROR( FT_MEM_REALLOC_MULT( ptr, oldcnt, \ |
| 299 | newcnt, itmsz ) ) |
| 300 | |
| 301 | #define FT_QALLOC( ptr, size ) \ |
| 302 | FT_MEM_SET_ERROR( FT_MEM_QALLOC( ptr, size ) ) |
| 303 | |
| 304 | #define FT_QREALLOC( ptr, cursz, newsz ) \ |
| 305 | FT_MEM_SET_ERROR( FT_MEM_QREALLOC( ptr, cursz, newsz ) ) |
| 306 | |
| 307 | #define FT_QALLOC_MULT( ptr, count, item_size ) \ |
| 308 | FT_MEM_SET_ERROR( FT_MEM_QALLOC_MULT( ptr, count, item_size ) ) |
| 309 | |
| 310 | #define FT_QREALLOC_MULT( ptr, oldcnt, newcnt, itmsz ) \ |
| 311 | FT_MEM_SET_ERROR( FT_MEM_QREALLOC_MULT( ptr, oldcnt, \ |
| 312 | newcnt, itmsz ) ) |
| 313 | |
| 314 | #define FT_FREE( ptr ) FT_MEM_FREE( ptr ) |
| 315 | |
| 316 | #define FT_NEW( ptr ) FT_MEM_SET_ERROR( FT_MEM_NEW( ptr ) ) |
| 317 | |
| 318 | #define FT_NEW_ARRAY( ptr, count ) \ |
| 319 | FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) |
| 320 | |
| 321 | #define FT_RENEW_ARRAY( ptr, curcnt, newcnt ) \ |
| 322 | FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) |
| 323 | |
| 324 | #define FT_QNEW( ptr ) \ |
| 325 | FT_MEM_SET_ERROR( FT_MEM_QNEW( ptr ) ) |
| 326 | |
| 327 | #define FT_QNEW_ARRAY( ptr, count ) \ |
| 328 | FT_MEM_SET_ERROR( FT_MEM_NEW_ARRAY( ptr, count ) ) |
| 329 | |
| 330 | #define FT_QRENEW_ARRAY( ptr, curcnt, newcnt ) \ |
| 331 | FT_MEM_SET_ERROR( FT_MEM_RENEW_ARRAY( ptr, curcnt, newcnt ) ) |
| 332 | |
| 333 | |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 334 | FT_BASE( FT_Pointer ) |
| 335 | ft_mem_strdup( FT_Memory memory, |
| 336 | const char* str, |
| 337 | FT_Error *p_error ); |
| 338 | |
| 339 | FT_BASE( FT_Pointer ) |
| 340 | ft_mem_dup( FT_Memory memory, |
| 341 | const void* address, |
| 342 | FT_ULong size, |
| 343 | FT_Error *p_error ); |
| 344 | |
Victoria Lease | 727dee1 | 2013-06-10 13:55:54 -0700 | [diff] [blame] | 345 | |
The Android Open Source Project | 049d6fe | 2009-03-03 19:29:31 -0800 | [diff] [blame] | 346 | #define FT_MEM_STRDUP( dst, str ) \ |
| 347 | (dst) = (char*)ft_mem_strdup( memory, (const char*)(str), &error ) |
| 348 | |
| 349 | #define FT_STRDUP( dst, str ) \ |
| 350 | FT_MEM_SET_ERROR( FT_MEM_STRDUP( dst, str ) ) |
| 351 | |
| 352 | #define FT_MEM_DUP( dst, address, size ) \ |
| 353 | (dst) = ft_mem_dup( memory, (address), (FT_ULong)(size), &error ) |
| 354 | |
| 355 | #define FT_DUP( dst, address, size ) \ |
| 356 | FT_MEM_SET_ERROR( FT_MEM_DUP( dst, address, size ) ) |
| 357 | |
| 358 | |
| 359 | /* Return >= 1 if a truncation occurs. */ |
| 360 | /* Return 0 if the source string fits the buffer. */ |
| 361 | /* This is *not* the same as strlcpy(). */ |
| 362 | FT_BASE( FT_Int ) |
| 363 | ft_mem_strcpyn( char* dst, |
| 364 | const char* src, |
| 365 | FT_ULong size ); |
| 366 | |
| 367 | #define FT_STRCPYN( dst, src, size ) \ |
| 368 | ft_mem_strcpyn( (char*)dst, (const char*)(src), (FT_ULong)(size) ) |
| 369 | |
| 370 | /* */ |
| 371 | |
| 372 | |
| 373 | FT_END_HEADER |
| 374 | |
| 375 | #endif /* __FTMEMORY_H__ */ |
| 376 | |
| 377 | |
| 378 | /* END */ |